Android Activity - 根 Activity 变化、APP 崩溃与自动重启
2026/8/5 12:46:07 网站建设 项目流程

根 Activity 变化

1、问题引入
  • 从 SplashAvtivity 跳转到了 LoginAvtivity,这种写法,是不是可以让 LoginAvtivity 成为根 Activity?
startActivity(newIntent(SplashAvtivity.this,LoginActivity.class));finish();
2、演示
(1)Activity
  1. StartActivity
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".StartActivity"><Buttonandroid:id="@+id/btn_go"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="前进"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/></androidx.constraintlayout.widget.ConstraintLayout>
publicclassStartActivityextendsAppCompatActivity{publicstaticfinalStringTAG=StartActivity.class.getSimpleName();@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_start);test();}privatevoidtest(){Log.i(TAG,"taskId: "+getTaskId());Log.i(TAG,"intent: "+getIntent().toString());Log.i(TAG,"isTaskRoot: "+isTaskRoot());ButtonbtnGo=findViewById(R.id.btn_go);btnGo.setOnClickListener(v->{Intentintent=newIntent(this,FinishActivity.class);startActivity(intent);});}}
  1. FinishActivity
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".FinishActivity"><Buttonandroid:id="@+id/btn_back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="前进"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/></androidx.constraintlayout.widget.ConstraintLayout>
publicclassFinishActivityextendsAppCompatActivity{publicstaticfinalStringTAG=FinishActivity.class.getSimpleName();@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_finish);test();}privatevoidtest(){Log.i(TAG,"taskId: "+getTaskId());Log.i(TAG,"intent: "+getIntent().toString());Log.i(TAG,"isTaskRoot: "+isTaskRoot());ButtonbtnBack=findViewById(R.id.btn_back);btnBack.setOnClickListener(v->finish());}}
(2)Test
  1. 应用启动,打开 StartActivity,输出结果如下
StartActivity - taskId: 170 StartActivity - intent: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.my.activity/.StartActivity } StartActivity - isTaskRoot: true
  1. 点击【前进】按钮,跳转到 FinishActivity,输出结果如下
FinishActivity - taskId: 170 FinishActivity - intent: Intent { cmp=com.my.activity/.FinishActivity } FinishActivity - isTaskRoot: false
(3)Change Test
  • 在 StartActivity 中,进行如下修改
Log.i(TAG,"taskId: "+getTaskId());Log.i(TAG,"intent: "+getIntent().toString());Log.i(TAG,"isTaskRoot: "+isTaskRoot());ButtonbtnGo=findViewById(R.id.btn_go);btnGo.setOnClickListener(v->{Intentintent=newIntent(this,FinishActivity.class);startActivity(intent);finish();});
  1. 应用启动,打开 StartActivity,输出结果如下
StartActivity - taskId: 171 StartActivity - intent: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.my.activity/.StartActivity } StartActivity - isTaskRoot: true
  1. 点击【前进】按钮,跳转到 FinishActivity,输出结果如下
FinishActivity - taskId: 171 FinishActivity - intent: Intent { cmp=com.my.activity/.FinishActivity } FinishActivity - isTaskRoot: true
3、小结
  1. 原 Activity 是根 Activity,启动新 Activity 后立即调用 finish 方法

  2. 新启动的 Activity 会继承原任务栈,新 Activity 会成为新的根 Activity

4、优化策略
  • 清空栈顶并设为根,在 Intent 中添加FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK标志
Intentintent=newIntent(SplashActivity.this,LoginActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);startActivity(intent);
  1. FLAG_ACTIVITY_CLEAR_TASK:清除原任务栈中所有 Activity

  2. FLAG_ACTIVITY_NEW_TASK:在新任务中启动,此时的 Activity 就是新栈的根

5、补充学习
  1. getTaskId 方法用于返回当前 Activity 所在任务栈的唯一 ID

  2. getIntent 方法用于返回启动当前 Activity 的 Intent 对象,这个 Intent 对象包含了启动该 Activity 时的所有信息,有 Action、Data、Category、Flags、Extras 等

  3. isTaskRoot 方法用于判断当前 Activity 是否是其所在任务栈的根 Activity,即栈底第一个 Activity


APP 崩溃与自动重启

  1. 在 Application 中,有如下处理
Thread.setDefaultUncaughtExceptionHandler((t,e)->{Log.i(TAG,"defaultUncaughtExceptionHandler: "+e.getMessage());...System.exit(1);});
  1. 从 LoginActivity 跳转到了 MainActivity,从 MainActivity 跳转到了 ComputeActivity

  2. 在 ComputeActivity 中操作时,报错了,现象如下

白屏了几秒后,回到了 LoginActivity
Log.i(TAG, "defaultUncaughtExceptionHandler: " + e.getMessage()) 有 7 次打印 第 1 次打印是 ComputeActivity 的报错触发 后面的 6 次打印是 MainActivity 的报错触发,因为 MainActivity 不支持直接启动,需要从 LoginActivity 跳转 MainActivity
也就是说,ComputeActivity 报错,APP 自动重启,打开 MainActivity 但是,MainActivity 报错,APP 自动重启,打开 MainActivity,这样重复了多次 最后,MainActivity 报错,APP 自动重启,打开 LoginActivity
  1. 如果不调用 setDefaultUncaughtExceptionHandler 方法,同样的情况,现象如下
白屏了几秒后,回到了 LoginActivity
ComputeActivity 报错,APP 自动重启,打开 MainActivity MainActivity 报错,APP 自动重启,打开 LoginActivity
  1. 修改了 setDefaultUncaughtExceptionHandler 方法,同样的情况,现象如下
Thread.setDefaultUncaughtExceptionHandler((t,e)->{Log.i(TAG,"defaultUncaughtExceptionHandler: "+e.getMessage());...Intentintent=newIntent(this,LoginActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);startActivity(intent);System.exit(1);});
白屏后回到了 LoginActivity
ComputeActivity 报错,APP 自动重启,打开 LoginActivity

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询