天天看點

Android插件化開發之Hook StartActivity方法(1)

第一步、先爆項目demo照片,代碼不多,不要怕

Android插件化開發之Hook StartActivity方法(1)

第二步、應該知道Java反射相關知識

如果不知道或者忘記的小夥伴請猛搓這裡,Android插件化開發基礎之Java反射機制研究  

http://blog.csdn.net/u011068702/article/details/49863931

第三步、應該知道Java靜态代理知識

如果不知道或者忘記的小夥伴請猛搓這裡,Android插件化開發基礎之靜态代理模式  

http://blog.csdn.net/u011068702/article/details/51765578

第四部、應該知道Java動态代理知識

如果不知道或者忘記的小夥伴請猛搓這裡,Android插件化開發基礎之Java動态代理(proxy)機制的簡單例子  

http://blog.csdn.net/u011068702/article/details/53185210

上面隻有代碼的解釋,如果不是很清楚的小夥伴可以再去到網上搜一搜相關知識。

第五步、應該知道Android裡面的ActivityThread類和Instrumentation類

如果不知道或者忘記的小夥伴請猛搓這裡,Android插件化開發之AMS與應用程式(用戶端ActivityThread、Instrumentation、Activity)通信模型分析  

http://blog.csdn.net/u011068702/article/details/53207039

希望認真看,知道ActivityThread和Instrumentation是幹嘛的,友善下面分析。

第六步、了解hook,并且分析源碼

如果我們自己建立代理對象,然後把原始對象替換為我們的代理對象,那麼就可以在這個代理對象為所欲為了;修改參數,替換傳回值,我們稱之為Hook。

接下來我們來實作Hook掉startActivity這個方法,當每次調用這個方法的時候來做我們需要做的事情,我這裡之列印了一些資訊,讀者可以更具自己的需求來修改,

我們的目的是攔截startActivity方法,有點類是spring 裡面AOP的思想。

1、hook一般在哪裡hook?

首先分析我們需要hook哪些對象,也就是說我們要hook的地方,什麼樣的對象比較好Hook呢?一般是容易找到和不容易改變的對象,這思路就來了,不改變一般在我們類的裡面單例對象是唯一對象,靜态變量我們一般加上final static 修飾,有了final就不會改變,不變模式裡面比如String類,裡面就很多final,我們更加這些找到hook的地方。

2、我們hook startActivity,分析startActivity到底是怎麼實作的 

我們每次Context.startActivity,由于Context的實作實際上是ContextImpl來實作的,;我們看ConetxtImpl類的startActivity方法:

@Override
public void startActivity(Intent intent, Bundle options) {
    warnIfCallingFromSystemProcess();
    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
        throw new AndroidRuntimeException(
                "Calling startActivity() from outside of an Activity "
                + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                + " Is this really what you want?");
    }
    mMainThread.getInstrumentation().execStartActivity(
        getOuterContext(), mMainThread.getApplicationThread(), null,
        (Activity)null, intent, -1, options);
}      

我們可以看到startActivity方法最後還是通過Instrumentation對象來執行execStartActivity來實作的,如果你認真看了《Android插件化開發之AMS與應用程式(用戶端ActivityThread、Instrumentation、Activity)通信模型分析 》上面這篇部落格,我們知道ActivityThread就是主線程,也就是我們常說的UI線程,可以去更新UI,一個程序隻有一個主線程,我們可以在這裡hook.

我們需要Hook掉我們的主線程對象,把主線程對象裡面的mInstrumentation給替換成我們修改過的代理對象;要替換主線程對象裡面的字段

繼續閱讀