天天看點

《Android插件化開發指南》勘誤

一些常識:

1)全書70個代碼例子中,涉及到插件的例子,請先assemble插件的項目,這會在HostApp項目中生成assets目錄,并在該目錄下plugin1.apk。這樣,HostApp才能正常運作。

2)本書基于Android6.0(API level 23)的源碼進行分析,本書的代碼在Android7.0(API level 24)手機上測試都是能正常工作的。對于Android 7.0以上版本,有些插件化的解決方案,已經過時了,比如AMN的gDefault字段。

3)針對于Android8.0(API 26),Android8.1(API 27),Android9(API 28),插件化所需要做的适配工作,參加以下3篇文章(第2版作為第23章會放入書中):

      Android插件化的相容性(上):Android O的适配

      Android插件化的相容性(中):Android P的适配

      Android插件化的相容性(下):突破Android P中灰黑名單的限制

-----------------------------------------------------------

2018年8月第1版第1次印刷和第2次印刷

1)前言

比如說AssetsManager的addAssetPath方法,ActivityThread的currentActivityThread方法。

這句話删除,舉例不當。

2)第2章,P25

ActivityManagerNativ改為ActivityManagerNative

3)第3章,P73

如果隻想擷取類的所有public構造函數,就不能再使用Class的getConstructors方法了,而要使用getDeclaredConstructors方法。

這裡寫反了,訂正如下:

如果隻想擷取類的所有public構造函數,隻要調用Class的getConstructors方法就足夠了。

4)第6章,P133

applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def file = output.outputFile
            output.outputFile = new File(file.parent,
                    "plugin1.apk")

            println("$buildDir/outputs/apk/")
            println("$rootDir/HostApp/src/main/assets")

            copy {
                from "$buildDir/outputs/apk/plugin1.apk"
                into "$rootDir/HostApp/src/main/assets"
            }
        }
}      

上面這段腳本,有個瑕疵,要執行兩次的插件項目中的assembleRelease指令,才能在HostApp的assets目錄下生成plugin1.apk,訂正如下:

assemble.doLast {
    android.applicationVariants.all { variant ->
        // Copy Release artifact to HostApp's assets and rename
        if (variant.name == "release") {
            variant.outputs.each { output ->
                File originFile = output.outputFile
                println originFile.absolutePath
                copy {
                    from originFile
                    into "$rootDir/HostApp/src/main/assets"
                    rename(originFile.name, "plugin1.apk")
                }
            }
        }
    }
}      

接下來,執行插件項目的assemble指令,隻要1次,即可生成在HostApp的assets目錄下生成plugin1.apk。

5)第2章 P32

App和ASM頻繁地向對方發送消息

修改為:App和AMS頻繁地向對方發送消息

6) 第2章,P44

2.9.2

在Service中,通過AMM/AMP

訂正為:

在Service中,通過AMN/AMP

7)第2章,P37

仍然是通過AMM/AMP

訂正為:仍然是通過AMN/AMP

8)前言,P5

把android-pluginmgr設計為對Instrumentation的思想進行Hook

訂正為: 把android-pluginmgr設計為對Instrumentation進行Hook

9)第18章,P287

ZeusStudy和1.6之間不應該有空格

10)第2章 P21

AndvoidManifest修改為AndroidManifest

11)第2章 P22

哪個,修改為那個

12)P101

圖中,多了一個-

13)P102,第9行末尾,重寫的邏輯,把英文句點改為中文句号。

14)P56

“主要邏輯都再此實作”中的“再此”應該為“在此”

15)113頁

“對AMN的getDafault方法進行Hook”中“getDafault”應該為“getDefault”。default寫錯了

16)110頁

“currentActivity-Thread”多了一個橫線“-”

17)124頁:

倒數第三行“會把asset目錄中的插件”中的“asset目錄”應該為“assets目錄”。缺個s

18)

292頁:“它有一個getsSring函數”中的“getsSring”應該為“getString”

19)

319頁:“在Android Studio中建立一個過程”中的“過程”修改為“工程”。

 20)

320頁:第2行:“同時在自定義的Class-Loader中”中的“Class-Loader”修改為“ClassLoader”。

21)

320頁

第13行:“但是AndroidAndroid系統源碼中也有一些類”中的“AndroidAndroid”修改為“Android“

22)235頁

那麼就通過10.3.2介紹的proxyCreateService方法

10.3.2改為14.4.2

23)238頁

ServiceManager(省略了10.3.1介紹的proloadServices和10.3.2介紹的proxyCreateService)

10.3.1改為14.4.3

preloadServices 改為preLoadServices

24)P97

RefInvoke.setFieldObject(sPackageManager,”sPackageManager”,proxy);

修改為

RefInvoke.setFieldObject(currentActivityThread,”sPackageManager”,proxy);

25)P100

圖5-2中 Context/Contexztimpi  修改為Context/ContextImpl

26)P5

為張勇的DroidPlugin添加腳注:

https://github.com/Qihoo360/DroidPlugin

27)P194

B準備好資料,寫到A要求的記憶體位址上,A就可以直接使用這些資料了

改為

A準備好資料,寫到B要求的記憶體位址上,B就可以直接使用這些資料了

28)P196

在B1中

在A1中

29)230

設計一個ProxyServiceManager的例子,

設計一個ProxyServiceManager的單例

30)235

這時候,不能把插件Service1換成ProxyService

這時候,不能把插件MyService1換成ProxyService

31)P245

 在sendBroadcastReceiver的時候

在sendBroadcast的時候

32) P25

AMN通過getDefault方法,從ServiceManager中取得一個名為activity的對象

AMN通過getDefault方法,從ServiceManager中取得一個對象

33)P25

看到這裡,你會發現AMP的startActivity方法,和AIDL的Proxy方法,是一模一樣的

看到這裡,你會發現AMP扮演着AIDL中的Proxy的角色,我們在2.3節介紹過AIDL的Proxy類。

34) P42

删除以下兩行代碼

Intent intent = new Intent(this, MyService.class);

startService(intent);

35)P55,删除下面這2句話

在插件化程式設計中,我們反射ActivityThread擷取apk包的資訊,一般用于目前的宿主apk ,而不是插件apk。

ApplicationPackageManager實作了IPackageManager.Stub。

36) P181

dat改為data