private final String parseDefaultActivityName(){
return this.packageInfo.activities != null && this.packageInfo.activities.length>0 ? this.packageInfo.activities[0].name:"";
}
//Theme setTo //將other Theme 的相同的復(fù)制到this
// TypeArray Theme里面的各個(gè)屬性值
//自定義Theme Theme必須繼承于某個(gè)已經(jīng)存在的Theme
/************/
應(yīng)用Theme屬性的兩種方式
1.在AndroidManifest.xml文件在<application /> 或者<activity/> 節(jié)點(diǎn)設(shè)置android:theme屬性
2.直接在代碼中調(diào)用setTheme()設(shè)置該Activity的主題,必須在第一次調(diào)用setContentView()前調(diào)用
自定義主題::///
<style name="MyTheme" parent="@android:style/Theme" >
<item name="android:windowNoTitle">true</item>
<item name="android:windowFrame">@drawable/icon</item>
<item name="android:windowBackground">****</item>
</style> // 很像DuiLib
兩個(gè)簡(jiǎn)單的api制定界面風(fēng)格
requestFeature(); getWindow().setFlags();
動(dòng)態(tài)加載里面應(yīng)用主題的代碼其實(shí)也是模仿系統(tǒng)加載流程
//參加 系統(tǒng)generateLayout(DecorView decor)-->getWindowStyle()-->obtainStyledAttributes()-->getTheme()
@Override
public Resources.Theme getTheme(){
if(mTheme != null){
return mTheme;
}
if(mThemeResource == 0){
mThemeResource = com.android.internal.R.style.Theme;
}
initializeTheme();
return mTheme;
}
private void initializeTheme(){
final boolean first = mTheme ==null;
if(first){
mTheme = getResources().newTheme();
Resources.Theme theme = mBase.getTheme();
// 調(diào)用ContextImpl類的getTheme()并级,獲取默認(rèn)的Theme
if(theme!=null){
mTheme.setTo(theme);//將theme配置應(yīng)用到mTheme屬性中择吊??缓苛?TypeArray
}
}
onApplyThemeResource(mTheme,mThemeResource,first);
}
如果沒有手動(dòng)設(shè)置 mThemeResource,則選取系統(tǒng)中為我們提供的默認(rèn)Theme,
方法一:Activity中調(diào)用setTheme()方法邓深,該方法實(shí)現(xiàn)在ContextThemWrapper.java
public void setTheme(int resid){
mThemeResource = resid; //設(shè)置mThemeResource
initializeTheme();
}
方法二:在AndroidManifest文件中未桥,為Activity節(jié)點(diǎn)配置android:theme屬性.
當(dāng)通過startActivity()啟動(dòng)一個(gè)Activity時(shí),會(huì)調(diào)用setTheme()方法芥备。
文件路徑:frameworks\base\core\java\android\app\ActivityThread.java
//宿主有了.jar ,而插件編譯時(shí)候也需要.jar冬耿,打包時(shí)候去掉***.jar
//不然就加載了兩次了,報(bào)錯(cuò) //工程運(yùn)行不了 //考慮bulid.gradle是否一致
//插件開發(fā)的三種模式
// 1.depend_on_host 插件完全依賴宿主的模式萌壳,適合于能夠得到宿主源代碼的情況
// 2.depend_on_interface 插件依賴宿主提供的接口亦镶,適合能夠拿到宿主接口的情況
// 3.main 插件不依賴宿主模式
//dl-lib author http://blog.csdn.net/zcxwww/article/details/51297587
//插件完全依賴宿主的模式,適合于能夠能到宿主的源代碼的情況袱瓮。
//這種模式一般多用在公司內(nèi)部缤骨,插件可以訪問宿主的所有代碼,
//但是尺借,這樣插件和宿主的耦合比較高绊起,宿主一動(dòng),插件就必須動(dòng)燎斩,比較麻煩
插件apk的開發(fā)規(guī)范
//1.不能用this虱歪,因?yàn)閠his指的是當(dāng)前對(duì)象,在不安裝的情況下瘫里,this只是一個(gè)普通的activity對(duì)象
//2.使用that: that在apk安裝運(yùn)行時(shí)候指向this实蔽,不安裝運(yùn)行時(shí)候指向proxyActivity
//3.不能直接調(diào)用activity的成員方法,必須通過that去調(diào)用谨读,由于that的動(dòng)態(tài)分配特性局装,
//通過that去調(diào)用activity的成員方法在安裝后依然可以正常運(yùn)行
// 4.啟動(dòng)新activity的約束,啟動(dòng)外部activity不受限制,啟動(dòng)apk內(nèi)部的activity有限制铐尚,由于
//apk中的activity沒注冊(cè)拨脉,所以不支持隱式調(diào)用,必須通過startActivityByProxy或者
//startActivityForResultByProxy,不支持launchMode
// 5.目前暫不支持Service宣增,BroadcastReceiver等需要注冊(cè)才能使用的組件
//dl最開始采取反射去管理activity的生命周期玫膀,bug:反射代碼寫起來復(fù)雜,過多使用反射有一定的性能開銷
//采取了接口機(jī)制爹脾,將activity的大部分生命周期方法提取出來作為一個(gè)接口(DLPlugin)帖旨,之后通過代理activity
//(DLProxyActivity)去調(diào)用插件activity實(shí)現(xiàn)的生命周期方法,這樣就完成了插件activity的生命周期管理
//而且沒有采取反射灵妨,當(dāng)我們想增加一個(gè)新的生命周期方法時(shí)候解阅,只需要在接口中聲明一下同時(shí)在代理activity中
//實(shí)現(xiàn)即可
//DLProxyActivity 在宿主apk中是注冊(cè)了的,所以可以直接通過Intent啟動(dòng)泌霍,DLProxyActivity實(shí)際是一個(gè)
//軀殼货抄,在自己的生命周期里面調(diào)用插件activity對(duì)應(yīng)的生命周期函數(shù),
//DLProxyImpl 負(fù)責(zé)解析插件apk的資源朱转,classLoader蟹地,反射加載插件activity,將實(shí)例傳遞給ProxyActivity
//所以ProxyActivity可以在自己的生命周期函數(shù)中調(diào)用activity對(duì)應(yīng)的函數(shù)
優(yōu)柔寡斷只會(huì)帶來痛苦藤为,10秒鐘想好 /// 你之前已經(jīng)寫過一次了