草庐IT

我是怎么一步步将SystemUI导入到AndroidStudio的

小驰笔记 2023-03-28 原文
这篇文件可能是你看过的写的最详细的关于SystemUI如何导入AS的文章了~

下面要讲的,是我如果一步步将SystemUI导入到AndroidStudio的。

 (备注:本文所讲内容的开发环境  ->   Android版本9.0  AndroidStudio 3.4   gradle插件版本 3.5)

 修改系统相关模块的代码,如果是小的修改还好,如果是需要改动比较多,那能将源码导入到AndroidStudio来修改是最好不过的了,修改效率会提高很多。

 这篇文件针对下面几点展开:

   一、下载SystemUI源码;    二、将SystemUI代码导入Eclipse,在Eclipse中导出工程gradle文件;    三、将SystemUI代码导入AndroidStudio;    四、导入过程遇到的问题及解决;   讲述重点会放在第四部分,遇到的问题及解决。

一、下载SystemUI源码

 SystemUI的代码,直接在Android源码中下载到本地来即可,在framewrok/bace/packages/目录下。

二、将SystemUI代码导入Eclipse,在Eclipse中导出工程gradle文件

 我们的终极目标是把SystemUI的代码导入到AndroidStudio,之所以先把工程导入到Eclipse,是借助eclipse帮我们生成工程需要的gradle文件,AndroidStudio的工程是依靠gradle来构建,有了这个gradle文件,下一步就可以导入AndroidStudio了。

导出gradle文件也很简单,选择我们的工程,右击,选择Export,选择Generate Gralde build files,然后一直next即可。

三、将SystemUI代码导入AndroidStudio

有了上面第二部分的导出的gralde文件,就可以打开AndroidStuido,找到工程目录,导入工程即可。

 导入工程后,会有报错,那肯定是正常的,不然就不会有第四部分的内容了。这里注意下gradle的版本,eclipse中导出的gradle版本可能会是比较旧的,这个需要根据自己的需要和提示的错误修改下。我是把gradle插件版本修改成了3.5.0

 

四、导入过程遇到的问题及解决

 将Android源码模块的代码导入到AndroidStudio之所以麻烦,就是源码模块的代码可能会涉及到引用的相关资源比较多,所谓的资源,就是jar或者系统其它的一些类。

  1)查看Android.mk涉及用到哪些资源

   源码的编译,是依靠.mk来进行编译,查看Android.mk,能帮我们大致了解下这个项目会用到哪些外部资源。

  LOCAL_STATIC_ANDROID_LIBRARIES 里面的,就是需要打包编译进apk的jar包  ----------------     LOCAL_STATIC_ANDROID_LIBRARIES := \     SystemUIPluginLib \     SystemUISharedLib \     android-support-car \     android-support-v4 \     android-support-v7-recyclerview \     android-support-v7-preference \     android-support-v7-appcompat \     android-support-v7-mediarouter \     android-support-v7-palette \     android-support-v14-preference \     android-support-v17-leanback \     android-slices-core \     android-slices-view \     android-slices-builders \     android-arch-core-runtime \     android-arch-lifecycle-extensions \LOCAL_JAVA_LIBRARIES  里面的jar,是只在编译的时候引用即可,不需要打包进apk,这些jar是系统本身的jar ----------------- LOCAL_JAVA_LIBRARIES := telephony-ext \     telephony-common \     android.car \     ims-common 2) 将需要的jar包导入到工程

  查看了Android.mk的内容,我们接下来就需要把相关的jar包导入到工程。好了,那这些jar包如何找呢。

  从Android.mk的内容我们看到,有2类jar包,一类是需要打包进apk的,一类是只需要编译阶段引用的。那我们找包的时候,也分2种情况来。

 LOCAL_STATIC_ANDROID_LIBRARIES 里面引用到的jar,可以在这个路径下找到对应的jar包:

