在开发项目的过程中,通常会遇到开发环境、测试环境、预发布环境、生产环境等多种环境互相切换的问题。客户端需要根据不同环境选择不同的域名调用接口,或者展示一些隐藏功能。如果每切换一种环境都需要重新打包,那就变得太蛋疼了。
简单的说下思路,就是把需要更改的域名以文件形式存到SD卡里,通过修改/读取文件设置域名。
解决方法分为以下几步:
区分正式包、测试包:
抽象来看,其实安装包只需要两种就行:正式包、测试包。
productFlavors {
dev {
manifestPlaceholders.put("TEST_SETTING", "true")
}
prod{
manifestPlaceholders.put("TEST_SETTING", "false")
}
}
创建app/src/main/assets/config.properties文件,内容如下:
log=false
host=http://www.xxx.com
修改AndroidManifest.xml
<meta-data
android:name="TEST_SETTING"
android:value="${TEST_SETTING}">
</meta-data>
创建工具类,用来读取存储在SDCard的自定义域名
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
public class HttpUtil {
public static final String TAG = "HttpUtil";
public static Context context;
public static void init(Context context) {
HttpUtil.context = context;
}
/**
* 获取Assets目录下prance.properties中的属性
*
* @param key
* @return
*/
public static String getAssetsProperties(String key) {
Context context = HttpUtil.context;
String result = "";
try {
Properties properties = new Properties();
InputStream is = context.getAssets().open(getPathName());
properties.load(is);
if (properties != null) {
if (properties.containsKey(key)) {
result = properties.get(key).toString();
}
}
} catch (Exception e) {
Log.d(TAG, "getAssetsProperties e[" + e + "]");
}
return result;
}
/**
* 读取本地SD卡文件下prance.properties中的属性
*
* @param
* @return
*/
private static String getSDcardProperties(String key) {
String result = "";
try {
Properties properties = new Properties();
InputStream is = new FileInputStream(getBaseDir() + getPathName());
properties.load(is);
if (properties != null) {
if (properties.containsKey(key)) {
result = properties.get(key).toString();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 初始化 prance.properties中的属性
*
* @param key
* @return
*/
public static String getPropertiesValue(String key) {
Context context = HttpUtil.context;
String result = "";
boolean settingOpen = false;
try {
ApplicationInfo appInfo = context.getPackageManager()
.getApplicationInfo(context.getPackageName(),
PackageManager.GET_META_DATA);
String msg = appInfo.metaData.getString(Constants.TEST_SETTING);
if (!TextUtils.isEmpty(msg) && msg.equals("true")) {
settingOpen = true;
} else {
settingOpen = false;
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (checkSaveLocationExists() && fileIsExists(getBaseDir() + getPathName()) && settingOpen) {
result = getSDcardProperties(key);
if (result.equals("")) {
result = getAssetsProperties(key);
}
} else {
result = getAssetsProperties(key);
}
return result;
}
/**
* 判断文件是否存在
*
* @return
*/
public static boolean fileIsExists(String pathName) {
try {
File f = new File(pathName);
if (!f.exists()) {
return false;
}
} catch (Exception e) {
return false;
}
return true;
}
/**
* 初始属性的文件名
*
* @return
*/
public static String getPathName() {
return "config.properties";
}
/**
* 检查是否安装SD卡
*
* @return
*/
public static boolean checkSaveLocationExists() {
String sDCardStatus = Environment.getExternalStorageState();
boolean status;
if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
status = true;
} else
status = false;
return status;
}
/**
* 初始化文件保存基本目录
*
* @return
*/
public static String getBaseDir() {
return Environment.getExternalStorageDirectory().getPath() + File.separator;
}
}
应用,请忽略Retrofit,关注第二行。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlUtil.getPropertiesValue("host") + File.separator)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
修改,这里只有最核心的修改代码,你应该有一个可视化界面,上面有host的输入框,动态修改host。
public void setting(String host) {
Properties prop = new Properties();
prop.put("host", host);
saveToSDCard(prop);
}
private void saveToSDCard(Properties prop) {
if (HttpUtil.checkSaveLocationExists()) {
File file = new File(HttpUtil.getBaseDir());
if (!file.exists()) {
file.mkdirs();
}
try {
FileOutputStream fos = new FileOutputStream(HttpUtil.getBaseDir() + HttpUtil.getPathName(), false);
prop.store(fos, null);
} catch (Exception e) {
e.printStackTrace();
}
//接下来根据需求,清理数据,然后重启APP进程
//Clear Data
//Restart Process
} else {
ToastUtil.getInstance().showToast("保存失败,无SD卡");
}
}
大功告成
如果你觉得本文对你有帮助,请分享给你的好友吧~
