组件之间AndroidManifest合并问题

由于 Android 项目在 Eclipse 和 AndroidStudio开发时 AndroidManifest.xml 文件的位置是不一样的,我们需要在build.gradle 中指定下 AndroidManifest.xml 的位置,AndroidStudio 才能读取到 AndroidManifest.xml,这样解决办法也就有了,我们可以为组件开发模式下的业务组件再创建一个 AndroidManifest.xml,然后根据isModule指定AndroidManifest.xml的文件路径,让业务组件在集成模式和组件模式下使用不同的AndroidManifest.xml,这样表单冲突的问题就可以规避了。 ————————————————     2,如果组件模式下, 则需要重新设置 AndroidManifest.xml 文件,里面配置新的Application路径。比如Login组件单独运行 AndroidManifest 清单文件  
if (!isModule.toBoolean()) {    implementation project(':b-main')    implementation project(':b-login')    implementation project(':b-setting')}
  解决的问题 1.Application 需要看下applicatin的初始化 有自己的application。
代理的application的作用
 
LoginApplicationDelegate
/**
 * login组件全局应用配置 * Created by chenran3 on 2017/12/6. */@EFModuleAnnotation(moduleName = "b-login",delegateName = "com.cryallen.applogin.LoginApplicationDelegate")public class LoginApplicationDelegate implements IApplicationDelegate {    private static final String TAG = "LoginApplicationDelegate";    @Override    public void onCreate() {        EFLog.d(TAG, "*------------------onCreate()---------------->");    }    @Override    public void enterBackground() {        EFLog.d(TAG, "*------------------enterBackground()---------------->");    }    @Override    public void enterForeground() {        EFLog.d(TAG, "*------------------enterForeground()---------------->");    }    @Override    public void receiveRemoteNotification(Map, String> message) {        EFLog.d(TAG, "receiveRemoteNotification msg = " + message);    }    @Override    public void onTerminate() {        EFLog.d(TAG, "*------------------onTerminate()---------------->");    }    @Override    public void onConfigurationChanged(Configuration configuration) {        EFLog.d(TAG, "*------------------onConfigurationChanged()---------------->");    }    @Override    public void onLowMemory() {        EFLog.d(TAG, "*------------------onLowMemory()---------------->");    }    @Override    public void onTrimMemory(int var1) {        EFLog.d(TAG, "*------------------onTrimMemory()---------------->");    }}
2.清单文件多个,解决app和单独module的配置   1)组件模式和集成模式的转换   Android Studio中的Module主要有两种属性,分别为:   1、application属性,可以独立运行的Android程序,也就是我们的APP;   apply plugin: ‘com.android.application’ 1 2、library属性,不可以独立运行,一般是Android程序依赖的库文件;   apply plugin: ‘com.android.library’ ————————————————
sourceSets {    main {        if (isModule.toBoolean()) {            manifest.srcFile 'src/main/module/AndroidManifest.xml'        } else {            manifest.srcFile 'src/main/AndroidManifest.xml'            //集成开发模式下排除debug文件夹中的所有Java文件            java {                exclude 'debug/**'            }        }    }}
3.切换app和切换组件的变量???? 目录中生成一个文件 gradle.properties,我们将使用这个文件的一个重要属性:在Android项目中的任何一个build.gradle文件中都可以把gradle.properties中的常量读取出来;那么我们在上面提到解决办法就有了实际行动的方法,首先我们在gradle.properties中定义一个常量值 isModule(是否是组件开发模式,true为是,false为否):   # 每次更改“isModule”的值后,需要点击 "Sync Project" 按钮 isModule=false ——————————————— 实现原理: asset目录下的json配置
/** * * 加载模块信息 */public void loadModule() {    Context context = getApplicationContext();    appDelegateList = new ArrayList();    delegateNameList = new ArrayList();    try {        AssetManager assetManager = context.getResources().getAssets();        String[] fileList = assetManager.list("");        int fileLength = fileList.length;        for(int i = 0; i < fileLength; ++i) {            String fileName = fileList[i];            if(fileName.startsWith(MODULE_PREFIX)) {                //解析json配置文件                ModuleInfo moduleInfo = parse(assetManager.open(fileName));                if(moduleInfo == null){                    continue;                }                moduleInfoList.add(moduleInfo);                delegateNameList.add(moduleInfo.getPackageName());                EFLog.d(TAG, "load Module: " + moduleInfo.getModuleName());            }        }        appDelegateList.addAll(ModuleClassUtils.getObjectsWithClassName(context, IApplicationDelegate.class, delegateNameList));    } catch (Exception e) {        e.printStackTrace();    }}
uploading.4e448015.gif转存失败重新上传取消   登入的解决办法: 业务组件自己的 Application 可以在组件开发模式下初始化一些数据,例如在组件开发模式下,A组件没有登录页面也没法登录,因此就无法获取到 Token,这样请求网络就无法成功,因此我们需要在A组件这个 APP 启动后就应该已经登录了,这时候组件自己的 Application 类就有了用武之地,我们在组件的 Application的 onCreate 方法中模拟一个登陆接口,在登陆成功后将数据保存到本地,这样就可以处理A组件中的数据业务了;另外我们也可以在组件Application中初始化一些第三方库。 ———————————————— 4)library依赖问题   在介绍这一节的时候,先说一个问题,在组件化工程模型图中,多媒体组件和Common组件都依赖了日志组件,而A业务组件有同时依赖了多媒体组件和Common组件,这时候就会有人问,你这样搞岂不是日志组件要被重复依赖了,而且Common组件也被每一个业务组件依赖了,这样不出问题吗?   其实大家完全没有必要担心这个问题,如果真有重复依赖的问题,在你编译打包的时候就会报错,如果你还是不相信的话可以反编译下最后打包出来的APP,看看里面的代码你就知道了。组件只是我们在代码开发阶段中为了方便叫的一个术语,在组件被打包进APP的时候是没有这个概念的,这些组件最后都会被打包成arr包,然后被app壳工程所依赖,在构建APP的过程中Gradle会自动将重复的arr包排除,APP中也就不会存在相同的代码了;   但是虽然组件是不会重复了,但是我们还是要考虑另一个情况,我们在build.gradle中compile的第三方库,例如AndroidSupport库经常会被一些开源的控件所依赖,而我们自己一定也会compile AndroidSupport库 ,这就会造成第三方包和我们自己的包存在重复加载,解决办法就是找出那个多出来的库,并将多出来的库给排除掉,而且Gradle也是支持这样做的,分别有两种方式:根据组件名排除或者根据包名排除,下面以排除support-v4库为例:   dependencies {     compile fileTree(dir: 'libs', include: ['*.jar'])     compile("com.jude:easyrecyclerview:$rootProject.easyRecyclerVersion") {         exclude module: 'support-v4'//根据组件名排除         exclude group: 'android.support.v4'//根据包名排除     } }   library重复依赖的问题算是都解决了,但是我们在开发项目的时候会依赖很多开源库,而这些库每个组件都需要用到,要是每个组件都去依赖一遍也是很麻烦的,尤其是给这些库升级的时候,为了方便我们统一管理第三方库,我们将给给整个工程提供统一的依赖第三方库的入口,前面介绍的Common库的作用之一就是统一依赖开源库,因为其他业务组件都依赖了Common库,所以这些业务组件也就间接依赖了Common所依赖的开源库。   dependencies {     compile fileTree(dir: 'libs', include: ['*.jar'])     //Android Support     compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"     compile "com.android.support:design:$rootProject.supportLibraryVersion"     compile "com.android.support:percent:$rootProject.supportLibraryVersion"     //网络请求相关     compile "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion"     compile "com.squareup.retrofit2:retrofit-mock:$rootProject.retrofitVersion"     compile "com.github.franmontiel:PersistentCookieJar:$rootProject.cookieVersion"     //稳定的     compile "com.github.bumptech.glide:glide:$rootProject.glideVersion"     compile "com.orhanobut:logger:$rootProject.loggerVersion"     compile "org.greenrobot:eventbus:$rootProject.eventbusVersion"     compile "com.google.code.gson:gson:$rootProject.gsonVersion"     compile "com.github.chrisbanes:PhotoView:$rootProject.photoViewVersion"       compile "com.jude:easyrecyclerview:$rootProject.easyRecyclerVersion"     compile "com.github.GrenderG:Toasty:$rootProject.toastyVersion"       //router     compile "com.github.mzule.activityrouter:activityrouter:$rootProject.routerVersion" } ———————————————— APT: 这一步我们需要先了解 APT这个概念,APT(Annotation Processing Tool)是一种处理注解的工具, 它对源代码文件进行检测找出其中的Annotation,使用Annotation进行额外的处理。 Annotation处理器在处理Annotation时可以根据源文件中的Annotation生成额外的源文件和其它的文件(文件具体内容由Annotation处理器的编写者决定),APT还会编译生成的源文件和原来的源文件,将它们一起生成class文件。在这里我们将在每一个业务组件的 build.gradle 都引入ActivityRouter 的 Annotation处理器,我们将会在声明组件和Url的时候使用,annotationProcessor是Android官方提供的Annotation处理器插件,代码如下:     dependencies {     compile fileTree(dir: 'libs', include: ['*.jar'])     annotationProcessor "com.github.mzule.activityrouter:compiler:$rootProject.annotationProcessor" } ———————————————— 4、组件化项目的工程类型   在组件化工程模型中主要有:app壳工程、业务组件和功能组件3种类型,而业务组件中的Main组件和功能组件中的Common组件比较特殊,下面将分别介绍。   1)app壳工程   app壳工程是从名称来解释就是一个空壳工程,没有任何的业务代码,也不能有Activity,但它又必须被单独划分成一个组件,而不能融合到其他组件中,是因为它有如下几点重要功能:   1、app壳工程中声明了我们Android应用的 Application,这个 Application 必须继承自 Common组件中的 BaseApplication(如果你无需实现自己的Application可以直接在表单声明BaseApplication),因为只有这样,在打包应用后才能让BaseApplication中的Context生效,当然你还可以在这个 Application中初始化我们工程中使用到的库文件,还可以在这里解决Android引用方法数不能超过 65535 的限制,对崩溃事件的捕获和发送也可以在这里声明。   2、app壳工程的 AndroidManifest.xml 是我Android应用的根表单,应用的名称、图标以及是否支持备份等等属性都是在这份表单中配置的,其他组件中的表单最终在集成开发模式下都被合并到这份 AndroidManifest.xml 中。   3、app壳工程的 build.gradle 是比较特殊的,app壳不管是在集成开发模式还是组件开发模式,它的属性始终都是:com.android.application,因为最终其他的组件都要被app壳工程所依赖,被打包进app壳工程中,这一点从组件化工程模型图中就能体现出来,所以app壳工程是不需要单独调试单独开发的。另外Android应用的打包签名,以及buildTypes和defaultConfig都需要在这里配置,而它的dependencies则需要根据isModule的值分别依赖不同的组件,在组件开发模式下app壳工程只需要依赖Common组件,或者为了防止报错也可以根据实际情况依赖其他功能组件,而在集成模式下app壳工程必须依赖所有在应用Application中声明的业务组件,并且不需要再依赖任何功能组件。 ———————————————— 2)功能组件和Common组件(公共依赖的库)   功能组件是为了支撑业务组件的某些功能而独立划分出来的组件,功能实质上跟项目中引入的第三方库是一样的,功能组件的特征如下:   1、功能组件的 AndroidManifest.xml 是一张空表,这张表中只有功能组件的包名;   2、功能组件不管是在集成开发模式下还是组件开发模式下属性始终是: com.android.library,所以功能组件是不需要读取 gradle.properties 中的 isModule 值的;另外功能组件的 build.gradle 也无需设置 buildTypes ,只需要 dependencies 这个功能组件需要的jar包和开源库。     manifest.xml重复权限问题
> Task :module_bracelet:processDebugManifest /Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml:50:5-69 Warning:Element uses-permission#android.permission.FLASHLIGHT at AndroidManifest.xml:50:5-69 duplicated with element declared at AndroidManifest.xml:48:5-69/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml:23:9-27:56 Warning:activity#[email protected]:name was tagged at AndroidManifest.xml:23 to replace other declarations but no other declaration present/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml:23:9-27:56 Warning:activity#[email protected]:configChanges was tagged at AndroidManifest.xml:23 to replace other declarations but no other declaration present/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml:23:9-27:56 Warning:activity#[email protected]:theme was tagged at AndroidManifest.xml:23 to replace other declarations but no other declaration present/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml:29:9-39:20 Warning:provider#[email protected]:name was tagged at AndroidManifest.xml:29 to replace other declarations but no other declaration present/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml:29:9-39:20 Warning:provider#[email protected]:authorities was tagged at AndroidManifest.xml:29 to replace other declarations but no other declaration present/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml:29:9-39:20 Warning:provider#[email protected]:exported was tagged at AndroidManifest.xml:29 to replace other declarations but no other declaration present/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml:29:9-39:20 Warning:provider#[email protected]:grantUriPermissions was tagged at AndroidManifest.xml:29 to replace other declarations but no other declaration present/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml Warning:meta-data#[email protected]:name was tagged at AndroidManifest.xml:0 to replace other declarations but no other declaration present/Users/mac/android-bracelet/bracelet/module_bracelet/src/main/module/AndroidManifest.xml Warning:meta-data#[email protected]:resource was tagged at AndroidManifest.xml:0 to replace other declarations but no other declaration present

Android 中使用 fragment 提示error inflating class fragment

需要添加引用
    android:id="@+id/frag_bracelet_debug"    android:layout_width="match_parent"    android:name="bracelet.yuedong.com.module_bracelet.fragment.BraceletFragment"    android:layout_height="match_parent">

需要解决provider的名字重复的问题 app和module切换的时候,R文件总是不一样,切换,每次自己弄?     组件生命周期的管理: 看到了你的frame里的代码实现 明白了,目前管理组件生命周期貌似只有这种方式,通过获取到绝对类名,反射调用。   ———————————————   我自己的参考: 简单入门:非常好的入门 https://blog.csdn.net/guiying712/article/details/55213884 https://www.jianshu.com/p/1c5afe686d75     非常不错的 https://www.jianshu.com/p/ba32488f9555   完美方案:demo不错 https://www.jianshu.com/p/1b1d77f58e84   弘扬的demo https://www.jianshu.com/p/00746e6fb48a    

 

更多相关文章

  1. ionic3文件目录介绍
  2. [Android]使用化名(alias)功能防止相同资源的重复
  3. android从未安装的apk文件里获取信息(包信息,资源信息)
  4. 提高开发效率-使用Android Studio Template快速生成模板文件
  5. Android API开发之OpenGL开发之Android OpenGL显示STL模型文件
  6. Android界面组件基本用法
  7. android studio R文件找不到

随机推荐

  1. Android(安卓)镜像地址[持续更新中]
  2. android 图片透明
  3. Android(安卓)工具
  4. Android(安卓)自动化测试―robotium(五)Spi
  5. Android的进程与线程模型
  6. Android 性能优化典范(六)
  7. SpannableStringBuilder的使用
  8. 蓝牙协议栈调试记录
  9. android各种组件的监听器
  10. Android -- 跨应用绑定service(AIDL)