这里列出的是androidx.annotation_annotation.jar的路径, 其它jar包也是类似方式查找,在./out/soong/.intermediates/prebuilts/sdk/current目录下

./out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.annotation_annotation/ android_common/turbine-combined/androidx.annotation_annotation.jarLOCAL_JAVA_LIBRARIES  里面引用到的jar,是在out/target/project/......./system/framework/目录下可以找到。

3) 问题:导入的不同jar包,包含了相同的内容

  通过上面的方式找到的jar,发现有个问题,就是不同的jar包,基本都包含了相同的内容。编译的时候会报Duplicate class 的错误。

 从下面这张图,我们可以看到,导入的3个不同的jar,都包含了相同的android.arch.*、android.support.*等等这些类,这个就导致编译直接报类重复了。 这个问题,在网上找了很多的解决方法,基本都是说导入jar包的时候,采用exclude字段,把重复的group或者module移除掉,不过我试的时候,直接提示gradle DSL 没有exclude。

我一直觉的可能是我找的jar包不对,不应该都包含有相同内容的,如果有知道原因的,可以和我说下,非常感谢!

######4)修改jar包,将jar包重复内容删除,再重新生成jar包

后面是没其它头绪了,就试着把jar包重复的内容删除,再重新合成jar包。

具体做法就是,把jar包后缀修改成zip,然后解压,删除重复的内容(这里删除内容,我只是删除了相关的重复类,本来的META-INF文件夹没有动)后,再通过jar cvf 命令,重新生成jar。

这个过程,就是不停的删除重复内容,然后再导出,再编译。

5)问题: More than one file was found异常

