Android開發(fā)工具之環(huán)境切換

Android開發(fā)工具之環(huán)境切換

Android開發(fā)工具之OKHTTP日志抓取

背景介紹

該工具是續(xù)篇,上一篇介紹的是Http日志抓取工具,這一篇講解環(huán)境切換,環(huán)境切換為什么需要這個(gè),現(xiàn)在稍微大點(diǎn)的公司基本都是兩套以上環(huán)境,分為測試、預(yù)發(fā)和線上,有些公司沒有預(yù)發(fā)這個(gè)部分。原來開發(fā)hybrid App的時(shí)候,可以直接修改配置文件的一個(gè)配置值可以切換當(dāng)前環(huán)境,但是App如何這么設(shè)置的劃,開發(fā)比較耗費(fèi)時(shí)間,每次調(diào)試測試或者預(yù)發(fā)環(huán)境的接口時(shí),總是得重新打包,對于一個(gè)開發(fā)者來說是十分痛苦的。

所以,環(huán)境切換就孕育而生,我們就打一次debug包,然后需要調(diào)試測試環(huán)境接口時(shí),就搖一搖進(jìn)入調(diào)試界面,然后點(diǎn)擊切換環(huán)境,切換成測試環(huán)境,然后自動(dòng)重啟app,再次打開之后,app就進(jìn)入測試環(huán)境,接口切換為測試環(huán)境的接口,數(shù)據(jù)配置都自動(dòng)切換成測試環(huán)境的東西,無需打包,無需修改代碼、無需重新運(yùn)行。

頁面截圖

[站外圖片上傳中...(image-d2f574-1569233613624)]
mrxgX3K2JMTwlHF

上面就是Debug界面,這個(gè)跟上一篇介紹的都是放在BaseActivity中,全局搖一搖就可以顯示該界面,點(diǎn)擊當(dāng)前環(huán)境就可以選擇當(dāng)前環(huán)境。

代碼實(shí)現(xiàn)

其實(shí)這部分也很簡單,主要是通過Sp存儲當(dāng)前環(huán)境狀態(tài),默認(rèn)第一次是測試環(huán)境,然后每次切換環(huán)境之后,將新的環(huán)境狀態(tài)存儲到sp當(dāng)中,然后清除App的存儲的數(shù)據(jù)狀態(tài),或者將數(shù)據(jù)存儲到每個(gè)狀態(tài)對應(yīng)的目錄下,這里見仁見智,退出登錄并重新啟動(dòng)App,讓App的新環(huán)境生效,重新加載新的App。

首先創(chuàng)建一個(gè)DebugActivity,來處理App所有的調(diào)試界面

DebugActivity.java

/**
 * Created by mguo on 2018/5/3.
 */
