使用AS,编译、调试、使用系统级API

作者: imyyq_star | 来源:发表于2017-04-24 14:08 被阅读872次

    0、前言

    上一篇 编译调试Android系统原生App - 以Settings为例 详细介绍了如何在Eclipse中编译和debug系统app,这次来看一下如何在AS中编译和调试。

    1、AS中编译Settings

    还是那句话,AS的编译不友好,建议在Eclipse中把基本的编译过了后,再搬到AS中来。

    res 错误:
        Error: Found item String/*** more than one time
    原因:
    strings.xml出现了name相同,但是product不同的字符串资源,不知道为啥在AS中不支持这个,但是我们的关键不在这,所以写个小工具遍历一下去掉重复的,留下default的即可。
    

    解决了res的错误后,接下来就看src的错误了,** 主要的问题是如何提升系统jar的优先级 **,因为系统jar中有些类跟SDK中的类是一样路径的,AS默认使用的是SDK的类,所以就会导致有些隐藏方法在AS中报红,比如WifiManager这个类的connect方法。
    在Eclipse中这点很好做,但是在AS中我找了好多方法,要么是低版本AS的方法,有没有效我不知道,要么是试了没用的方法,找来找去,最终还是没有找到完美的解决方法。

    *** 以下的方法是我目前在用的,算是抛砖引玉,如果有朋友知道相关的解决方案,烦请一定留言告知。 ***

    提升系统jar的优先级,也就是提升下面3个jar的优先级:

    • framework.jar
    • core.jar
    • common.jar

    步骤:

    1. 新建app/system_libs文件夹,放入以上三个jar
    2. 在根目录的build.gradle中allprojects节点加入:
    gradle.projectsEvaluated {
            tasks.withType(JavaCompile) {
                options.compilerArgs.add('-Xbootclasspath/p:app/system_libs/framework.jar')
                options.compilerArgs.add('-Xbootclasspath/p:app/system_libs/core.jar')
                options.compilerArgs.add('-Xbootclasspath/p:app/system_libs/common.jar')
            }
        }
    

    在app/build.gradle中加入

    task pushDownJdkDependency {
        def imlFile = file("app.iml")
        println 'Change app.iml order'
        try {
            def parsedXml = (new XmlParser()).parse(imlFile)
            def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
            parsedXml.component[1].remove(jdkNode)
            new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': "Android API 24 Platform", 'jdkType': 'Android SDK'])
            def writer = new StringWriter()
            new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml)
            imlFile.text = writer.toString()
        } catch (FileNotFoundException e) {
            // nop, iml not found
        }
    }
    

    与android和dependencies节点是同一级别的。

    在dependencies中加入

        provided files('system_libs/framework.jar')
        provided files('system_libs/core.jar')
        provided files('system_libs/common.jar')
    

    最后sync项目,会发现无论怎么sync,Gradle都会报错,但是,在Gradle Console和Messages窗口中都没有错误提示,很奇怪。但是幸运的是src中那些之前提示没有找到对应类或方法的地方终于不报红了,也可以查看源码了。

    不过此时尝试build apk,还是会报找不到类,你是不是觉得我在逗你玩?哈哈哈,没有啦,我的确不知道更好的方法,以上这些是为下面的做铺垫,看到这还有兴趣的请继续看!!

    2、AS中调试Settings

    虽然上面第1步没有成功,但是至少已经解决了编译时的错误,现在已经可以调试Settings了,只不过无法直接运行debug调试,但是我们还是有办法调试Settings的,要注意的是,不要修改源码,为什么?因为你修改了就跟系统中的Settings是源码不一致了,调试自然就不可以了。所以说所谓的调试,只是利用AS来查看某些功能的流程和方便查看某些代码。并没有什么特别大的用处。

    如何调试:

    Paste_Image.png

    利用AS的这个按钮,就可Attached到com.android.settings这个进程,查看Settings的运行状态。

    好吧,这步其实没什么卵用,** 再没有可以直接debug的方式之前,也只能用Eclipse来调试了。 **

    当然,这种方式适用于任何app,只要是安装的app没有混淆过都可以。

    但是~~~这一步还是为下一步铺垫的,至少我们现在可以通过Attached查看Debug的状态了呀!!!

    3、AS中使用系统级API

    很多时候,我们并不需要在源码的基础上做项目,而是在我们自己的项目中引入系统jar,然后使用其功能就可以了。因此以上两步就派上用场啦。但是,(发现这篇文章好多个但是,哈哈哈)还是不能直接debug运行的,幸运的是,引入后,打包apk是没问题的,亲测是完全可以打包apk,然后安装或push到系统中,通过第二步的方式和log查看运行结果的。虽然差强人意,但是也算是解决了部分问题。如果你的项目是Eclipse的,那自然没问题,但是现在的项目大多数都是AS。

    总结

    通过以上步骤,至少可以在AS中使用系统级的API了,就是在AS中调试有点麻烦,但是如果在Eclipse中通过调试知道了某些系统API的使用方式,在AS上使用问题也不是很大。

    ** 在这里,希望有更好解决方案的朋友,随时候教。 **

    相关文章

      网友评论

      • 欠揍了:Hi,请问您在Studio中Settings编译成功了嘛?Settings项目转换成AS项目后的代码开源嘛?能否提个PR
        imyyq_star:无法运行,没有开源
      • 56febd9ee37c:小工具遍历一下去掉重复的 ?:wink: 怎么写呢

      本文标题:使用AS,编译、调试、使用系统级API

      本文链接:https://www.haomeiwen.com/subject/lgwuzttx.html