Android内置系统apk问题

平台:Rockchip
android版本: 7.1
个人博客:https://www.letcos.top/

1.问题描述

​ 一款产品需要内置定制的launcher,使用了一些第三方的sdk。按系统app的内置方法,增加share system uid获得系统权限。但是在使用的过程中大概率会出现系统应用setting(设置)闪退。并伴随录音服务挂掉,密钥链等问题(开始以为是独立的 bug,后面分析都是内置系统apk引起的问题)。

2. 分析思路

2.1 分析

查看logcat ,下面是关键log

03-12 10:48:50.247 1381 1381 E AndroidRuntime: Process: com.android.settings, PID: 1381
03-12 10:48:50.247 1381 1381 E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate application com.android.settings.SettingsApplication: java.lang.ClassNotFoundException: Didn’t find class “com.android.settings.SettingsApplication” on path: DexPathList[[zip file “/system/priv-app/Settings/Settings.apk”],nativeLibraryDirectories=[/system/priv-app/Settings/lib/arm64, /system/priv-app/Settings/Settings.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib, /system/lib, /vendor/lib]]

setting apk找不到32位的库,所以运行会闪退。那看一下系统内置的setting是多少位的。

//查看系统apk信息
adb shell dumpsys package p > dumpsys_p

在 dumpsys_P中找到setting的primaryCpuAbi=arm64-v8a,可见setting是64位apk。由于setting是64位apk,而且没有编译32位库,所以找不到32位库闪退就很好解释了。现在的问题是为什么64位的setting apk会到32位的目录下去找所需要的库?

 Package [com.android.settings] (f0c9a0e):
    userId=1000
    sharedUser=SharedUserSetting{f9d70ba android.uid.system/1000}
    pkg=Package{3232b02 com.android.settings}
    codePath=/system/priv-app/Settings
    resourcePath=/system/priv-app/Settings
    legacyNativeLibraryDir=/system/priv-app/Settings/lib
    primaryCpuAbi=arm64-v8a
    secondaryCpuAbi=null
    versionCode=25 minSdk=25 targetSdk=25
    versionName=7.1.2
    splits=[base]   
    ...

通过对比安装 launcher app挂掉之前和之后发现以下13个系统app被强制从64bit改到了32bit

package:/system/app/KeyChain/KeyChain.apk=com.android.keychain  //可能导致密钥链问题
package:/system/app/SoundRecorder/SoundRecorder.apk=com.android.soundrecorder //可能导致语音挂掉问题
package:/system/priv-app/SettingsProvider/SettingsProvider.apk=com.android.providers.settings
package:/system/app/RkExplorer/RkExplorer.apk=com.android.rk
package:/system/priv-app/InputDevices/InputDevices.apk=com.android.inputdevices
package:/system/priv-app/Telecom/Telecom.apk=com.android.server.telecom
package:/system/app/MediaFloat/MediaFloat.apk=com.android.rk.mediafloat
package:/system/priv-app/StressTest/StressTest.apk=com.cghs.stresstest
package:/system/priv-app/Settings/Settings.apk=com.android.settings
package:/system/app/WallpaperBackup/WallpaperBackup.apk=com.android.wallpaperbackup
package:/system/priv-app/FusedLocation/FusedLocation.apk=com.android.location.fused
package:/system/priv-app/DeviceTest/DeviceTest.apk=com.DeviceTest
package:/system/priv-app/FusedLocation/FusedLocation.apk=com.android.location.fused

不仅找到setting 被强制改为32位,还有13个apk也被修改为了32位。其中正好有之前遇到了2个问题:报密钥链错误和语音服务失效。原来这几个问题的根本原因都是我们内置app 使用了32位库,所有apk被判定位32位;而作为系统app,使用了系统的systemuid,由于andorid的机制规定一个进程只能是32位或64位中的一种,所有使用systemuid的apk都因为内置了launcher apk而强制变成32位。由于系统内置的64位apk没有对应的32位库,所有会闪退。

2.2 原理简介

android加载so文件的机制
apk在安装的过程中,系统就会对apk进行解析根据app的primaryCpuAbi值,确定这个apk安装是在32还是64位的虚拟机上,如果是32位虚拟机那么就不能使用64位so,如果是64位虚拟机也不能使用32位so。

而64位设备可以提供32和64位两种虚拟机,根据apk选择开启哪一种,因此说64位设备兼容32的so库。具体来说就是apk在安装的时候,apk解包的时候,就已经确定要加载多少位的库了,如果apk里面放有两种库,实际用的时候,也是只会加载一种库。

apk架构确定顺序

  1. 如果apk包中lib文件夹下有.so库,就根据这个.so库的架构模式,确定app的primaryCpuAbi的值
  2. 2.对于system app, 如果没法通过第一步确定primaryCpuAbi的值,PKMS会根据/system/app/{APP_NAME}/lib和/system/app/{APP_NAME}/lib64这两个文件夹是否存在,来确定它的primaryCpuAbi的值
  3. 3.对于还没有确定的app, 在最后还会将自己的primaryCpuAbi值与和他使用相同UID的package的值设成一样
  4. 4.对于到这里还没有确认primaryCpuAbi的app,就会在启动进程时使用ro.product.cpu.abilist这个property的值的第一项作为它关联的ABI

3. 解决方案

基于android加载so文件的机制,我们可以采用一下几种方法来解决该问题

  • apk不使用系统的uid,自己新增一个具有系统权限的uid(比较麻烦)

  • 把我们的apk修改为64位的,将所有使用的32位so替换为64位(可能有些三方so不提供64位版本)

  • 把所有32位库再封装一次,做成jar包,然后使用这些jar包。(需要自己封装)

  • 将所有32位库服务抽离出来,单独运行一个(或多个)进程。(需要提前确定好app的架构,不然需要重构app)

  • 在系统apk(例如:Settings)安装位置system/priv-app/xxx/目录下面建立一个lib/arm64文件夹.(利用apk架构确定顺序强制将系统apk变为64位)

  • 将系统apk编译为32位(可能影响性能)

            a.在apk对应的android.mk中 LOCAL_DEX_PREOPT := nostripping
            b./device/rockchip/rk3399/BoardConfig.mk,DEX_PREOPT_DEFAULT := nostripping
    

参考链接:

https://blog.csdn.net/weiqifa0/article/details/88432165

4.其他问题

4.1 系统签名

​ 当一个应用如果想通过sharedUserId的方式与另一个应用运行于同一个进程当中,这两个应用的签名必须保持一致。所以我们内置系统apk的时候需要使用系统签名。

​ apk系统签名可以参考:https://www.jianshu.com/p/63d699cffa1a

4.2 API版本过高

如果我们内置的API版本过高,那么在内置编译的时候会报错,这是由于odex机制的原因。

apk要预置进源码的时候,会对apk进行一个解析,好形成odex文件加速apk的运行,但是基于高版本的sdk开发的apk里面的一些资源是无法被低版本正确的解析

解决方法:

  • 降低apk 的API版本然后重新编译,保持和系统的API版本一致。(这样可能导致app某些功能不可用)
  • 关闭apk odex优化。(导致启动速度变慢)

在对应apk的Android.mk 文件中添加

LOCAL_DEX_PREOPT := false
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容