@Route(path = RouterConstant.ACTIVITY_DEBUG)
public class DebugActivity extends BaseSwipeBackActivity {
    @Bind(R.id.tv_env)
    TextView tvEnv;
    @Bind(R.id.tv_device_bind)
    TextView tvDeviceBind;
    @Bind(R.id.rl_device_bind)
    RelativeLayout rlDeviceBind;
    String[] items = new String[]{"測試", "生產(chǎn)", "預(yù)生產(chǎn)", "本地"};
    String[] itemBind = new String[]{"開啟校驗(yàn)", "取消校驗(yàn)"};
    @Bind(R.id.img_back)
    ImageView imgBack;
    @Bind(R.id.index_app_name)
    TextView indexAppName;
    @Bind(R.id.tv_title_right)
    TextView tvTitleRight;
    @Bind(R.id.rl_wechat_share)
    RelativeLayout rlWechatShare;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_debug_layout;
    }

    @Override
    protected void onInitialization(Bundle bundle) {
        ARouter.getInstance().inject(this);
    }

    @Override
    protected void initView(Bundle bundle) {
        if (GlobalEnv.isRelease()) {
            rlDeviceBind.setVisibility(View.GONE);
        }
        rlDeviceBind.setVisibility(View.VISIBLE);
        tvEnv.setText(items[GlobalEnv.getEnvModel()]);
        tvDeviceBind.setText(itemBind[GlobalEnv.isVerifyDevice() ? 0 : 1]);
        indexAppName.setText("環(huán)境調(diào)試");
        tvTitleRight.setText(getString(R.string.string_txt_cancel));
        tvTitleRight.setVisibility(View.VISIBLE);
    }

    @Override
    protected void initData(Bundle bundle) {

    }

    @OnClick({R.id.rl_cd,R.id.rl_http,R.id.layout_debug, R.id.rl_demo_list, R.id.layout_webview, R.id.rl_device_bind, R.id.tv_title_right, R.id.img_back, R.id.rl_update, R.id.rn_setting,R.id.rl_wechat_share})
    public void onViewClicked(View view) {

        switch (view.getId()) {
            case R.id.img_back:
                finish();
                break;
            case R.id.rl_demo_list:
                gStartActivity(DemoListActivity.class);
                break;
            case R.id.tv_title_right:
                finish();
                break;
            case R.id.rl_device_bind:
                AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
                builder1.setTitle("選擇是否校驗(yàn)");
                builder1.setSingleChoiceItems(itemBind, GlobalEnv.getEnvModel(), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int i) {
                        dialog.dismiss();
                        GlobalEnv.setVerifyDevice(getContext(), i == 0);
                        tvDeviceBind.setText(itemBind[i]);
                    }
                });
                builder1.show();
                break;
            case R.id.layout_debug:
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("選擇環(huán)境");
                builder.setSingleChoiceItems(items, GlobalEnv.getEnvModel(), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int i) {
                        dialog.dismiss();
                        if (GlobalEnv.getEnvModel() == i) {
                            return;
                        }
                        showToast("應(yīng)用重啟中");
                        GlobalEnv.setEnvModel(i);
                        tvEnv.setText(items[i]);
                        UserManager.getInstance().logout();
                        AppExitUtil.restart(DebugActivity.this);
                    }
                });
                builder.show();
                break;
            case R.id.layout_webview:
                getRouter().showWebviewWithUrl("file:///android_asset/index.html");
                break;
            case R.id.rn_setting:
                gStartActivity(RNDebugActivity.class);
//                down();
                break;
            case R.id.rl_cd:
                openBrowser("");
                break;
            case R.id.rl_http:
                gStartActivity(HttpListActivity.class);
                break;
            case R.id.rl_update:
                new SweetAlertDialog.Builder(this).setMessage("是否打開瀏覽器").setPositiveButton("確定", new SweetAlertDialog.OnDialogClickListener() {
                            @Override
                            public void onClick(Dialog dialog, int which) {
                                String url = "";
                                int envModel = GlobalEnv.getEnvModel();
                                switch (envModel) {
                                    case ENV_DEBUG:
                                        url = "";
                                        ??????????? break;
                                    case ENV_RELEASE:
                                        url = "";
                                        break;
                                    case ENV_BETA:
                                        url = "";
                                        break;
                                }
                                openBrowser(url);
                            }
                        }
                ).setNegativeButton("取消", null)
                        .show();

                break;
            case R.id.rl_wechat_share:
                gStartActivity(SendToWXActivity.class);
                break;
        }
    }

    @Override
    protected String initPageName() {
        return "調(diào)試頁面";
    }
}

GlobalEnv.java

public class GlobalEnv {

    public static final int ENV_DEBUG = 0;//測試環(huán)境
    public static final int ENV_RELEASE = 1;//生產(chǎn)環(huán)境
    public static final int ENV_BETA = 2;//預(yù)生產(chǎn)環(huán)境
    public static final int ENV_LOCAL = 3;//本地環(huán)境

    private static boolean mVerifyDevice = true;
    private static int mEnvModel = 0;
    private static String mtaChannel = "cstore";
    private static String versionName = "";

    public static String getChannel() {
        return mtaChannel;
    }

    public static String getVersionName() {
        return versionName;
    }

