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

插件targetSdkVersion版本过高问题 #582

Closed
qq8803128 opened this issue Aug 14, 2021 · 14 comments
Closed

插件targetSdkVersion版本过高问题 #582

qq8803128 opened this issue Aug 14, 2021 · 14 comments

Comments

@qq8803128
Copy link

当插件的androidManifest.xml只存在manifest节点的情况,打包成插件apk之后manifest里面只有manifest和use-sdk的情况,目前我就测试了targetSdkVersion为28和30的情况:
当插件的targetSdkVersion为28的时候,packageManager.getPackageArchiveInfo可以获取到PackageInfo;
当插件的targetSdkVersion为30的时候,获取不到PackageInfo信息,在androidManifest文件添加application节点后打包可以获取到PackageInfo
由于shadow的pluginmanager.apk也使用了packageManager.getPackageArchiveInfo,导致无法初始化
测试设备小米11
android11
miui 12.5.9

@qq8803128
Copy link
Author

由于这个是android系统packageManager自己解析的问题,无法处理,因此只能添加提示
`
class ChangeApkContextWrapper extends ContextWrapper {
private Resources createResources(String apkPath, Context base) {
PackageManager packageManager = base.getPackageManager();
PackageInfo packageArchiveInfo = packageManager.getPackageArchiveInfo(apkPath, GET_META_DATA);
if (packageArchiveInfo == null){
throw new RuntimeException("获取插件"+ new File(apkPath).getName() + "信息失败,"+ "原因可能是插件targetSdkVersion过高,可以通过降低targetSdkVersion版本或者在插件androidManifest文件中添加一个application节点解决。");
}
packageArchiveInfo.applicationInfo.publicSourceDir = apkPath;
packageArchiveInfo.applicationInfo.sourceDir = apkPath;
try {
return packageManager.getResourcesForApplication(packageArchiveInfo.applicationInfo);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}

}

}
`

@shifujun shifujun added the bug Something isn't working label Aug 16, 2021
@shifujun
Copy link
Collaborator

我没法复现这个问题。麻烦fork一下,如果能复现,把修改push上来看看。

按照你说的情况,应该是打包的apk中的AndroidManifest.xml有问题。那么应该和运行的设备无关。

我把所有版本都改到30,也会有application项。
要么是:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    android:compileSdkVersion="30"
    android:compileSdkVersionCodename="11"
    package="com.tencent.shadow.sample.manager"
    platformBuildVersionCode="30"
    platformBuildVersionName="11">

    <uses-sdk
        android:minSdkVersion="30"
        android:targetSdkVersion="30" />

    <application
        android:extractNativeLibs="false" />
</manifest>

要么至少是空的tag:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="local"
    android:compileSdkVersion="30"
    android:compileSdkVersionCodename="11"
    package="com.tencent.shadow.sample.host"
    platformBuildVersionCode="30"
    platformBuildVersionName="11">

    <uses-sdk
        android:minSdkVersion="30"
        android:targetSdkVersion="30" />

    <application />
</manifest>

@shifujun shifujun added question and removed bug Something isn't working labels Aug 16, 2021
@qq8803128
Copy link
Author

@shifujun 我这边使用的是idea2020.1编译android工程,如果自己不在androidManifest里面手动添加application节点的话,编译后的apk不会存在application节点

@qq8803128
Copy link
Author

Uploading image.png…
idea版本信息

@qq8803128
Copy link
Author

我这边写了一个demo,2个pluginmanager.apk ,唯一的区别就是targetSdkVersion不同,一个是30,一个是28,androidManifest里面都不存在application节点,但是28的可以解析,30的无法解析,demo我发下吧
app-debug.zip,我用as自带的30的模拟器也测试过,跟我用手机一样的结果,都是30的无法解析,28的可以解析

@shifujun
Copy link
Collaborator

你这个app-debug.zip的源码push上来看看吧。打包apk的行为应该主要还是受AGP的版本影响。AGP可能会参考targetSDK改变逻辑。

@qq8803128
Copy link
Author

@shifujun 应该不需要吧,你可以直接用PackageManager解析assets里面的2个pluginmanager.apk、pluginmanager28.apk就可以看到pm无法解析第一个apk文件

@shifujun
Copy link
Collaborator

你有无法解析的apk文件这个我信,不用测。但是这不解决问题呀,得找出来它为什么会产生。

@qq8803128
Copy link
Author

@shifujun 我看了下,插件的targestSdkVersion版本如果是android11的话,PMS解析包会调用到
image
PackageParser2,感觉就是这里除了问题,我查看了下android的源码,发现这个AppIntegrityManagerServiceImpl是android11新增的一个类,这个类的相关信息https://shuma.jcoal.com/shuma/20210409_0439087.html这边有介绍,感觉就是这个类的问题吧,但是我没有找到为啥targetSdkversion=30的时候在哪里判断调用到这个类的

@shifujun shifujun removed the question label Aug 17, 2021
@shifujun
Copy link
Collaborator

我大概清楚了。通过枚举测试不同版本的AGP,我确定这个问题应该是AGP已经修复的Bug。3.6.0以及更早的版本有不生成<application />的问题。从4.0.0开始就修复了。这个问题和targestSdkVersion或者其他version都没有关系。

因此我觉得这个问题Shadow不用特别兼容。对于适用低于4.0.0的项目,如果遇到此问题,建议主动写一个<application />来workaround。

https://developer.android.com/studio/releases/gradle-plugin

@qq8803128
Copy link
Author

@shifujun 但是对于targetSdkVersion<30,不存在application节点还是可以解析的,所以理论上我觉得这个问题产生的根本原因还是PackageManager的问题吧

@shifujun
Copy link
Collaborator

估计是AGP的开发和PackageManager的开发在这个细节上早先没有对齐吧。PackageManager和AGP对我们来说都是黑盒的API,从一个API获取到的apk作为输入给另一个API,有问题也只能是这个黑盒自己的bug。所以到底是PackageManager的bug还是AGP的bug,对我们来说不重要。

@qq8803128
Copy link
Author

在系统版本低于30的手机上面不存在application节点的apk都可以解析,不受插件apk的targetSdkVersion影响
在系统版本=30的手机上面,如果apk的targetSdkVersion版本>=30,需要apk的androidManifest中存在application节点,
targetSdkVersion<30的话,表现和系统版本低于30的手机上面一致

@shifujun
Copy link
Collaborator

一个targetSdkVersion>=30的app,使用低于4.0.0的AGP构建,恐怕有点不太匹配了吧。

shifujun added a commit to shifujun/Shadow that referenced this issue Aug 17, 2021
避免4.0.0以下版本生成没有<application />的apk,在targetSdkVersion>=30时,在API 30以上的手机上Crash。

Tencent#582
shifujun added a commit that referenced this issue Aug 17, 2021
避免4.0.0以下版本生成没有<application />的apk,在targetSdkVersion>=30时,在API 30以上的手机上Crash。

#582
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

2 participants