Android在debug和release模式自動載入不同的配置檔案
阿新 • • 發佈:2019-02-16
思路:
1. 判斷當前執行在何種模式下
2. 載入配置檔案
1. 判斷當前執行在何種模式下
當直接在eclipse中執行程式和android tools工具打包時候,會自動修改gen/**/BuildConfig.java中的欄位DEBUG欄位的值
if (BuildConfig.DEBUG) {
// debug模式
} else {
// release模式
}
2. 載入配置檔案
使用PULL解析器解析asset中的不同配置檔案,每個配置檔案配置了需要反射的類名稱資訊以及欄位資訊
xml檔案格式:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<description></description>
<className>com.yanjun.testpowerful.Config</className>
<a>1</a>
<b>2</b>
</root>
解析類:
package com.yanjun.testpowerful.util;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
import android.text.TextUtils;
import android.util.Xml;
public class LoadConfigUtil {
// 解析對應到類
private static final String TAG_CLASSNAME = "className";
// xml中根節點tag名稱
private static final String TAG_ROOTNAME = "root";
// xml編碼
private static final String XML_ENCODING = "utf-8";
/**
* 載入配置
* @param ctx
* @param fileName
* @throws IOException
* @throws XmlPullParserException
*/
public static void load(Context ctx, String fileName) throws IOException, XmlPullParserException {
// 將xml解析為map
Map<String, String> content = parser(ctx, fileName);
// 檢查類配置
String className = content.get(TAG_CLASSNAME);
if (TextUtils.isEmpty(className)) {
throw new IllegalStateException("missing configuration: missing " + TAG_CLASSNAME);
}
Class<?> clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return ;
}
// 通過反射設定值
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
try {
// 只反射靜態欄位
if ((field.getModifiers() & Modifier.STATIC) != Modifier.STATIC) {
continue ;
}
String fieldName = field.getName();
if (!content.containsKey(fieldName)) {
continue;
}
field.setAccessible(true);
field.set(null, content.get(fieldName));
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*
* 將xml解析為map
*/
private static Map<String, String> parser(Context ctx, String fileName) throws IOException, XmlPullParserException {
Map<String, String> content = new HashMap<String, String>();
InputStream in = ctx.getAssets().open(fileName);
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, XML_ENCODING);
String lastTagName = null;
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
if (parser.getName().equals(TAG_ROOTNAME)) {
break;
}
lastTagName = parser.getName();
break;
case XmlPullParser.TEXT:
if (lastTagName == null) {
break;
}
String value = parser.getText();
if (value != null) {
content.put(lastTagName, value.trim());
}
case XmlPullParser.END_TAG:
lastTagName = null;
break;
}
eventType = parser.next();
}
} finally {
if (in != null) {
in.close();
}
}
return content;
}
}
在Application建立的時候反射具體的配置到類中:
package com.yanjun.testpowerful;
import android.app.Application;
import com.yanjun.testpowerful.util.LoadConfigUtil;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 載入配置檔案
loadConfig();
}
/*
* 載入配置檔案
*/
private void loadConfig() {
try {
if (BuildConfig.DEBUG) {
LoadConfigUtil.load(this, "config-debug.xml");
} else {
LoadConfigUtil.load(this, "config-release.xml");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 後續:
-
優點
-可以對生產環境和測試環境使用兩套不同的配置,並動態切換,不用修改程式碼和配置
- 缺點
-在app啟動的時候使用到了解析xml、反射等技術,可能會額外增加app啟動時間,尤其在配置較多的時候
- 提示
-減少不必要的配置
-將必須的配置定義到同一個類中,其它常量定義其他類中
-如果使用了混淆,記得去掉混淆xml中配置的類
-如果需要動態載入多個類的配置,可使用多個配置檔案
補充:
當引用Library專案時,使用了Library專案中的BuildConfig類,該類中的DEBUG不會在打包的時候被修改,可以Application啟動的時候通過程式碼獲取程式的模式,並做相應的設定
// 判斷是否是以debug模式執行
if ((getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) == ApplicationInfo.FLAG_DEBUGGABLE) {
// 設定日誌輸出級別:輸出所有日誌
LOG_LEVEL = LOG_LEVEL_DEBUG|LOG_LEVEL_INFO|LOG_LEVEL_WARN|LOG_LEVEL_ERROR|LOG_LEVEL_ASSERT;
} else {
// 設定日誌輸出級別:不輸出
LOG_LEVEL = 0;
}