    public static boolean isDebug() {
        return TextUtils.equals(BuildConfig.BUILD_TYPE, "debug");
    }

    public static boolean isBeta() {
        return TextUtils.equals(BuildConfig.BUILD_TYPE, "beta");
    }

    public static boolean isRelease() {
        return TextUtils.equals(BuildConfig.BUILD_TYPE, "release");
    }

    public static int getEnvModel() {
        return mEnvModel;
    }

    public static void setVerifyDevice(Context context, boolean verify) {
        mVerifyDevice = verify;
        SharedUtil.instance(context).saveBoolean("env_device_verify", verify);
    }

    public static boolean isVerifyDevice() {
        return mVerifyDevice;
    }

    public static void setEnvModel(int envModel) {
        mEnvModel = envModel;
        SharedUtil.instance(BaseApp.getContext()).saveInt("mEnvModel", envModel);
        switch (envModel) {
            case ENV_DEBUG:
                ApiManager.getInstance().setBaseUrl(ApiConstant.BASETESTURL);
                ApiManager.getInstance().setWebUrl(ApiConstant.WEBTESTURL);
                ApiManager.getInstance().setTaskUrl(ApiConstant.TASKTESTURL);
                break;
            case ENV_RELEASE:
                ApiManager.getInstance().setBaseUrl(ApiConstant.BASEURL);
                ApiManager.getInstance().setWebUrl(ApiConstant.WEBURL);
                ApiManager.getInstance().setTaskUrl(ApiConstant.TASKURL);
                ApiManager.getInstance().setEmosUrl(ApiConstant.EOMSURL);
                break;
            case ENV_BETA:
                ApiManager.getInstance().setBaseUrl(ApiConstant.BASESTAGEURL);
                ApiManager.getInstance().setWebUrl(ApiConstant.WEBSTAGEURL);
                ApiManager.getInstance().setTaskUrl(ApiConstant.TASKSTAGEURL);
                ApiManager.getInstance().setEmosUrl(ApiConstant.EOMSURL);
                break;
            case ENV_LOCAL:
                ApiManager.getInstance().setBaseUrl(ApiConstant.BASELOCALURL);
                ApiManager.getInstance().setWebUrl(ApiConstant.WEBLOCALURL);
                ApiManager.getInstance().setTaskUrl(ApiConstant.TASKLOCALURL);
                break;
            default:
                ApiManager.getInstance().setBaseUrl(ApiConstant.BASETESTURL);
                ApiManager.getInstance().setWebUrl(ApiConstant.WEBTESTURL);
                ApiManager.getInstance().setTaskUrl(ApiConstant.TASKTESTURL);
                break;
        }

    }

    public static void init(Application application) {
        mVerifyDevice = SharedUtil.instance(application).getBoolean("env_device_verify", true);
        mtaChannel = DeviceUtil.getAppMetaData(application, "GJ_CHANNEL");
        versionName = DeviceUtil.getVersionName(application);
        Log.v("GlobalEnv", "channel=" + mtaChannel);
//        if (GlobalEnv.isRelease()) {
//            GlobalEnv.setEnvModel(GlobalEnv.ENV_RELEASE);
//            return;
//        }
        if (ApiManager.getInstance().isSetting()) {
            mEnvModel = SharedUtil.instance(application).getInt("mEnvModel", 0);
            return;
        }
        if (TextUtils.equals(BuildConfig.BUILD_TYPE, "debug")) {
            setEnvModel(ENV_DEBUG);
        } else if (TextUtils.equals(BuildConfig.BUILD_TYPE, "release")) {
            setEnvModel(ENV_RELEASE);
        } else if (TextUtils.equals(BuildConfig.BUILD_TYPE, "beta")) {
            setEnvModel(ENV_BETA);
        }
    }
}

主要操作就是,切換環(huán)境-->保存新的環(huán)境配置-->退出登陸,并清除數(shù)據(jù)-->重啟App,里面有一部分操作是個(gè)人項(xiàng)目里面將網(wǎng)絡(luò)基礎(chǔ)BaseUrl和webview需要設(shè)置的環(huán)境配置的url進(jìn)行重置。

