1. 程式人生 > >在Android Studio下的一種模組化思路

在Android Studio下的一種模組化思路

        隨著專案功能的增多,我們在Android Studio下的module也越來越多,或者說本身我們就想將功能按module劃分。比如,你想做個 “微信” 一樣的應用,有聊天模組、朋友圈模組,購物模組、遊戲模組等等,你想把這些模組以module劃分,通常情況下是將這些module打包成一個微信apk的,但在某些情況下又想能夠單獨發一個 朋友圈apk,或者只有聊天功能的apk等。只需要做以下幾點就可以了。
    1.  如何改變module的“屬性”,是library還是application?
    2. 要想到每個module都有自己的“生命週期”,怎麼讓module作為library時,作為Application的module無浸入的載入module生命週期?
    1. 如何改變module的“屬性”?         在gradle中可以使用一個變數來控制是library還是application,如下所示:
1
def isBuildApk = false
2
if (isBuildApk) {
3
    apply plugin: 'com.android.application'
4
} else {
5
    apply plugin: 'com.android.library'
6
}
            在需要module成為apk時,將isBuildApk改為true,但此時需要在額外增加一個配置才行,否則在編譯時會報錯誤,說是找不到applicationId:
1
android {
2
    ... ...
3
    defaultConfig {
4
        if(isBuildApk){
5
            applicationId "com.xdja.zzlib"
6
        }
7
        ... ...
8
    }
9
    ... ...
10
}
            當然,如果你想在編譯成apk時,額外增加一些不作為library時的一些程式碼時,以及使用作為app的AndroidMenifest.xml時,可以做如下新增: 1
sourceSets {
2
        main {
3
            if (isBuildApk) {
4
                manifest.srcFile 'src/main_apk/AndroidManifest.xml'
5
                java
.srcDirs = ['src/main/java', 'src/main_apk/java']
6
            }
7
        }
8
    }
    2. 每個module都有自己的“生命週期”,怎麼讓module作為library時,作為Application的module無浸入的載入module生命週期?
        每個module都寫一個自己的Application,然後在AndroidMinefist.xml中配置上這個Application的屬性,在apk的module中增加一個總控制,能夠呼叫到所有依賴的module的Application即可。
        在moduleA中正常寫moduleA所需要的Application:
1
public class ModuleAApplication  extends Application{
2
    @Override
3
    public void onCreate() {
4
        super.onCreate();
5
        Log.v("testMeta",ReallyApplication.class.getSimpleName() + "  "  + getMethodStr());
6
        Log.v("testMeta","pkgName = " + getApplicationContext().getPackageName());
7
    }
8
     @Override
9
    public void onTerminate() {
10
        super.onTerminate();
11
        Log.v("testMeta",ReallyApplication.class.getSimpleName() + "  "  + getMethodStr());
12
    }
13
    @Override
14
    public void onLowMemory() {
15
        super.onLowMemory();
16
        Log.v("testMeta",ReallyApplication.class.getSimpleName() + "  "  + getMethodStr());
17
    }
18
    @Override
19
    protected void attachBaseContext(Context base) {
20
        super.attachBaseContext(base);
21
        Log.v("testMeta",ReallyApplication.class.getSimpleName() + "  "  + getMethodStr());
22
    }
23
    private String getMethodStr(){
24
        return Thread.currentThread() .getStackTrace()[3].getMethodName();
25
    }
26
}
        並在moduleA中的AndroidMenifest.xml中增加如下選項:
1
 <application >
2
        <meta-data android:name="xdja.zzlib.ModuleAApplication"
3
            android:value="application"/>
4
</application>
        再在主Apk中Application中,做如下處理,即通過檢視Application的meta-data來找到都有哪些module的Application,然後在各個生命週期中呼叫得到的meta-data中的各個Application生命週期:
1
public class ApkApplication extends Application {
2
    ArrayList<Application> applicationList = new ArrayList<>();
3 4
    @Override
5
    public void onCreate() {
6
        super.onCreate();
7
        for (Application application : applicationList) {
8
            try {
9
                application.onCreate();
10
            } catch (Exception e) {
11
                e.printStackTrace();
12
            }
13
        }
14
    }
15
     @Override
16
    public void onTerminate() {
17
        super.onTerminate();
18
        for (Application application : applicationList) {
19
            try {
20
                application.onTerminate();
21
            } catch (Exception e) {
22
                e.printStackTrace();
23
            }
24
        }
25
    }
26
    @Override
27
    public void onLowMemory() {
28
        super.onLowMemory();
29
        for (Application application : applicationList) {
30
            try {
31
                application.onLowMemory();
32
            } catch (Exception e) {
33
                e.printStackTrace();
34
            }
35
        }
36
    }
37
    @Override
38
    protected void attachBaseContext(Context base) {
39
        super.attachBaseContext(base);
40
        PackageManager pm = getPackageManager();
41
        try {
42
            PackageInfo pi = pm.getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
43
            ApplicationInfo ai = pi.applicationInfo;
44
            Bundle bundle = ai.metaData;
45
            Set<String> set = bundle.keySet();
46
            for (String s : set) {
47
                String value = bundle.getString(s);
48
                Log.w("testMeta", s);
49
                Log.w("testMeta", value);
50
                Log.w("testMeta", "....");
51 52
                if (value.equals("application")) {
53
                    try {
54
                        Class c = getClass().getClassLoader().loadClass(s);
55
                        Application application = (Application) c.newInstance();
56
                        applicationList.add(application);
57
                    } catch (Exception e) {
58
                        e.printStackTrace();
59
                    }
60
                }
61
            }
62
            for (Application application : applicationList) {
63
                try {