zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    -bash: fork: Cannot allocate memory 问题的处理
    Docker top 命令
    docker常见问题修复方法
    The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
    What's the difference between encoding and charset?
    hexcode of é î Latin-1 Supplement
    炉石Advanced rulebook
    炉石bug反馈
    Sidecar pattern
    SQL JOIN
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7390983.html
Copyright © 2011-2022 走看看