舉例: Http配置Url

// 其他統(tǒng)一的配置
        GHttp.getInstance().init(context)                           //必須調(diào)用初始化
                .setBaseUrl(ApiManager.getInstance().getBaseUrl())
                .setOkHttpClient(builder.build())               //建議設(shè)置OkHttpClient,不設(shè)置會使用默認(rèn)的
                .setCacheMode(CacheMode.NO_CACHE)               //全局統(tǒng)一緩存模式,默認(rèn)不使用緩存,可以不傳
//                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局統(tǒng)一緩存時(shí)間,默認(rèn)永不過期,可以不傳
                .setCacheTime(1000 * 60 * 60 * 24)           //全局統(tǒng)一緩存時(shí)間,默認(rèn)永不過期,可以不傳
                .setRetryCount(3)                               //全局統(tǒng)一超時(shí)重連次數(shù),默認(rèn)為三次,那么最差的情況會請求4次(一次原始請求,三次重連請求),不需要可以設(shè)置為0
                .addCommonHeaders(headers)                      //全局公共頭
                .addCommonParams(params);                       //全局公共參數(shù)

Url配置管理類ApiManager.java

public class ApiManager {
    private static ApiManager apiManager;
    private Context mContext;

    public ApiManager(Context context) {
        mContext = context;
    }

    public static ApiManager getInstance() {
        if (apiManager == null) {
            synchronized (ApiManager.class) {
                if (apiManager == null) {
                    apiManager = new ApiManager(BaseApp.getContext());
                }
            }
        }
        return apiManager;
    }

    private String baseUrl;
    private String webUrl;
    private String taskUrl;

    private String emosUrl;

    public boolean isSetting() {
        return !TextUtils.isEmpty(SharedUtil.instance(mContext).getString("baseUrl"));
    }

    public String getBaseUrl() {
        return TextUtils.isEmpty(baseUrl) ? SharedUtil.instance(mContext).getString("baseUrl", ApiConstant.BASEURL) : baseUrl;
    }

    public String getWebURL() {
        return TextUtils.isEmpty(webUrl) ? SharedUtil.instance(mContext).getString("webUrl", ApiConstant.WEBURL) : webUrl;
    }

    public String getTaskUrl() {
        return TextUtils.isEmpty(taskUrl) ? SharedUtil.instance(mContext).getString("taskUrl", ApiConstant.TASKURL) : taskUrl;
    }

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
        SharedUtil.instance(mContext).saveString("baseUrl", baseUrl);
    }

    public void setTaskUrl(String taskUrl) {
        this.taskUrl = taskUrl;
        SharedUtil.instance(mContext).saveString("taskUrl", taskUrl);
    }

    public void setWebUrl(String webUrl) {
        this.webUrl = webUrl;
        SharedUtil.instance(mContext).saveString("webUrl", webUrl);
    }

    public String getEmosUrl() {
//        return emosUrl;
        return TextUtils.isEmpty(emosUrl) ? SharedUtil.instance(mContext).getString("emosUrl", ApiConstant.EOMSURL) : emosUrl;
    }

    public void setEmosUrl(String emosUrl) {
        this.emosUrl = emosUrl;
        SharedUtil.instance(mContext).saveString("emosUrl", emosUrl);
    }
}

這只是部分環(huán)境代碼,剩下的邏輯都可以這樣來處理,switch一下環(huán)境,然后處理相應(yīng)的邏輯就OK,環(huán)境切換主要是為了滿足公司測試、預(yù)發(fā)和線上環(huán)境的切換,比如測試測完測試環(huán)境,然后服務(wù)端發(fā)布了預(yù)發(fā)環(huán)境,直接搖一搖切換環(huán)境,直接環(huán)境就切換成了預(yù)發(fā)環(huán)境的接口鏈接,線上也是這種原理,然后就可以直接進(jìn)行測試。

此篇over。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容