Android 测试环境和生产环境动态切换实现思路

xiaoxiao2021-02-28  11

        在开发项目的过程中,通常会遇到开发环境、测试环境、预发布环境、生产环境等多种环境互相切换的问题。客户端需要根据不同环境选择不同的域名调用接口,或者展示一些隐藏功能。如果每切换一种环境都需要重新打包,那就变得太蛋疼了。

简单的说下思路,就是把需要更改的域名以文件形式存到SD卡里,通过修改/读取文件设置域名。

解决方法分为以下几步:

区分正式包、测试包:

抽象来看,其实安装包只需要两种就行:正式包、测试包。

productFlavors {    dev {        manifestPlaceholders.put("TEST_SETTING""true")    }    prod{        manifestPlaceholders.put("TEST_SETTING""false")    }}

创建app/src/main/assets/config.properties文件,内容如下:

log=falsehost=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卡");    }}

大功告成

如果你觉得本文对你有帮助,请分享给你的好友吧~

转载请注明原文地址: https://www.6miu.com/read-2250393.html

最新回复(0)