小米手机运行Android应用仅OnResume触发、OnCreate与OnStart不执行问题
异常诱因
你的Activity生命周期本身是正常执行的,不存在被跳过的问题,异常表现完全是小米MIUI系统对Toast的定制化处理导致的:
- MIUI修改了AOSP原生的Toast全局队列逻辑,对短时间内连续触发的Toast会做节流处理。应用冷启动时
onCreate、onStart、onResume三个方法是连续快速调用的,你在每个方法中都弹出时长3.5秒的长Toast,系统会直接丢弃还没来得及展示的前序Toast,仅保留最后触发的Toast展示,因此你只会看到onResume的提示;删除onResume的Toast后,最后触发的变为onStart的Toast,所以你能看到onStart的提示,onCreate的Toast依然被丢弃。 - 小米MIUI对应用冷启动阶段非用户交互触发、且使用ApplicationContext作为上下文的Toast有额外拦截优化,避免启动阶段非必要提示打扰用户,这也进一步提升了onCreate阶段Toast的丢失概率。
- 模拟器运行的是原生Android系统,没有上述定制逻辑,Toast可以按顺序正常展示,因此表现符合生命周期预期。
解决方法
优先使用标准生命周期验证方式
不要用Toast验证生命周期,Toast依赖系统全局服务,展示逻辑受厂商定制规则影响,本身可靠性极低。建议直接在生命周期方法中打印日志:
// 随便自定义一个TAG字符串即可 Log.d("LifecycleTest", "onCreate 执行");
之后在Logcat中筛选对应TAG的输出,就能准确看到所有生命周期方法的执行顺序,不会被系统拦截。
若必须使用Toast做可视化验证,可做以下修改:
- 把Toast的上下文从
getApplicationContext()换成当前Activity的this,Activity上下文的Toast优先级更高,被MIUI拦截的概率更低。 - 全局持有唯一的Toast实例,每次弹出新Toast前先取消上一个实例,避免队列积压:
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private Toast currentToast; private void showTip(String text) { if (currentToast != null) { currentToast.cancel(); } currentToast = Toast.makeText(this, text, Toast.LENGTH_LONG); currentToast.show(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); showTip("Created!"); } @Override public void onStart() { super.onStart(); showTip("Started!"); } @Override public void onResume() { super.onResume(); showTip("Resume!"); } // 其余生命周期方法同理替换为showTip调用即可 @Override public void onPause() { super.onPause(); showTip("Pause!"); } @Override public void onStop() { super.onStop(); showTip("Stop!"); } @Override public void onDestroy() { super.onDestroy(); showTip("Destroy!"); } @Override public void onRestart() { super.onRestart(); showTip("Restart!"); } }
- 到系统设置的应用信息页,找到你的应用,开启「悬浮窗」/「显示在其他应用上层」权限,解除MIUI对Toast的展示限制。
内容的提问来源于stack exchange,提问作者cedieasd
相关产品推荐
相关产品推荐

