美文网首页
2018-01-13

2018-01-13

作者: zeromemcpy | 来源:发表于2018-02-08 22:22 被阅读0次

    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秒钟想好 /// 你之前已经写过一次了

    相关文章

      网友评论

          本文标题:2018-01-13

          本文链接:https://www.haomeiwen.com/subject/nqyxtftx.html