Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

插件APP切换到后台后再切换回前台,插件和宿主之间插入其他应用的层级关系,导致插件APK无法退回到宿主APK #1199

Closed
LeonWu6 opened this issue Jun 12, 2023 · 3 comments

Comments

@LeonWu6
Copy link

LeonWu6 commented Jun 12, 2023

在 shadow 的 sample APP 加载插件后,显示的UI是:com/tencent/shadow/sample/plugin/app/lib/gallery/cases/UseCaseSummaryFragment.java

这时,按手机的 Home 键,将 sample APP 切换到后台,
然后再通过 android 的近期任务栏将 sample APP 再切换回前台。
这时通过 adb shell dumpsys activity containers > activity_containers_shadow.txt 指令查看当前容器层级信息,发现 sample 的宿主和插件之间不会加入其他容器层信息。
层级关系如下:插件activity --> 宿主 activity

#1 ActivityRecord{97b453f u0 com.tencent.shadow.sample.host/com.tencent.shadow.sample.plugin.runtime.PluginDefaultProxyActivity t12} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#0 815fc2f com.tencent.shadow.sample.host/com.tencent.shadow.sample.plugin.runtime.PluginDefaultProxyActivity type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#0 ActivityRecord{c76a15d u0 com.tencent.shadow.sample.host/.MainActivity t12} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#0 bdb731d com.tencent.shadow.sample.host/com.tencent.shadow.sample.host.MainActivity type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]

而我的一个使用Shadow 框架的 APK,将插件apk加载起来后,再按Home键切到后台,
然后再通过近期任务栏将插件APK再切换回到前台。
这时,同样通过 adb shell dumpsys activity containers > activity_containers_em.txt 指令查看当前容器层级信息,发现宿主和插件之间会加入了 com.android.launcher 的层次关系。
层级关系如下:插件activity --> com.android.launcher --> 宿主 activity

#0 ActivityRecord{4130f91 u0 com.oplus.em/.runtime.PluginDefaultProxyActivity t8} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#0 e30a018 com.oplus.em/com.oplus.em.runtime.PluginDefaultProxyActivity type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#3 Task=1 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#0 Task=2 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#0 ActivityRecord{3388b3f u0 com.android.launcher/.Launcher t2} type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#0 68e6d0c com.android.launcher/com.android.launcher.Launcher type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#2 Task=7 type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#2 ActivityRecord{f3628ee u0 com.oplus.em/.MainActivity t7} type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]
#0 1cd801a com.oplus.em/com.oplus.em.MainActivity type=standard mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2412]

这个问题,使得我这个 apk 在切换到后台再切换回前台操作后,无法从插件apk的 activity 回到宿主 apk 的activity 中,而是会根据窗口容器层级树,直接从插件 apk 回到 launcher UI。

请教:
为什么Shadow sample app 可以在切换回后台再切回前台过程中,容器层级树上,插件app和宿主app之间不会插入 com.android.launcher ?是有哪些关键点被我忽略了吗?

请您指点迷津,十分感谢!

@shifujun
Copy link
Collaborator

这个问题只和Activity栈有关。Shadow在这个问题上特别简单,没有任何特殊处理。所以你需要关注的点就是PluginDefaultProxyActivity 等插件在宿主中的壳子Activity在manifest中声明的各种属性,比如singleTask等。对于系统来说,它只能看看是宿主启动了这个壳子Activity,即使相同的壳子配对了不同的插件activity。

查这个问题时你应该注意下切到后台前后Activity栈中的对象是否一致,也可能是重建的。还应该关注activity manager系统日志。另外我没什么见过launcher出现在栈里的印象。

没有代码就只能猜到这了。

@LeonWu6
Copy link
Author

LeonWu6 commented Jun 13, 2023

Hi shifujun @shifujun

感谢您的回复!
这个问题的原因我找到了。

我在一个APK(后面称为ParentAPK)中通过 startActivity() 的方式,启动了我的 com.oplus.em 宿主 APP的 MainActivity,但我没有加 Intent.FLAG_ACTIVITY_NEW_TASK 这个 flag,使得 com.oplus.em/.MainActivity 这个宿主APP的 activity 是在 ParentAPK 的task 里面,如下:

Task{7219a54 #92 type=standard A=1000:com.oplus.parentApk U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=3}
mLastPausedActivity: ActivityRecord{aee6e1 u0 com.oplus.em/.pluginhelper.PluginLoadActivity t-1 f}}
mLastNonFullscreenBounds=Rect(283, 690 - 797, 1770)
isSleeping=false
* Hist #2: ActivityRecord{3e483b3 u0 com.oplus.em/.MainActivity t92}
packageName=com.oplus.em processName=com.oplus.em

而我的 com.oplus.em 的插件 Activity 是在自己的 com.oplus.em 的 task 里面。如下:

* Task{9bd32b5 #95 type=standard A=1000:com.oplus.em U=0 visible=true visibleRequested=true mode=fullscreen translucent=true sz=1}
mLastNonFullscreenBounds=Rect(283, 690 - 797, 1770)
isSleeping=false
topResumedActivity=ActivityRecord{4c706c0 u0 com.oplus.em /.runtime.PluginDefaultProxyActivity t95}
* Hist #0: ActivityRecord{4c706c0 u0 com.oplus.em /.runtime.PluginDefaultProxyActivity t95}
packageName=com.oplus.em processName=com.oplus.em :plugin

所以,宿主APP 和插件 APP是在不同的两个 APP task 中。
所以,当插件APP从前台切换到后台,再切回前台时,插件 task和 宿主task 中间就插入了 launcher UI 的 task。

解决方法就是在 parentApk 启动我的 com.oplus.em 宿主APP 的 MainActivity 时,加上一个 flag:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
这样,com.oplus.em 的宿主和插件就在相同的 com.oplus.em 的task 中了,中间不会再插入其他 task。

@LeonWu6 LeonWu6 closed this as completed Jun 13, 2023
@itxiaox
Copy link

itxiaox commented Aug 4, 2023

我也碰到类似问题,宿主Activity通过shadow打开插件Activity后,关闭插件Activity,直接返回到桌面,并不是期望的返回到上个Activity, 即宿主Actvity; 经过实验发现比较奇怪的是,当我的插件apk时候一个简单的APK(demo.apk)的时候是符合预期的,能正常返回上个Activity, 但当我把插件apk换成实际复杂业务插件APK的时候就出现上面情况,有大佬碰到过类似情况吗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants