组件化开发实现

      2017年的时候就想学习学习组件化开发了。当时也看了一些相关文章,只是没有动手实现试试。直到这段时间才静下心来学习,我将自己学习到的东西记录下来,希望对各位感兴趣的同学有所帮助。在学习的过程中,我有一种感觉:学习组件化开发不难,难的是功能的分类。

      1.组件化是什么?

      组件化开发结构图 

       普通开发结构图(按自己的理解画的)

         

      之前我们开发的时候,在主App中实现所有的四大组件。网络框架,图片框架,第三方sdk等等一些工具类都放在主App中。这样的后果就是在后期的维护非常困难,不需要的图片代码文件,xml文件等都很难找出,耦合度较高,修改一处地方可能要修改很多处地方。

     组件化开发在多人开发中优势非常明显。将网络框架,图片加载框架,第三方sdk,BaseXX等工具放在一个common Module中。根据功能分类成Module分别依赖common  Module。最后主app 依赖各个功能Module。在这种开发模式下,每个开发者只需要调试自己的Module。在后期维护的时候也容易找到相应的功能点。

    

    下面我们代码实现:

    1.区分使用com.android.library  和 com.android.application。

     一般情况下,Module使用的是com.android.library 表示自己是一个library。而主项目使用的是com.android.application 表示自己是一个application。

     1.1 为了方便Module 和 App模式间运行的切换,我们需要一个类似开关的东西。在gradle.properties文件上定义一个变量。isModule  为了方便在Module 和 app切换。


          

     1.2 还需要在每个Module中写入

if(isModule.toBoolean()){
    apply plugin: 'com.android.application'
}else{
    apply plugin: 'com.android.library'
} 

     需要注意的是  gradle.properties 文件输出的值是String类型的,需要转换成Boolean类型才能做判断。

    我们还需要在主app的build.gradle中添加:

     当isModule为false时,主项目依赖Module,否则就依赖  librarycommon

     注意!注意!注意!  每次isModule 切换时 必须sync project (点击 


   2.区分使用AndroidMenifest.xml文件

     当我们需要将一个Module当成是一个app做运行的时候,除了上一步使用com.android.application外,还得需要AndroidMenifest.xml文件。但是在各个Module组合在一起的时候,就出现了一个问题: 主app有一个AndroidMenifest.xml文件,各个Module也有一个AndroidMenifest.xml文件,这种情况下就会出现冲突问题。因为主app中AndroidMenifest.xml定义的属性跟其他Module中AndroidMenifest.xml定义的属性发生了冲突。那么该怎么解决呢?这里提供了一个方法:
      我们在每个Module的main目录下创建debug目录和release目录。这两个目录都存放着AndroidMenifest.xml文件。当isModule为true时,使用debug目录下的AndroidMenifest.xml文件,当isModule为false时,使用的是release目录下的AndroidMenifest.xml文件。

    

在每个Module的build.gradle中写着:  
      sourceSets {
        main {
            if (isModule.toBoolean()) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
                java {
                    include 'debug/**'
                }
            }
        }
    }

需要注意的是Module中添加的Android四大组件都必须在debug和release目录的AndroidMenifest.xml上注册。另外,debug目录下AndroidMenifest.xml是长这样子的:


<application
        android:name="debug.LibraryAApplication"
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true">

        <activity android:name=".LibraryOneActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

     relearse目录下 AndroidMenifest.xml是长这样子的:

<application
        android:label="@string/app_name"
        >
        <activity android:name=".LibraryOneActivity"/>
    </application>

比较发现:debug下的AndroidMenifest.xml  比 relearse下的AndroidMenifest.xml 属性多。这样做的目的是,在将Module组合在一起的时候,release下的AndroidMenifest.xml与app下的AndroidMenifest.xml定义的属性没有发生冲突。


   3.Application问题

      对于一个应用应用来说,有且只有一个Application。当开发者没有自定义application时,系统会使用默认的application。
      当在AndroidMenifest.xml使用自己定义的application,系统才会调用自定义的。
       
      每个Module创建了application时,将各个Module组合以后就会发生Module的Application 和 主app的Application冲突情况。
       
      这里提供了一种方式解决这个问题:
      同解决AndroidMenifest.xml问题类似,我们在java目录下创建一个debug目录并在这个目录下创建application,在debug目录的AndroidMenifest.xml上使用这个application。并在build.gradle中加入


当前app模式运行时,将debug目录下的文件删除掉。


4.实现统一版本

      在多人开发的时候总会出现一种情况:我把代码下载下来时大多情况下是不能运行的,我通常需要去修改sdk版本号和编译版本号,当使用多个Module时,还需要一个一个Module去修改。版本统一就显得很有必要了。我们想要的就是在改变一处地方,全部都改变。

      4.1 在project中创建一个config.gradle(名字随便)文件。

           

            4.2 配置各种信息

ext{
    android = [
            compileSdkVersion: 25,
            buildToolsVersion:"25.0.2",
            minSdkVersion:15,
            targetSdkVersion:25,
            versionCode:1,
            versionName:"1.0"
    ]
    depenVersion = [
            support:"25.3.1"
    ]
    dependencies = [
         // --------------  Android  ------------
         appcompatv7 : 'com.android.support:appcompat-v7:25.3.1',
         // -----------------  test  -------------
         junit : 'junit:junit:4.12'
    ]
}

     4.3 在project的 build.gradle文件中引用   

apply from :"config.gradle"

     4.4 在各个Module中使用

android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion

    defaultConfig {
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode rootProject.ext.android.versionCode
        versionName rootProject.ext.android.versionName
    }
}


     5.Module间的跳转
       Module间的跳转是实现组件化开发中很关键的一步。之前我们使用Intent做跳转,但是在组件化时候Module之间是分割开的(没有相互依赖。)。比如说A Module中只能找到本Module实现的Activity,并没有找到其他Module的activity。
      我解决的方法是:使用 ActivityRouter 做Module间跳转。

     需要了解ActivityRouter的请猛点这里:ActivityRouter

     集成ActivityRouter

     5.1  在project的build.gradle中

    

     5.2 在每个Module(包括app)的build.gradle中引用:

        


    5.3 在每个Module(包括app)中创建一个类做标记。(类似于说明该Module引用了ActivityRouter功能)

   例如:

       

    5.4  app中标识所有的Module标记

    

    “app”是主app标记的,“aModule”和“bModule”分别是其他两个Module标记的。

     在主app的AndroidMenifest.xml中添加:

    

<activity
            android:name="com.github.mzule.activityrouter.router.RouterActivity"
            android:theme="@android:style/Theme.NoDisplay">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="assembly" /><!--改成自己的scheme-->
            </intent-filter>
        </activity>
    需要注意的是:scheme的值 是自己填的。它就相当于http一样,在后面的跳转中起到很大的作用。

    5.5 在librarya中一个Activity定义路径:

    

@Router("libraryOne")
public class LibraryOneActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.a_main_activity);
    }

    public  void aClick(View view){
        Routers.open(LibraryOneActivity.this,"assembly://libraryTwo");
    }

}
    我们在主app的界面跳转到  librarya的界面是:

public void main(View view){
        Routers.open(MainActivity.this,"assembly://libraryOne");
    }
    注意我标有红色的地方。

    当然 Module间的界面跳转也是可以如此操作的。    

    需要了解 界面间的传值的可以 看看ActivityRouter的教程,很简单,我就不在这里写了。

     Module间的交互可以使用EventBus就可以了。

     有需要源码的在这里  组件化开发源码


   









        

     

    



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值