6565
6666#[ cfg( target_os = "android" ) ]
6767extern crate android_log_sys as log_ffi;
68- # [ macro_use ]
69- extern crate lazy_static ;
68+ extern crate once_cell ;
69+ use once_cell :: sync :: OnceCell ;
7070#[ macro_use]
7171extern crate log;
7272
7373extern crate env_logger;
7474
75- use std:: sync:: RwLock ;
76-
7775#[ cfg( target_os = "android" ) ]
7876use log_ffi:: LogPriority ;
7977use log:: { Level , Log , Metadata , Record } ;
@@ -105,21 +103,20 @@ fn android_log(_priority: Level, _tag: &CStr, _msg: &CStr) {}
105103
106104/// Underlying android logger backend
107105pub struct AndroidLogger {
108- config : RwLock < Config > ,
106+ config : OnceCell < Config > ,
109107}
110108
111109impl AndroidLogger {
112110 /// Create new logger instance from config
113111 pub fn new ( config : Config ) -> AndroidLogger {
114112 AndroidLogger {
115- config : RwLock :: new ( config) ,
113+ config : OnceCell :: from ( config) ,
116114 }
117115 }
118116}
119117
120- lazy_static ! {
121- static ref ANDROID_LOGGER : AndroidLogger = AndroidLogger :: default ( ) ;
122- }
118+
119+ static ANDROID_LOGGER : OnceCell < AndroidLogger > = OnceCell :: new ( ) ;
123120
124121const LOGGING_TAG_MAX_LEN : usize = 23 ;
125122const LOGGING_MSG_MAX_LEN : usize = 4000 ;
@@ -128,7 +125,7 @@ impl Default for AndroidLogger {
128125 /// Create a new logger with default config
129126 fn default ( ) -> AndroidLogger {
130127 AndroidLogger {
131- config : RwLock :: new ( Config :: default ( ) ) ,
128+ config : OnceCell :: from ( Config :: default ( ) ) ,
132129 }
133130 }
134131}
@@ -140,8 +137,7 @@ impl Log for AndroidLogger {
140137
141138 fn log ( & self , record : & Record ) {
142139 let config = self . config
143- . read ( )
144- . expect ( "failed to acquire android_log filter lock for read" ) ;
140+ . get_or_init ( Config :: default) ;
145141
146142 if !config. filter_matches ( record) {
147143 return ;
@@ -423,7 +419,7 @@ impl<'a> fmt::Write for PlatformLogWriter<'a> {
423419/// This action does not require initialization. However, without initialization it
424420/// will use the default filter, which allows all logs.
425421pub fn log ( record : & Record ) {
426- ANDROID_LOGGER . log ( record)
422+ ANDROID_LOGGER . get_or_init ( AndroidLogger :: default ) . log ( record)
427423}
428424
429425/// Initializes the global logger with an android logger.
@@ -434,16 +430,13 @@ pub fn log(record: &Record) {
434430/// It is ok to call this at the activity creation, and it will be
435431/// repeatedly called on every lifecycle restart (i.e. screen rotation).
436432pub fn init_once ( config : Config ) {
437- if let Err ( err) = log:: set_logger ( & * ANDROID_LOGGER ) {
433+ let log_level = config. log_level ;
434+ let logger = ANDROID_LOGGER . get_or_init ( || AndroidLogger :: new ( config) ) ;
435+
436+ if let Err ( err) = log:: set_logger ( logger) {
438437 debug ! ( "android_logger: log::set_logger failed: {}" , err) ;
439- } else {
440- if let Some ( level) = config. log_level {
441- log:: set_max_level ( level. to_level_filter ( ) ) ;
442- }
443- * ANDROID_LOGGER
444- . config
445- . write ( )
446- . expect ( "failed to acquire android_log filter lock for write" ) = config;
438+ } else if let Some ( level) = log_level {
439+ log:: set_max_level ( level. to_level_filter ( ) ) ;
447440 }
448441}
449442
0 commit comments