从零开始Android组件化改造(四) - 模块配置的统一管理

我的Github:https://github.com/BzCoder
本文基于MVPArms进行分析:https://github.com/JessYanCoding/MVPArms
欢迎各位留言讨论

前段时间赶项目,耽误了一些时间,没有及时更新文章。
在组件化开发中,每个模块都可能会拥有独有的配置,在打包时,又有全局统一管理的配置。我们就要对这里最终进行整合。我们分为四个点来讨论。

  • 收集配置
  • 配置Applicaition
  • 配置Activity
  • 配置Fragment

跨模块收集配置

因为组件化改造后,配置都分散在各个模块中,我们需要借助手段将它们再集中起来,此时我们可以借用Manifest,因为在整体运行阶段,系统会将Manifest统一合并形成一份Manifest。利用这个特性,我们可以通过meta-data的方式将散落在各个模块集中到一起。下方代码可以帮助收集配置,以下代码分了两个步骤,首先将Manifest中meta-data的value为ConfigModule取出,然后通过它的Key去反射实例化ConfigModule配置文件,最后返回List文件,这样就完成了各个模块信息收集。ConfigModule中包含了我们对于Applicaition,Activity,Fragment的配置管理方法。

public final class ManifestParser {
    private static final String MODULE_VALUE = "ConfigModule";
    private final Context context;

    public ManifestParser(Context context) {
        this.context = context;
    }

    public List parse() {
        List modules = new ArrayList();
        try {
            ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
                    context.getPackageName(), PackageManager.GET_META_DATA);
            if (appInfo.metaData != null) {
                for (String key : appInfo.metaData.keySet()) {
                    if (MODULE_VALUE.equals(appInfo.metaData.get(key))) {
                        modules.add(parseModule(key));
                    }
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException("Unable to find metadata to parse ConfigModule", e);
        }

        return modules;
    }

    private static ConfigModule parseModule(String className) {
        Class clazz;
        try {
            clazz = Class.forName(className);
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("Unable to find ConfigModule implementation", e);
        }

        Object module;
        try {
            module = clazz.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException("Unable to instantiate ConfigModule implementation for " + clazz, e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Unable to instantiate ConfigModule implementation for " + clazz, e);
        }

        if (!(module instanceof ConfigModule)) {
            throw new RuntimeException("Expected instanceof ConfigModule, but found: " + module);
        }
        return (ConfigModule) module;
    }
}

在ConfigModule接口中包含了四个方法,参数为context , List<>,这方便在各个模块中注入配置。

public interface ConfigModule {
    void injectAppLifecycle(@NonNull Context context, @NonNull List lifecycles);
    void injectActivityLifecycle(@NonNull Context context, @NonNull List lifecycles);
    void injectFragmentLifecycle(@NonNull Context context, @NonNull List lifecycles);
}

Application

因为一个App只有一个Application,但是由于我们是组件化开发,我们并不能在每个模块当中直接对Application进行操作,但是上面的代码已经帮我们解决掉了最关键的收集配置问题,所以接下来我们使用代理模式就可以解决各个模块Application的拼装问题。我们模仿LifeCycle的写法。

public interface AppLifecycles {
    void attachBaseContext(@NonNull Context base);

    void onCreate(@NonNull Application application);

    void onTerminate(@NonNull Application application);

   void onTrimMemory(@NonNull Application application);

   void onLowMemory(@NonNull Application application,int level);
}

我们新建类AppDelegate来实现AppLifecycles
在Application中我们只需要在相应的生命周期方法中调用即可。其中AppLifecycles 为我们从上文中List取得。

 for (AppLifecycles lifecycle : mAppLifecycles) {
            lifecycle.attachBaseContext(base);
        }

配置Activity

在Api14后,Application中加入了ActivityLifecycleCallbacks,这里我们要区分它和LifeCycle的不同,ActivityLifecycleCallbacks是在Applicaiton中对于所有Activity统一管理,更像是BaseActivity的概念,LifeCycle是Acitivity内部组件的生命周期监听。ActivityLifecycleCallbacks我们经常用来:嵌入第三方SDK在Activity中的启动,控制某个Activity被初始化的数量,如各种详情页详情页,判断应用是否在前台状态等。所以Acitivity的管理,我们可以直接拿来即用。我们只要把List取得的List通过Application.registerActivityLifecycleCallbacks(lifecycle)注册到基Application即可。

配置Fragment

Fragment依附于Activity,所以对于Fragment的配置我们需要在Activity的onCreate中进行。在FragmentActivity中,系统给我们提供了registerFragmentLifecycleCallbacks(@NonNull FragmentManager.FragmentLifecycleCallbacks var1, boolean var2);方法,其中布尔值True代表递归注册,就是当Fragment嵌套Fragment的情况。于是我们在配置Fragment时,只需要在基类中的ActivityLifecycleCallback的onActivityCreated中调用registerFragmentLifecycleCallbacks即可,当然会有同学问此处的List如何取得,这个就需要我们的Dagger2来实现了。这个我们以后再讨论。

以上就完成了在组件化开发中对于不同模块的Applicaition,Activity,Fragment配置的统一管理。

你可能感兴趣的:(从零开始Android组件化改造(四) - 模块配置的统一管理)