当前位置: 首页 > 工具软件 > Android Astro > 使用案例 >

【Android】An activity without a UI must call finish() before onResume() completes

吕高昂
2023-12-01

今天在配合客户实现安装第三方app时,遇到一个问题,安装过程中,会长时间黑屏(30s~60s),最初怀疑是否是安装时,android系统资源(内存和CPU)剩余不多,导致安装时间较长,但是这样的话,解释不通,为什么会黑屏的问题,这时只能辛苦导出系统anr日志和logcat日志,一点一点去跟踪分析了,具体错误信息如下:

11-17 16:40:07.336  4415  4415 E pzz     : 安装APK文件
11-17 16:40:07.336  1330  1615 W ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:966 com.android.server.policy.PhoneWindowManager.interceptKeyBeforeQueueing:6214 com.android.server.wm.InputMonitor.interceptKeyBeforeQueueing:448 com.android.server.input.InputManagerService.interceptKeyBeforeQueueing:1971 <bottom of call stack> 
11-17 16:40:07.338  1330 20989 I ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://com.feid.feidterminal.FileProvider/download/DownLoadFeiD/mt.apk typ=application/vnd.android.package-archive flg=0x10000001 cmp=com.android.packageinstaller/.InstallStart} from uid 10041
11-17 16:40:07.338  1330  1614 D WindowManager: mHIKKeyPolicy.interceptKeyBeforeDispatching
11-17 16:40:07.339  1330  1614 W KeyPolicyImpl: interceptKeyBeforeQueueing keyCode :140
11-17 16:40:07.341   400   400 W /system/bin/hwservicemanager: getTransport: Cannot find entry vendor.qti.hardware.iop@1.0::IIop/default in either framework or device manifest.
11-17 16:40:07.341  1330 20989 E ANDR-PERF-JNI: Iop tryGetService failed
11-17 16:40:07.345  1330 20989 D ActivityTrigger: activityStartTrigger: Activity is Triggerred in full screen ApplicationInfo{8d91d53 com.android.packageinstaller}
11-17 16:40:07.345  1330 20989 E ActivityTrigger: activityStartTrigger: not whiteListedcom.android.packageinstaller/com.android.packageinstaller.InstallStart/27
11-17 16:40:07.345  1330 20989 D CompatibilityInfo: mCompatibilityFlags - 4
11-17 16:40:07.345  1330 20989 D CompatibilityInfo: applicationDensity - 160
11-17 16:40:07.345  1330 20989 D CompatibilityInfo: applicationScale - 1.0
11-17 16:40:07.346  1330 20989 D ActivityTrigger: activityResumeTrigger: The activity in ApplicationInfo{8d91d53 com.android.packageinstaller} is now in focus and seems to be in full-screen mode
11-17 16:40:07.346  1330 20989 E ActivityTrigger: activityResumeTrigger: not whiteListedcom.android.packageinstaller/com.android.packageinstaller.InstallStart/27
11-17 16:40:07.350  1330 20989 D ActivityTrigger: activityResumeTrigger: The activity in ApplicationInfo{8d91d53 com.android.packageinstaller} is now in focus and seems to be in full-screen mode
11-17 16:40:07.350  1330 20989 E ActivityTrigger: activityResumeTrigger: not whiteListedcom.android.packageinstaller/com.android.packageinstaller.InstallStart/27
11-17 16:40:07.354  1330 20989 D CompatibilityInfo: mCompatibilityFlags - 4
11-17 16:40:07.354  1330 20989 D CompatibilityInfo: applicationDensity - 160
11-17 16:40:07.354  1330 20989 D CompatibilityInfo: applicationScale - 1.0
11-17 16:40:07.355  1330 20989 D CompatibilityInfo: mCompatibilityFlags - 4
11-17 16:40:07.355  1330 20989 D CompatibilityInfo: applicationDensity - 160
11-17 16:40:07.355  1330 20989 D CompatibilityInfo: applicationScale - 1.0
11-17 16:40:07.366   540  3460 D msm8916_platform: platform_set_channel_map mixer_ctl_name:Playback Channel Map12
11-17 16:40:07.367   540  3460 D msm8916_platform: platform_set_channel_map: set mapping(1 2 0 0 0 0 0 0) for channel:2
11-17 16:40:07.367   540  3460 D audio_hw_primary: start_output_stream: exit
11-17 16:40:07.369  1330  1343 I ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://com.feid.feidterminal.FileProvider/download/DownLoadFeiD/mt.apk typ=application/vnd.android.package-archive flg=0x2000000 cmp=com.android.packageinstaller/.InstallStaging (has extras)} from uid 10015
11-17 16:40:07.372  1330  1343 D ActivityTrigger: activityStartTrigger: Activity is Triggerred in full screen ApplicationInfo{8d91d53 com.android.packageinstaller}
11-17 16:40:07.372  1330  1343 E ActivityTrigger: activityStartTrigger: not whiteListedcom.android.packageinstaller/com.android.packageinstaller.InstallStaging/27
11-17 16:40:07.373  1330  1343 D CompatibilityInfo: mCompatibilityFlags - 4
11-17 16:40:07.373  1330  1343 D CompatibilityInfo: applicationDensity - 160
11-17 16:40:07.373  1330  1343 D CompatibilityInfo: applicationScale - 1.0
11-17 16:40:07.373  1330  1343 D ActivityTrigger: activityResumeTrigger: The activity in ApplicationInfo{8d91d53 com.android.packageinstaller} is now in focus and seems to be in full-screen mode
11-17 16:40:07.373  1330  1343 E ActivityTrigger: activityResumeTrigger: not whiteListedcom.android.packageinstaller/com.android.packageinstaller.InstallStaging/27
11-17 16:40:07.373  1330  1343 D ActivityTrigger: ActivityTrigger activityPauseTrigger 
11-17 16:40:07.374  1330  1343 D zww     : acquireWakeLock ~~~
11-17 16:40:07.374  1330  1343 D zww     : acquireWakeLockInternal: lock=240036497, flags=0x1, tag="*launch*", ws=WorkSource{10015}, uid=1000, pid=1330
11-17 16:40:07.374  1330  1343 E PowerManagerService: Read the path /sys/class/power_supply/usb/usb_otg successfully, the value is 1
11-17 16:40:07.384  1330  4261 D ActivityTrigger: activityResumeTrigger: The activity in ApplicationInfo{8d91d53 com.android.packageinstaller} is now in focus and seems to be in full-screen mode
11-17 16:40:07.384  1330  4261 E ActivityTrigger: activityResumeTrigger: not whiteListedcom.android.packageinstaller/com.android.packageinstaller.InstallStaging/27
11-17 16:40:07.386  1330  4261 D CompatibilityInfo: mCompatibilityFlags - 4
11-17 16:40:07.386  1330  4261 D CompatibilityInfo: applicationDensity - 160
11-17 16:40:07.386  1330  4261 D CompatibilityInfo: applicationScale - 1.0
11-17 16:40:07.440 21292 21292 W Activity: An activity without a UI must call finish() before onResume() completes

