在Android Studio下的一種模組化思路
阿新 • • 發佈:2019-01-02
隨著專案功能的增多,我們在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
1
每個module都寫一個自己的Application,然後在AndroidMinefist.xml中配置上這個Application的屬性,在apk的module中增加一個總控制,能夠呼叫到所有依賴的module的Application即可。
在moduleA中正常寫moduleA所需要的Application:
1
1
1
1. 如何改變module的“屬性”,是library還是application?
2. 要想到每個module都有自己的“生命週期”,怎麼讓module作為library時,作為Application的module無浸入的載入module生命週期?
1. 如何改變module的“屬性”? 在gradle中可以使用一個變數來控制是library還是application,如下所示:
1
def isBuildApk = false
2if (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時,可以做如下新增:
1sourceSets {
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
3
public void onCreate() {
4
super.onCreate();
5
Log.v("testMeta",ReallyApplication.class.getSimpleName() + " " + getMethodStr());
6
Log.v("testMeta","pkgName = " + getApplicationContext().getPackageName());
7
}
8
9
public void onTerminate() {
10
super.onTerminate();
11
Log.v("testMeta",ReallyApplication.class.getSimpleName() + " " + getMethodStr());
12
}
13
14
public void onLowMemory() {
15
super.onLowMemory();
16
Log.v("testMeta",ReallyApplication.class.getSimpleName() + " " + getMethodStr());
17
}
18
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
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
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
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
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 {