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);
    }
}
四、效果圖

在這裏插入圖片描述

發佈了55 篇原創文章 · 獲贊 14 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章