正常app開發過程中,編譯,打包過程都是android studio自動完成。如無特殊需求無需人為幹預,但是要實作插樁就必須在android studio的自動化打包流程中加入插樁的過程。
android studio采用gradle作為建構工具,所有有必要了解一下gradle建構的基本概念和流程。如果不熟悉可以參考一下下列文章:
<a href="http://www.cnblogs.com/davenkin/p/gradle-learning-1.html">gradle學習系列之一——gradle快速入門</a>
<a href="http://blog.csdn.net/innost/article/details/48228651">深入了解android之gradle</a>
gradle的建構工程實質上是通過一系列的task完成的,是以在建構apk的過程中就存在一個打包dex的任務。gradle 1.5以上版本提供了一個新的api:transform,官方文檔對于transform的描述是:
the goal of this api is to simplify injecting custom class manipulations without having to deal with tasks, and to offer more flexibility on what is manipulated. the internal code processing (jacoco, progard, multi-dex) have all moved to this new mechanism already in 1.5.0-beta1. the dex class is gone. you cannot access it anymore through the variant api (the getter is still there for now but will throw an exception)
transform can only be registered globally which applies them to all the variants. we'll improve this shortly.
there's no way to control ordering of the transforms.
transform任務一經注冊就會被插入到任務執行隊列中,并且其恰好在dex打包task之前。是以要想實作插樁就必須建立一個transform類的task。
gradle的執行腳本就是由一系列的task完成的。task有一個重要的概念:input的output。每一個task需要有輸入input,然後對input進行處理完成後在輸出output。
在android開發中我們經常使用到的plugin有:"com.android.application","com.android.library","java"等等。
每一個plugin包含了一系列的task,是以執行gradle腳本的過程也就是執行目标腳本所apply的plugin所包含的task。
建立一個module,選擇library module,module名字必須叫buildsrc
删除module下的所有檔案,除了build.gradle,清空build.gradle中的内容
然後建立以下目錄 src-main-groovy
修改build.gradle如下,同步
像普通module一樣建立package和類,不過這裡的類是以groovy結尾,建立類的時候選擇file,并且以.groovy作為字尾
自定義plugin:
8.inject.groovy, jarziputil.groovy
在app module下build.gradle檔案中添加新插件:<code>apply plugin: com.hotpatch.plugin.register</code>
建立一個單獨的module,命名為com.hotpatch.plugin.antilazyload:
使用上一篇部落格介紹的方法打包hack.jar。然後将hack.jar複制到app module下的assets目錄中。另外注意:app module不能依賴hack module。之是以要建立一個hack module,同時人為地在dex打包過程中插入對其他hack.jar中類的依賴,就是要讓apk檔案在安裝的時候不被打上<code>class_ispreverified</code>标記。
另外由于hack.jar位于assets中,是以必須要在加載patch_dex之前加載hack.jar。另外由于加載其他路徑的dex檔案都是在<code>application.oncreate()</code>方法中執行的,此時還沒有加載hack.jar,是以這就是為什麼在上一章節插樁的時候不能在<code>application</code>中插樁的原因。