android开发模式之组件化开发

一、简介

基于模块化。有一个主工程(壳工程)和多个组件(module)。开发时每个组件都是application,打包发布时每个组件都作为library。

关于模块化:

模块化是AndroidStudio中引进的概念,主要分为application和library两种格式。将工程中共享部分和各个业务模块,拆分成多个module,实现代码和业务上的解耦。是组件化的基础。

二、存在的意义
  • 将公共依赖库以及各个业务模块代码彻底解耦,使得组件关系更加清晰。
  • 摆脱了修改一个模块需要编译这个工程的弊端,加快了编译速度。
三、实现步骤

在组件化开发中,实现难点主要在于
1.组件间界面的跳转以及数据的传递和共享
2.开发和发布环境如何快速切换,毕竟application和library在gradle及AndroidManifest的配置上有

3.1 对于路由的处理

我们可以使用Intent跳转,但是考虑到Intent需要依赖library硬编码,我们这里使用ActivityRouter作为项目路由,在app包下:

public class MainActivity extends AppCompatActivity {

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

    public void textOnClick(View view) {
        Routers.open(MainActivity.this, Uri.parse("modularization://url_path/1/字符串"));
    }
}

3.2 对于usermodule包在开发中作为library与application切换

首先我们需要在项目根目录gradle.properties下定义变量用来区分usermodule是作为library还是application

IsBuildSignle=true

另外在usermodule作为独立application的时候,app包不需要依赖于usermodule,所以需要在app包的Gradle中处理成

apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.hugo'
android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.common.modularization_master"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    if (!IsBuildSignle.toBoolean()){
        compile project(':usermodule')
    }
    compile 'org.greenrobot:eventbus:3.0.0'
    compile 'com.github.mzule.activityrouter:activityrouter:1.2.2'
}

同时在usermodule不作为独立application的时候,manifest不需要程序入口,所以对于usermodule我们需要定义两套manifest。在usermodule的Gradle中我们处理成

if(IsBuildSignle.toBoolean()){
    apply plugin:'com.android.application'
}else{
    apply plugin:'com.android.library'
}
android {
    compileSdkVersion 26
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets{
        main{
            if(IsBuildSignle.toBoolean()){
                manifest.srcFile 'src/main/AndroidManifest.xml'
//                java.srcDirs += "src/main/debug/java/";
            }else{
                manifest.srcFile 'src/library/AndroidManifest.xml'
            }
        }
    }
    //代码静态检查,避免资源混淆
//    resourcePrefix "usermodule"
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    compile 'com.github.mzule.activityrouter:activityrouter:1.2.2'
    annotationProcessor 'com.github.mzule.activityrouter:compiler:1.1.7'
}

最后我们可以在usermodule作为library中接收来自于app包的数据:

@Modules({"usermodule"})
@Module("usermodule")
@Router("url_path/:id/:title")
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.usermodule_activity_main);
        int id = 0;
        String title = null;
        if (getIntent().getExtras() != null) {
            id = getIntent().getExtras().getInt("id", 0);
            title = getIntent().getExtras().getString("title", null);
        }
        ((TextView) findViewById(R.id.tv_usermodule)).setText("This is user module:" + "id:" + id + ",title:" + title);
    }
}
四、效果图

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章