查问题的老方法,我们需要先看一下,系统为什么会报出这个异常,通过搜索源码发现,android 6.0之后,在/frameworks/base/core/java/android/app/Activity.java 中的**performResume()**方法添加了如下判断:

 final void performResume() {
        performRestart();
       // 此处省略一万code ......

        // invisible activities must be finished before onResume() completes
       // 原因在这里,对比android5.x与6.0之后的此处源码,可知,新增了这个判断
       // 判断当然视图是否可见,如果不可见,需要在onResume()中调用finish操作
        if (!mVisibleFromClient && !mFinished) {
            Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
            if (getApplicationInfo().targetSdkVersion
                    > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
                throw new IllegalStateException(
                        "Activity " + mComponent.toShortString() +
                        " did not call finish() prior to onResume() completing");
            }
        }

        // Now really resume, and install the current status bar and menu.
        mCalled = false;

        mFragments.dispatchResume();
        mFragments.execPendingActions();

        onPostResume();
        if (!mCalled) {
            throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onPostResume()");
        }
    }

由此可知,App代码中,应该是调用了什么属性或者进行了什么操作,导致视图不可见,进而导致视图运行时进入了这个判断,系统抛出了这个异常。

一层一层的抽丝剥茧去看,这时我们再从Activity: An activity without a UI must call finish() before onResume() completes错误往回看日志,找到开头,可以发现,是app内部调用了packageinstaller之后爆发了这一系列问题,与客户进行沟通,发现,客户想要通过自己的app实现后台安装其他app,从上面分析可知,是在安装app过程中,系统报出的这个错误,所以我们找客户确认了一下,的确app代码中,进行了如下设置:

//xml中调用
<activity android:name=".xxxActivity" 
    android:theme="@android:style/Theme.Translucent.NoTitleBar"/>

//代码中在onCreate之前调用
 setTheme(android.R.style.Theme_NoDisplay);

小结
问题原因找到了,我们现在想需要想解决方法,有上面的源码分析,可知,应用更新时,必然会调用到系统的packageInstall,而android6.0之后的系统,抛出这个异常的前提是,会去判断getApplicationInfo().targetSdkVersion android.os.Build.VERSION_CODES.LOLLIPOP_MR1,所以解决方法有以下三个:
1) APP中,对于android系统做兼容处理,在android6.0之后的系统中,需要将android.R.style.Theme_No_Dispaly属性改为android.R.style.Theme_Translucent_NoTitleBar
2) APP中,将targetSdkVersion修改为小于等于android.os.Build.VERSION_CODES.LOLLIPOP_MR1(即 SDK API 21)。
3) 系统源码中,适配客户需求,当然了不能简单的只是把6.0之后performResume中新增的判断去掉这样修改,因为系统源码环环相扣,还是要了解设计者的意图,才可以去删除代码。

 类似资料: