You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Activity生命周期重启时Timber日志重复打印的原因及解决方法

问题成因

Timber的日志树存储在全局静态集合中,每次调用Timber.plant()方法都会向该集合新增一个日志树实例。每次打印日志时,Timber会遍历所有已种植的日志树,依次执行日志输出逻辑。
你将Timber.plant(new Timber.DebugTree())写在Activity的onCreate方法中,每次Activity因配置变更(如屏幕旋转)重建时,都会重复种植新的DebugTree实例,N次重建就会有N个日志树,最终同一条日志会被输出N次,你遇到的二次输出就是因为已经种植了2个DebugTree。

解决方法

推荐方案:全局初始化Timber

Timber官方推荐将初始化逻辑放在Application的onCreate方法中,Application全局仅会初始化一次,不会出现重复种植日志树的问题。

  1. 自定义Application类:
public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // 建议仅在Debug版本初始化DebugTree,避免线上环境输出敏感日志
        if (BuildConfig.DEBUG) {
            Timber.plant(new Timber.DebugTree());
        }
    }
}
  1. 在AndroidManifest.xml的application节点中注册自定义Application:
<application
    android:name=".MyApp"
    ...其余配置保持不变...>
    ...Activity等组件声明...
</application>
  1. 删除Activity中onCreate方法内的Timber.plant(new Timber.DebugTree())代码即可。

特殊场景方案:需在Activity中初始化

如果确实有业务需求需要在Activity内初始化Timber,可以选择以下两种方式避免重复种植:

方式1:静态标记判断是否已初始化

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "StateChange";
    // 静态标记全局仅会初始化一次,不受Activity重建影响
    private static boolean sTimberInitialized = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (!sTimberInitialized) {
            Timber.plant(new Timber.DebugTree());
            sTimberInitialized = true;
        }
        setContentView(ActivityMainBinding.inflate(getLayoutInflater()).getRoot());
        Timber.tag(TAG).i("onCreate");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
    }
}

方式2:Activity销毁时移除对应日志树

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "StateChange";
    private Timber.Tree mDebugTree;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDebugTree = new Timber.DebugTree();
        Timber.plant(mDebugTree);
        setContentView(ActivityMainBinding.inflate(getLayoutInflater()).getRoot());
        Timber.tag(TAG).i("onCreate");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 移除当前Activity种植的日志树,避免后续重复
        Timber.uproot(mDebugTree);
        Log.i(TAG, "onDestroy");
    }
}

内容的提问来源于stack exchange,提问作者hescul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 22:36:04