Android:点击ActionBar返回按钮后应用无响应问题排查
我发现应用的ActionBar返回按钮并非必需(所有页面均可通过底部菜单访问),但仍需排查点击该按钮后应用无响应的原因。我的主Activity为TestTypeMenuActivity,所有Activity均继承自BaseActivity,以下以CollegeSearchActivity为例说明相关配置与代码:
1. AndroidManifest配置
在清单文件中为CollegeSearchActivity配置父Activity为主Activity:
<activity android:name=".ui.activities.main.collegesearch.CollegeSearchActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".ui.activities.test.testtypemenu.TestTypeMenuActivity" /> </activity>
2. 核心代码实现
CollegeSearchActivity中的ActionBar初始化
override fun createActionBar() { val activityTitle = TMLocale.getStringResourceByResId(R.string.activitycommunity_textview_findcolleges).uppercase() super.createActionBar(activityTitle, showBackButton = true, capitalizeTitle = true) }
BaseActivity中的ActionBar创建逻辑
fun createActionBar(title: String, showBackButton: Boolean, capitalizeTitle: Boolean){ if(useToolBar){ val toolbar = this.createToolbar(title, capitalizeTitle) if (toolbar!=null) setSupportActionBar(toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(showBackButton) val toolbarColor = getActivityTextColor() toolbar?.setNavigationIconColor(Color.parseColor(toolbarColor)) } }
Toolbar扩展方法
fun Activity.createToolbar(actionbarTitle: String, capitalizeTitle: Boolean = true): Toolbar? { val toolbar = findViewById<Toolbar>(R.id.toolbar) if (toolbar != null) { this.setActionBarBackground(toolbar) val capitalizedTitle = if (capitalizeTitle) WordUtils.capitalizeFully(actionbarTitle) else actionbarTitle val tvActionBarTitle = toolbar.findViewById<TextView>(R.id.tvActionBarTitle) val textColor = BaseActivity.getAppTextColor(context) tvActionBarTitle.setTextColor(Color.parseColor(textColor)) if (tvActionBarTitle != null) tvActionBarTitle.text = capitalizedTitle } return toolbar }
3. 问题现象与临时修复
此前功能正常,但突然出现点击ActionBar返回按钮后应用无响应的情况。在BaseActivity中添加以下代码后,问题消失:
override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == android.R.id.home) { super.onBackPressed() return true } return super.onOptionsItemSelected(item) }
我不想仅通过添加代码解决问题,希望明确问题突发的原因及这段修复代码的原理。
4. 附Logcat输出
2024-04-29 19:49:39.261 2431-4576 ThermalTraceService com.huawei.iaware I code:1, appInfo:com.xxx.xxx#10000, levelInfo:0,warm_system_h,7 2024-04-29 19:49:39.527 4864-4864 Settings com...xxx.xxx W Setting device_provisioned has moved from android.provider.Settings.Secure to android.provider.Settings.Global. 2024-04-29 19:49:39.528 4864-4864 HiTouch_HiTouchSensor com...xxx.xxx V User setup is finished. 2024-04-29 19:49:39.740 4864-4864 AudioManager com...xxx.xxx V querySoundEffectsEnabled... 2024-04-29 19:49:43.090 4864-4929 ZrHungImpl com...xxx.xxx I sendRawEvent. wpId = 257 2024-04-29 19:49:43.092 4864-4929 HiView.HiEvent com...xxx.xxx E length is 0 or exceed MAX: 1024 2024-04-29 19:49:45.405 4864-4929 ZrHungImpl com...xxx.xxx I sendRawEvent. wpId = 258 2024-04-29 19:49:45.405 4864-4929 HiView.HiEvent com...xxx.xxx E length is 0 or exceed MAX: 1024 2024-04-29 19:49:47.537 4864-4885 lsatactexampre com...xxx.xxx I Background concurrent copying GC freed 109772(6560KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 8312KB/16MB, paused 150us total 103.835ms 2024-04-29 19:49:54.273 2431-4576 ThermalTraceService com.huawei.iaware I code:1, appInfo:com.xxx.xxx#10000, levelInfo:0,warm_system_h,6#0,warm_systemh_screenoff,1 2024-04-29 19:49:56.395 4864-4885 lsatactexampre com...xxx.xxx I Background concurrent copying GC freed 111727(6869KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 10034KB/19MB, paused 122us total 112.971ms 2024-04-29 19:50:09.785 4864-4885 lsatactexampre com...xxx.xxx I Background concurrent copying GC freed 132123(7836KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 12MB/24MB, paused 215us total 124.915ms 2024-04-29 19:50:19.288 2431-4576 ThermalTraceService com.huawei.iaware I code:1, appInfo:com.xxx.xxx#10000, levelInfo:0,warm_system_h,5
问题分析
修复代码的原理
ActionBar返回按钮(对应android.R.id.home)的点击事件会触发onOptionsItemSelected回调。默认情况下,当通过setDisplayHomeAsUpEnabled(true)显示返回按钮时,系统会尝试根据Manifest中配置的PARENT_ACTIVITY启动父Activity,但这个过程依赖正确的Activity栈管理和父Activity启动模式配置。
添加的代码直接拦截了home按钮的点击事件,调用super.onBackPressed()触发当前Activity的默认返回逻辑——遵循Activity栈的出栈规则,直接将当前Activity从栈中移除,绕过了系统基于父Activity配置的导航逻辑,避免了原逻辑中可能出现的阻塞。
问题突发的可能原因
- Activity栈异常:近期修改了Activity启动模式、任务栈配置,或是某些操作导致栈内Activity实例异常,使得系统无法正确定位父Activity,或启动父Activity时出现阻塞。
- Manifest配置失效:依赖库(如AppCompat)更新导致
android.support.PARENT_ACTIVITY的解析逻辑变化,或是配置的父Activity路径出现大小写、包名变更等错误,系统无法正确解析。 - UI层冲突:近期修改了Toolbar样式、主题,或是引入新UI库,破坏了系统默认的
home按钮事件分发逻辑,导致事件无法正常处理。 - 系统兼容问题:从Logcat可见涉及华为系统服务,可能是特定机型/系统版本更新后,默认导航逻辑出现兼容性问题,阻塞了事件处理流程。
注:当前Logcat未包含ANR的堆栈信息,建议下次复现时抓取/data/anr/traces.txt文件,可更精准定位阻塞线程与原因。
内容的提问来源于stack exchange,提问作者Diego Perez