编译的时候,还遇到了下面的问题,说是META-INF/*** 内容有多个地方都有, 这个问题,我觉得的可能和上面第4点的内容有关, 删除重复包的时候,我还是保留原来的META-INF文件夹没有动。 

More than one file was found with OS independent path  'META-INF/androidx.legacy_legacy-support-core-ui.version'这个问题可以通过添加 packagingOptions {...}来进行解决,在工程的build.gradle 文件中添加,下面就是我添加的,提示那个有多的,就加下。

android {     compileSdkVersion 28     defaultConfig {         applicationId "com.android.systemui"         minSdkVersion 28         targetSdkVersion 28         versionCode 29     }     packagingOptions {         exclude 'META-INF/androidx.mediarouter_mediarouter.version'         exclude 'META-INF/androidx.localbroadcastmanager_localbroadcastmanager.version'         exclude 'META-INF/androidx.lifecycle_lifecycle-livedata-core.version'         exclude 'META-INF/androidx.appcompat_appcompat.version'         exclude 'META-INF/androidx.swiperefreshlayout_swiperefreshlayout.version'         exclude 'META-INF/androidx.cursoradapter_cursoradapter.version'         exclude 'META-INF/androidx.media_media.version'         exclude 'META-INF/androidx.drawerlayout_drawerlayout.version'         exclude 'META-INF/androidx.print_print.version'         exclude 'META-INF/androidx.versionedparcelable_versionedparcelable.version'         exclude 'META-INF/androidx.interpolator_interpolator.version'         exclude 'META-INF/androidx.palette_palette.version'         exclude 'META-INF/androidx.fragment_fragment.version'         exclude 'META-INF/androidx.customview_customview.version'         exclude 'META-INF/androidx.documentfile_documentfile.version'         exclude 'META-INF/androidx.vectordrawable_vectordrawable.version'         exclude 'META-INF/androidx.legacy_legacy-support-core-utils.version'         exclude 'META-INF/androidx.loader_loader.version'         exclude 'META-INF/androidx.lifecycle_lifecycle-runtime.version'         exclude 'META-INF/androidx.viewpager_viewpager.version'         exclude 'META-INF/androidx.asynclayoutinflater_asynclayoutinflater.version'         exclude 'META-INF/androidx.lifecycle_lifecycle-viewmodel.version'         exclude 'META-INF/androidx.recyclerview_recyclerview.version'         exclude 'META-INF/androidx.core_core.version'         exclude 'META-INF/androidx.arch.core_core-runtime.version'         exclude 'META-INF/androidx.vectordrawable_vectordrawable-animated.version'         exclude 'META-INF/androidx.slidingpanelayout_slidingpanelayout.version'         exclude 'META-INF/androidx.slice_slice-core.version'         exclude 'META-INF/androidx.coordinatorlayout_coordinatorlayout.version'         exclude 'META-INF/androidx.legacy_legacy-support-core-ui.version'     } }6) 问题:Duplicate class,support包合androidx包引用有冲突  错误提示:

Duplicate class android.support.v4.app.INotificationSideChannel found  in modules android-arch-lifecycle-extensions.jar  (android-arch-lifecycle-extensions.jar) and classes.jar (androidx.core:core:1.1.0-beta01)   解决方法: 在gradle.properties中添加启用androidx支持,gradle.proerties文件本来是没有的,没有的话,就自己创建个

android.useAndroidX=true

7) 问题:adb push apk进入,重启,提示权限错误

android.view.InflateException: Binary XML file line #87:  uid=10014 needs permission android.permission.READ_CONTACTS  to read lock_screen_owner_info_enabled for user 0  错误提示,需要android.permission.READ_CONTACTS 权限,这个权限在manifest中是有申请的了。后面参考了https://blog.csdn.net/grindstone_fos/article/details/53924295 提供的方法解决了。

 方法就是:执行adb命名,给与相应权限。我是遇到有2个权限需要通过下面方式来执行下才行。

 adb shell pm grant "com.android.systemui" "android.permission.READ_CONTACTS"          adb shell pm grant "com.android.systemui" "android.permission.READ_EXTERNAL_STORAGE"

8)问题: 提示资源找不到

 好不容易解决了上面的一堆的问题,下面是接着报了个资源找不到的问题。这个没查到是啥原因,后面是把调用到的代码暂时屏蔽了。

Line 1145: 12-28 14:27:52.209 E/AndroidRuntime( 2422): FATAL EXCEPTION: main Line 1146: 12-28 14:27:52.209 E/AndroidRuntime( 2422): Process: com.android.systemui, PID: 2422 Line 1147: 12-28 14:27:52.209 E/AndroidRuntime( 2422): android.content.res.Resources$NotFoundException: Resource ID #0x0 Line 1148: 12-28 14:27:52.209 E/AndroidRuntime( 2422):  at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:216) Line 1149: 12-28 14:27:52.209 E/AndroidRuntime( 2422):  at android.content.res.Resources.getDimensionPixelSize(Resources.java:727) Line 1150: 12-28 14:27:52.209 E/AndroidRuntime( 2422):  at androidx.slice.widget.ListContent.<init>(ListContent.java:103) Line 1151: 12-28 14:27:52.209 E/AndroidRuntime( 2422):  at androidx.slice.widget.ListContent.<init>(ListContent.java:88) Line 1152: 12-28 14:27:52.209 E/AndroidRuntime( 2422):  at com.android.keyguard.KeyguardSliceView.showSlice(KeyguardSliceView.java:161) Line 1153: 12-28 14:27:52.209 E/AndroidRuntime( 2422):  at com.android.keyguard.KeyguardSliceView.onChanged(KeyguardSliceView.java:343)

9)问题:AndroidRunTime 空指针异常

OverviewProxyService.java 中报了个空指针异常,获取到的 mRecentsComponentName 为空,也就是通过mContext.getString(com.android.internal.R.string.config_recentsComponentName)没法获取到对应的资源,后面是直接改成将string的内容写进去了。

  

写在后面

导这个工程花了比较多的时间,还好没有放弃~~


本人从事Android Camera相关开发已有5年

目前在深圳上班

欢迎大家关注我的微信公众号“小驰笔记”

大家一起学习交流

 ------- 2020.02.04   21:31 立春


有关我是怎么一步步将SystemUI导入到AndroidStudio的的更多相关文章

  1. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

  2. ruby - 怎么来的(a_method || :other) returns :other only when assigning to a var called a_method? - 2

    给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R

  3. ruby-on-rails - 我该怎么办 :remote location validation with CarrierWave? - 2

    我在我的Rails3示例应用程序上使用CarrierWave。我想验证远程位置上传,因此当用户提交无效URL(空白或非图像)时,我不会收到标准错误异常:CarrierWave::DownloadErrorinImageController#createtryingtodownloadafilewhichisnotservedoverHTTP这是我的模型:classPaintingtrue,:length=>{:minimum=>5,:maximum=>100}validates:image,:presence=>trueend这是我的Controller:classPaintingsC

  4. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  5. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  6. ruby - EventMachine - 你怎么知道你是否落后了? - 2

    我正在研究使用EventMachine支持的twitter-streamruby​​gem来跟踪和捕获推文。我对整个事件编程有点陌生。我如何判断我在事件循环中所做的任何处理是否导致我落后?有没有简单的检查方法? 最佳答案 您可以通过使用周期性计时器并打印出耗时来确定延迟。如果您使用的是1秒的计时器,您应该已经过了大约1秒,如果它更长,您就知道您正在减慢react器的速度。@last=Time.now.to_fEM.add_periodic_timer(1)doputs"LATENCY:#{Time.now.to_f-@last}"@

  7. ruby - 如果它是标点符号,我怎么能从字符串中删除最后一个字符,在 ruby​​ 中? - 2

    啊,正则表达式有点困惑。我正在尝试删除字符串末尾所有可能的标点符号:ifstr[str.length-1]=='?'||str[str.length-1]=='.'||str[str.length-1]=='!'orstr[str.length-1]==','||str[str.length-1]==';'str.chomp!end我相信有更好的方法来做到这一点。有什么指点吗? 最佳答案 str.sub!(/[?.!,;]?$/,'')[?.!,;]-字符类。匹配这5个字符中的任何一个(注意,。在字符类中并不特殊)?-前一个字符或组

  8. ruby - Ruby 中 <=> 运算符的名称是什么?他们怎么调用它? - 2

    在Ruby中有运算符(operator)。在API中,他们没有命名它的名字,只是:Theclassmustdefinetheoperator...Comparableusestoimplementtheconventionalcomparison......theobjectsinthecollectionmustalsoimplementameaningfuloperator...它叫什么名字? 最佳答案 参见上面的@Tony。然而,它也被称为(俚语)“宇宙飞船运算符(operator)”。

  9. Ruby:如何从另一个文件导入变量? - 2

    我正在尝试创建一个与compass一起使用的本地配置文件,这样我们就可以处理开发人员机器上的不同导入路径。到目前为止,我已经尝试将文件导入到异常block中,以防它不存在,然后进一步使用该变量:local_config.rbVENV_FOLDER='venv'config.rbVENV_FOLDER='.'beginrequire'local_config.rb'rescueLoadErrorendputsVENV_FOLDER通常我是一名Python开发人员,所以我希望导入将VENV_FOLDER的值更改为venv,但它仍然是。之后。有没有一种方法可以导入local_config.r

  10. ruby - Ruby 导入的方法总是私有(private)的吗? - 2

    最好用一个例子来解释:文件1.rb:deffooputs123end文件2.rb:classArequire'file1'endA.new.foo将给出错误“':调用了私有(private)方法'foo'”。我可以通过执行A.new.send("foo")来解决这个问题,但是有没有办法公开导入的方法?编辑:澄清一下,我没有混淆include和require。另外,我不能使用正常包含的原因(正如许多人正确指出的那样)是因为这是元编程设置的一部分。我需要允许用户在运行时添加功能;例如,他可以说“run-this-app--includefile1.rb”,应用程序的行为将根据他在file1

随机推荐