1. 程式人生 > >Android 測試環境和生產環境動態切換實現思路

Android 測試環境和生產環境動態切換實現思路

        在開發專案的過程中,通常會遇到開發環境、測試環境、預釋出環境、生產環境等多種環境互相切換的問題。客戶端需要根據不同環境選擇不同的域名呼叫介面,或者展示一些隱藏功能。如果每切換一種環境都需要重新打包,那就變得太蛋疼了。

簡單的說下思路,就是把需要更改的域名以檔案形式存到SD卡里,通過修改/讀取檔案設定域名。

解決方法分為以下幾步:

  1. 區分正式包、測試包:

抽象來看,其實安裝包只需要兩種就行:正式包、測試包。

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

大功告成

如果你覺得本文對你有幫助,請分享給你的好友吧~

相關推薦

Android 測試環境生產環境動態切換實現思路

        在開發專案的過程中,通常會遇到開發環境、測試環境、預釋出環境、生產環境等多種環境互相切換的問題。客戶端需要根據不同環境選擇不同的域名呼叫介面,或者展示一些隱藏功能。如果每切換一種環境都需要重新打包,那就變得太蛋疼了。簡單的說下思路,就是把需要更改的域名以檔案形式存到SD卡里,通過修改/讀取檔案

開發環境 測試環境 生產環境的區別

對於一個剛進入公司的新人來說,在熟悉工作環境的時候,會聽著幾個“老人”在自己可視範圍之外或者輕鬆的討論著業務,其措辭拿捏精準,期間,涉及到一系列的概念,可能會讓你不覺明厲,暗歎:“高階,大氣,上檔次”。有些術語,它既有官方稱呼,也有通俗叫法,對於不覺明厲的我們只

