private final String parseDefaultActivityName(){
return this.packageInfo.activities != null && this.packageInfo.activities.length>0 ? this.packageInfo.activities[0].name:"";
}
//Theme setTo //将other Theme 的相同的复制到this
// TypeArray Theme里面的各个属性值
//自定义Theme Theme必须继承于某个已经存在的Theme
/************/
应用Theme属性的两种方式
1.在AndroidManifest.xml文件在<application /> 或者<activity/> 节点设置android:theme属性
2.直接在代码中调用setTheme()设置该Activity的主题,必须在第一次调用setContentView()前调用
自定义主题::///
<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
两个简单的api制定界面风格
requestFeature(); getWindow().setFlags();
动态加载里面应用主题的代码其实也是模仿系统加载流程
//参加 系统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();
// 调用ContextImpl类的getTheme(),获取默认的Theme
if(theme!=null){
mTheme.setTo(theme);//将theme配置应用到mTheme属性中???TypeArray
}
}
onApplyThemeResource(mTheme,mThemeResource,first);
}
如果没有手动设置 mThemeResource,则选取系统中为我们提供的默认Theme,
方法一:Activity中调用setTheme()方法,该方法实现在ContextThemWrapper.java
public void setTheme(int resid){
mThemeResource = resid; //设置mThemeResource
initializeTheme();
}
方法二:在AndroidManifest文件中,为Activity节点配置android:theme属性.
当通过startActivity()启动一个Activity时,会调用setTheme()方法。
文件路径:frameworks\base\core\java\android\app\ActivityThread.java
//宿主有了.jar ,而插件编译时候也需要.jar,打包时候去掉***.jar
//不然就加载了两次了,报错 //工程运行不了 //考虑bulid.gradle是否一致
//插件开发的三种模式
// 1.depend_on_host 插件完全依赖宿主的模式,适合于能够得到宿主源代码的情况
// 2.depend_on_interface 插件依赖宿主提供的接口,适合能够拿到宿主接口的情况
// 3.main 插件不依赖宿主模式
//dl-lib author http://blog.csdn.net/zcxwww/article/details/51297587
//插件完全依赖宿主的模式,适合于能够能到宿主的源代码的情况。
//这种模式一般多用在公司内部,插件可以访问宿主的所有代码,
//但是,这样插件和宿主的耦合比较高,宿主一动,插件就必须动,比较麻烦
插件apk的开发规范
//1.不能用this,因为this指的是当前对象,在不安装的情况下,this只是一个普通的activity对象
//2.使用that: that在apk安装运行时候指向this,不安装运行时候指向proxyActivity
//3.不能直接调用activity的成员方法,必须通过that去调用,由于that的动态分配特性,
//通过that去调用activity的成员方法在安装后依然可以正常运行
// 4.启动新activity的约束,启动外部activity不受限制,启动apk内部的activity有限制,由于
//apk中的activity没注册,所以不支持隐式调用,必须通过startActivityByProxy或者
//startActivityForResultByProxy,不支持launchMode
// 5.目前暂不支持Service,BroadcastReceiver等需要注册才能使用的组件
//dl最开始采取反射去管理activity的生命周期,bug:反射代码写起来复杂,过多使用反射有一定的性能开销
//采取了接口机制,将activity的大部分生命周期方法提取出来作为一个接口(DLPlugin),之后通过代理activity
//(DLProxyActivity)去调用插件activity实现的生命周期方法,这样就完成了插件activity的生命周期管理
//而且没有采取反射,当我们想增加一个新的生命周期方法时候,只需要在接口中声明一下同时在代理activity中
//实现即可
//DLProxyActivity 在宿主apk中是注册了的,所以可以直接通过Intent启动,DLProxyActivity实际是一个
//躯壳,在自己的生命周期里面调用插件activity对应的生命周期函数,
//DLProxyImpl 负责解析插件apk的资源,classLoader,反射加载插件activity,将实例传递给ProxyActivity
//所以ProxyActivity可以在自己的生命周期函数中调用activity对应的函数
优柔寡断只会带来痛苦,10秒钟想好 /// 你之前已经写过一次了
网友评论