准备工作
写在最前面,迁移过程中必然会出现很多的问题,整个过程可能会花费比较长的时间,所以要做好心理准备,有问题可留言,一起探讨。
- 需要先在虚拟机上源码整编通过,因为迁移会用到一些编译生成的jar包之类的
- 环境:
- AndroidStudio:最开始是Android Studio 3.5.2 后面因为一直报错就更新到 Android Studio Electric Eel | 2022.1.1 Patch 1
- gradle:最开始是是用的3.5.2,后面一直报错就跟as一起升级了,gradle版本用的4.0.1
- 我这边是迁移的Android 10的systemui
- jdk 永远的1.8
迁移
参考文章:
https://blog.csdn.net/A601023332/article/details/108028937
https://www.jianshu.com/p/6efee2c698a6
https://blog.csdn.net/Mr_ZJC/article/details/104173196
-
新建空as项目(建议选择有kt版本的,因为systemui里面有kt的代码,就不用后面自己来引包配置之类的了)
-
把源码com.anroid下面的systemui和keyguard代码拿进来放到app/src/main/java/com.android下,把源码的res和res-keyguard 拿进来放到app/src/main 下
-
新建4个module-new Android Library
模块名 包名 legacy com\android\systemui\recents plugin com\android\systemui\plugins plugin-core com\android\systemui\plugins shared com\android\systemui\shared settingslib com.android.settingslib -
把所有模块的源码的src下面的代码,以及.bp和manifest文件放入到对于的路径下面
如果需要转成Androidx 可以看下这篇 文章:https://www.jianshu.com/p/1466ebefe4d0
此时的路径长这样:
遇见的错误及解决方案
- 错误: -source 1.7 中不支持默认方法
(请使用 -source 8 或更高版本以启用默认方法)
请参考:https://blog.csdn.net/China_Style/article/details/88418139
- Found item String/kg_failed_attempts_almost_at_wipe more than one time
重复的资源配置,删除tablet的这一类
//使用如下正则可以快速替换
(.*?)<string name="(.*?)" product="tablet" msgid="(.*?)">(.*?)</string>(.*?)
- AAPT: error: resource android:color/notification_material_background_color not found.
资源找不到,我是直接替换成具体的RGB颜色值的,用chatgpt问的每一个颜色对应的rgb
- MethodHandle.invoke and MethodHandle.invokeExact are only supported starting with Android O (–min-api 26)
修改所有模块下的gradle的minSdkVersion为26
- error: resource android:style/Theme.Material.QuickSettings not found.
修改gradle配置文件(这个搞了几乎一整天!!!)
之前:
android {
compileSdkVersion 34
buildToolsVersion "34.0.0"
defaultConfig {
applicationId "com.android.systemui"
minSdkVersion 29
targetSdkVersion 34
...
}
}
现在:
android {
compileSdkVersion 29
buildToolsVersion "34.0.0"
defaultConfig {
applicationId "com.android.systemui"
minSdkVersion 29
targetSdkVersion 29
...
}
}
- 错误: 找不到符号
符号类 WirelessUtils
位置:程序包 com.android.settingslib
这个问题是因为我的settingslib模块的gradle配置错了
以前的:
java.srcDirs = [
'../src/main/java',
]
现在的:
java.srcDirs = [
'src/main/java',
]
- androidx.mediarouter_mediarouter-nodeps
我的settingslib模块的Android.bp 里面有一个静态引用是androidx.mediarouter_mediarouter-nodeps,build.gradle直接改成即可
implementation 'androidx.mediarouter:mediarouter:1.0.0'
- Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.1.16.
systemui源码里面有kotlin的代码,当初新建项目的时候新建的是java语言的,所以项目里面没有配置kotlin相关的,导致编译代码的时候报错找不到kt的文件,于是我自己手动加了一些kotlin的配置进去后,就报了这个错误。最后我是参考这篇文章来解决的: https://juejin.cn/post/7114218994831687688#comment 。我的做法比较粗暴:将kotlin的依赖版本号改为报错里面最高的一个版本号,这个看情况而定,最好选择新建一个kotlin的项目,应该就不会有这个问题了
- Error: Duplicate resources
这个简单,删除重复的就行,需要注意的是:我最开始点击的下面具体的报错这里是不会给你指出具体是哪一个资源配置在报错的,应该点击上面的这个就能看见所有的具体的报错的资源名称。
,
在经历过九九八十一难过后终于能编译通过了
但是跑出来似乎没看见我的systmeui呀!!我痛哭!
- LeakReporter_Factory
根据报错日志可以发现是找不到类LeakReporter_Factory,于是跟了下代码,最终发现这个类在SystemUI-tags.jar里面定义的,于是…修改app的build.gralde对 SystemUI-tags.jar的依赖方式:
之前:
compileOnly files('../jar/SystemUI-tags.jar')
现在:
implementation files('../jar/SystemUI-tags.jar')
- Duplicate class android.support.v4.xxxx
ok,没有意外,又报错了,类重复引用错误,由于我刚刚把SystemUI-tags也引用进来了,所以报了很多重复的问题,看了最下面一行,区区3586个错误而且(图片是删了一些类后编译再报的错误数量,最开始忘记截图了),来吧,我采用的方式是将SystemUI-tags解压,直接删除里面的重复类,试了下这种方式是可以减少重复类引用的报错的…
- More than one file was found with OS independent path META-INF/androidx.localbroadcastmanager_localbroadcastmanager.version
果然,经过我一阵删除之后依旧报错
可以借鉴这位老哥的文章:https://blog.csdn.net/qq_38287890/article/details/101204604
- Program type already present: androidx.core.app.INotificationSideChannel
因为引用的库太多了,所以有时候可能你引用的本地jar里面跟Android自身引用的jar有重复的地方,比如这个INotificationSideChannel类就是在androidx.core和SystemUI-tags.jar!\android\support\v4\app 也有,我删了systemui_tag 里面的类在重新编译的
或者 参考这位老哥的文章 : https://blog.csdn.net/Calvin_zhou/article/details/80880501,使用configurations将多余的依赖排除掉,后面我发现这种all*全部排除的方式也不是很好,可能其他库会用到这个group,这样又会导致其他库找不到这个group里面的类了,所以还是按需exclude。
//直接全部排除掉重复冲突的整个group
configurations {
all*.exclude group: 'xxx'
}
//按需选择需要排除的依赖里面的group,此时依赖树的重要性就体现出来了,因为你需要通过查看依赖树来判断哪些是引用了这个group的
implementation ('group:module:version') {
exclude group: 'xxx', module: 'xxx'
}
- Unresolved reference: BATTERY_ESTIMATES_LAST_UPDATE_TIME
这个是settingslib模块的Estimate类引用的系统的全局常量找不到了,但是能点进去而且能看到这个常量,仔细看就可以发现这个常量是被hide了的,所以我直接在代码里面把常量值拿进来用了,hh
- error: resource style/TextAppearance.Compat.Notification.Info (aka com.android.systemui:style/TextAppearance.Compat.Notification.Info) not found.
内心逐渐崩溃… == 这个问题可能就是由于上面exclude了导致的,折腾了一天,我没在代码里面看见哪里在引用这个style,所以我 在app里面的styles.xml加了一个报错的这个空样式
- 错误: 找不到符号
符号: 方法 newInstance(Context,AttributeSet,Boolean,Object,AmbientPulseManager,DynamicPrivacyController,ConfigurationController,ActivityStarterDelegate,StatusBarStateControllerImpl)
位置: 类 NotificationStackScrollLayout_Factory
app的gradle里面引用了dagger相关的依赖,版本最开始用的2.19,但是由于之前报错 error:Program type already present: androidx.core.os.IResultReceiver
$Stub$
Proxy 类冲突的时候把版本改到2.46.1 然后解决了这个IResultReceiver类冲突问题,但是现在在2.46.1版本里面的DaggerSystemUIFactory_SystemUIRootComponent类要引用的 NotificationStackScrollLayout_Factory.newInstance()不存在,
- Program type already present: androidx.core.os.IResultReceiver
$Stub$
Proxy
又是熟悉的bug… 给 androidx.legacy:legacy-support-v4:1.0.0 加了 exclude group: ‘androidx.core’, module: 'core’后解决
后面又经历了几天的Program type already present: androidx.core.os.IResultReceiver
$Stub$
Proxy这个问题,改了改去,改了好久都没改好,一直报这个错误,都把所有的远程依赖都exclude排除了androidx.core但是还是会有这个问题,已经崩溃了…
昨天周一,心情不好,请假了一天,一天都在家窝着,感觉不错,用投影仪看了动漫《空想新子和她的千年魔法》,感觉挺治愈的,看了一点荒野求生,然后买了一坨喜欢吃的榴莲,有点熟过头了…
然后今天周二一早来就想着用新建空项目来把gradle里面的依赖都放进来看看会不会报错,版本号这些参考了下以前自己的项目,但是由于gradle版本太新了,我目前 用的这个as不支持,所以去找了个今年一月份的版本,然后依赖拿进来编译是不报错的,能正常生成apk,然后把systemui的gradle版本号这些参考这个空项目改一下,就可以编译成功了!!!
所以我想说的是:如果有一个bug卡了好几天,别急,停下来休息一下,或许明天就会有意想不到的收获,祝你幸运。
至此算是一个阶段性胜利。yeah!
总结一下:以上这么长一段话可以总结成一句话就是:换了个新一点的as编辑器
但是,还是没有ui显示出来,logcat中看见有崩溃日志,这里就不细说了,大家按照自己的报错来修改就行
- android:textColor=“?attr/wallpaperTextColor”
类似attr/xxx的这种分两种情况:
1、自定义的属性:在attrs.xml中定义的,然后在styles.xml中,对应的清单文件引用的style样式中去赋值,这里有时候赋值是用的Android原生的xml资源,引用方式类似 @android:color/xxx,但是这种方式有时候会引用不到,会报运行时错误,去掉号的话能点进去看到对应的具体的样式,但是运行的话会报错说这个资源是private的,所以我是直接把这个资源拷贝到res下面去引用的
2、Android 源码里面的属性:并且是在源码里面赋值的,但是不知道为什么这个资源还是引用不到,会报错找不到。留坑~
- Caused by: android.view.InflateException: Binary XML file line #59 in com.android.systemui:layout/super_status_bar: uid=10012 needs permission android.permission.READ_CONTACTS to read lock_screen_owner_info_enabled for user 0
07-13 18:52:11.890 2402 2402 E AndroidRuntime: Caused by: java.lang.SecurityException: uid=10012 needs permission android.permission.READ_CONTACTS to read lock_screen_owner_info_enabled for user 0
权限错误,参考了这个老哥的方法解决的,执行adb命令即可。
adb shell pm grant “com.android.systemui” “android.permission.READ_CONTACTS”
adb shell pm grant “com.android.systemui” “android.permission.READ_EXTERNAL_STORAGE”
- 耗时半个月,还好没有放弃,虽然有些ui面目全非了,但是好歹迁移过来了,按需修改吧!加油!