springboot不同環境,不同配置的實現(開發環境生產環境切換

首先,是我實現的最終效果圖可以看到這裡配置了3個application,其中第一個是總的配置,第二個是開發環境,第三個是生產環境。總的配置總是會生效的,而另外兩個配置生效的條件,則要看看我們在總的配置裡配置了什麼,比如這裡,我在application.yml裡配置了開發環境s

webpack開發環境生產環境切換原理

在package.json中有如下設定: "scripts": {     "dev": "node build/dev-server.js",     "build:prod": "cross-env NODE_E

解決測試環境生產環境頁面路徑不匹配的辦法

實際應用中,一般用來解決jsp測試和生產環境路徑不同的問題: <% String appContext = request.getContextPath(); String basePath = request.getScheme()+"://"+request.get

navicat測試環境生產環境資料結構同步

測試環境完成測試,資料庫的修改的資料結構需要同步到生產環境的資料庫。可以通過寫指令碼的方式完成資料同步,當然navicat提供了更簡單的方式 第一步:工具-結構同步 第二步:對比正式庫和測試庫存

vuejs經驗交流之-開發環境生產環境的啟動

分享 技術 cli cnpm 刪掉 經驗交流 http 開發環境 yarn vue開發環境 首先要下載必要的包 命令 cnpm install/yarn install 1 啟動後臺服務 npm run server

手把手教你用webpack3搭建react項目(開發環境生產環境)(一)

stc reac config nod top llb cor git history 開發環境和生產環境整個配置源碼在github上,源碼地址:github-webpack-react 如果覺得有幫助,點個Star謝謝!! (一)是開發環境,(二)是生產環境。 一、首

Spring Cloud 進階之路 -- Eureka的高可用,搭建 Eureka叢集(開發環境生產環境

  Eureka 作為註冊中心,必須保障高可用,否則會直接影響有關的整個服務體系。 以下分別進行開發環境和生產環境的多服務中心叢集配置。   目錄 一、開發環境簡易配置: 1、配置Configurations 2、在Configurations 裡

webpack -- 關於proxyTable的配置在開發環境生產環境中的原理解析

前言 首先,proxyTable是我們在本地開發環境中除錯介面用的,目的是為了解決本地跨域的問題,因為本地地址為localhost:xxxx/xxx 在線上的生產環境是沒用的!!! 假設我們用的是vue-cli命令列工具生成的webpack專案模板

Spring Cloud 進階之路 -- Eureka的高可用,搭建 Eureka叢集(開發環境生產環境

Eureka 作為註冊中心,必須保障高可用,否則會直接影響有關的整個服務體系。 以下分別進行開發環境和生產環境的多服務中心叢集配置。 目錄 一、開發環境簡易配置: 1、配置Configurations 在上一

react+webpack 打包,開發環境生產環境整合一體拿來就能用

直接上程式碼: webpack.config.js import webpack from "webpack"; import path from "path"; var path = path.resolve(__dirname,"/main.j") var

騰訊雲的開發環境生產環境傻傻分不清

開發環境和生產環境 為了方便開發除錯,防止影響到線上服務,騰訊雲提供開發和生產兩套環境,兩套環境擁有以下特點: 開發環境 免費使用 自動分配測試用二級域名:xxxxxxx.qcloud.la 自動部署免費 HTTPS 僅可用於線上除錯,不可釋出

Webpack配置區分開發環境生產環境

  在專案開發的時候,我們通常會將程式分為開發環境和生產環境(或者叫線上環境),開發環境通常指的是我們正在開發的這個階段所需要的一些環境配置,也就是方便我們開發人員除錯開發的一種環境;生產環境通常指的是我們將程式開發完成經過測試之後無明顯異常準備釋出上線的環境,也可以理解為使用者可以正常使用的就是生產環境;

Spring.profile實現開發、測試生產環境的配置切換

軟體開發過程一般涉及“開發 -> 測試 -> 部署上線”多個階段,每個階段的環境的配置引數會有不同,如資料來源,檔案路徑等。為避免每次切換環境時都要進行引數配置等繁瑣的操作,可以通過spring的profile功能來進行配置引數的切換。 以我用到的專案的實際情況

Spring之——Spring.profile實現開發、測試生產環境的配置切換

軟體開發過程一般涉及“開發 -> 測試 -> 部署上線”多個階段,每個階段的環境的配置引數會有不同,如資料來源,檔案路徑等。為避免每次切換環境時都要進行引數配置等繁瑣的操作,可以通過spring的profile功能來進行配置引數的切換。 以我用到的專案的實際

【Spring】使用@Profile註解實現開發、測試生產環境的配置切換,看完這篇我徹底會了!!

## 寫在前面 > 在實際的企業開發環境中,往往都會將環境分為:開發環境、測試環境和生產環境,而每個環境基本上都是互相隔離的,也就是說,開發環境、測試環境和生產環境是互不相通的。在以前的開發過程中,如果開發人員完成相應的功能模組並通過單元測試後,會通過手動修改配置檔案的形式,將專案的配置修改成測試環境

Docker 標準化開發測試生產環境

對於大部分企業來說,搭建 PaaS 既沒有那個精力,也沒那個必要,用 Docker 做個人的 sandbox 用處又小了點。可以用 Docker 來標準化開發、測試、生產環境。Docker 佔用資源小,在一臺 E5 128 G 記憶體的伺服器上部署 100 個容器都綽綽有餘,

開發環境生產環境測試環境的基本理解區別

開發環境:開發環境是程式猿們專門用於開發的伺服器,配置可以比較隨意, 為了開發除錯方便,一般開啟全部錯誤報告。 測試環境:一般是克隆一份生產環境的配置,一個程式在測試環境工作不正常,那麼肯定不能把它釋出到生產機上。 生產環境:是指正式提供對外服務的,一般會關掉錯誤報告,開啟

通過 spring 容器內建的 profile 功能實現開發環境測試環境生產環境配置自動切換

軟體開發的一般流程為工程師開發 -> 測試 -> 上線,因此就涉及到三個不同的環境,開發環境、測試環境以及生產環境,通常這三個環境會有很多配置引數不同,例如資料來源、檔案路徑、url等,如果每次上線一個新版本時都手動修改配置會十分繁瑣,容易出錯。spring 為我