• Android插件化开发之解决OpenAtlas组件在宿主的注冊问题


    OpenAtlas有一个问题,就是四大组件必须在Manifest文件里进行注冊,那么就必定带来一个问题,插件中的组件都要反复在宿主中注冊。像Service,ContentProvider等组件眼下没有什么好的解决方法。仅仅能在宿主中注冊。

    可是像Activity,显然是有解决方法的。就是使用Fragment取代Activity,Activity仅仅是作为一个放Fragment的容器,那么不仅在插件中不用再清单文件里注冊,就连宿主的注冊问题也一并攻克了。那么,解决方式呢,没错,就是之前写的一篇博文Android使用Fragment打造万能页面切换框架

    在阅读下文前,请务必先阅读该文章。

    可是使用该页面切换框架也带来一个问题。就是该框架中是通过反射调用Fragment,可是在宿主中假设直接使用反射,会报java.lang.ClassNotFoundException的错误。我们必须使用OpenAtlas提供的插件的ClassLoader来载入,为了支持OpenAtlas。我对该框架进行了改动,使其支持OpenAtlas

    在配置类CoreConfig中添加两个变量。控制是否启用OpenAtlas,以及用于设置和获得ClassLoader。并提供静态的getter和setter方法

    /**
     * Atlas支持 start
     */
    private static boolean isOpenAtlas=false;
    private static ClassLoader mBundleClassLoader =null;
    
    public static boolean isOpenAtlas() {
        return isOpenAtlas;
    }
    
    public static void setIsOpenAtlas(boolean isOpenAtlasFlag) {
        isOpenAtlas = isOpenAtlasFlag;
    }
    
    public static ClassLoader getBundleClassLoader() {
        return mBundleClassLoader;
    }
    
    public static void setBundleClassLoader(ClassLoader classLoader) {
        mBundleClassLoader = classLoader;
    }
    /**
     * Atlas支持 end
     */

    改动原来的核心函数。推断CoreConfig中的布尔变量。是否启用了OpenAtlas,默认是不启用的。假设启用了,则通过getBundleClassLoader函数获得ClassLoader,可是前提是你调用了setBundleClassLoader函数设置了ClassLoader,返回的才不是空

    /**
     * Atlas的支持 start
     */
    if (CoreConfig.isOpenAtlas()){
        ClassLoader bundleClassLoader = CoreConfig.getBundleClassLoader();
        if(bundleClassLoader==null){
            Log.d(TAG, "OpenAtlas bundle ClassLoader is null!");
            return null;
        }
        fragment = (BaseFragment) CoreConfig.getBundleClassLoader().loadClass(corePage.getClazz()).newInstance();
    }else{
        fragment = (BaseFragment) Class.forName(corePage.getClazz()).newInstance();
    }
    /**
     * Atlas的支持 end
     */

    之后在宿主中调用的时候,记得开启OpenAtlas的支持。并设置ClassLoader,而ClassLoader的获取是通过Atlas的成员函数getBundleClassLoader()来获取,该函数须要传递一个參数,该參数就是相应插件的包名,也就是之前生成的插件信息列表的json中的pkgName

    之后的开发就是正常程序的开发了。可是注意一点,就是宿主的入口Activity必须继承页面切换框架中的BaseActivity,而且不须要调用setContentView进行页面设置。直接使用openPage函数打开Fragment就可以。插件中的Fragment必须继承页面切换框架中的BaseFragment,而且记得在宿主Application中调用 CoreConfig.init(this);进行该框架的初始化。

    然后在宿主中调用。记得设置ClassLoader和开启OpenAtlas的支持。Fragment的配置文件page.json 不须要拷到宿主中

    CoreConfig.setIsOpenAtlas(true);
    ClassLoader bundleClassLoader = Atlas.getInstance().getBundleClassLoader("com.lizhangqu.fragment");
    CoreConfig.setBundleClassLoader(bundleClassLoader);
    openPage("test", null, CoreAnim.none);

    而插件中,不应该将该框架打包进去,仅仅是编译的时候提供,详细的适配工作见上一篇文章Android插件化开发之Atlas插件适配

    最后,提供一个例子源代码

    http://download.csdn.net/detail/sbsujjbcy/9031679

  • 相关阅读:
    【转载】ARM与单片机的区别
    关于头文件定义的一点思考
    关于*** WARNING L15: MULTIPLE CALL TO SEGMENT
    【转】单片机中volatile定义的作用详解
    关于单片机位数的思考(8位、16位、32位)
    memcpy函数
    ubuntu下打开windows里的txt文件乱码解决
    linux source filename
    linux环境设置export
    pdf转word工具
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7390983.html
Copyright © 2020-2023  润新知