Android 正式测试预发布环境一键切换——不要再注释来注释去了

本文主要解决实际开发过程中各个环境之间繁琐的切换问题。

案例:

正式环境域名“http://abc.net",测试环境域名“http://test.abc.net",预发布环境域名“http://develop.abc.net",h5正式为“http://h5.abc.net",h5测试...,h5预发布...,图片加载正式...,...

于是你在url里这么写(为了省去前缀也许你写成了Interface,结果是一样的)

public class MyUrls {
    //正式
    public static final String HTTP = "http://abc.net";
    public static final String H5 = "http://xxx";
    public static final String IMG = "http://yyy";

    //测试
//    public static final String HTTP = "http://test.abc.net";
//    public static final String H5 = "http://xxxx";
//    public static final String IMG = "http://yyyy";
    //预发布
//    public static final String HTTP = "http://develop.abc.net";
//    public static final String H5 = "http://xxxxx";
//    public static final String IMG = "http://yyyyy";

    //...其他


    //接口
    //登录
    public static final String LOGIN = HTTP + "login";
}

于是每天都有“帮我打一个正式包”、“帮我打一个测试包”、“帮我打一个预发布包”...不绝于耳

而你每次都不耐烦的:注释、反注释

终于有一天你把测试的url发布到了应用市场上......

其实你也不想这样,但静态常量放在那不知该如何下手

但我告诉你,静态常量是不可修改,但不是不可动态赋值

由于多数博客鱼龙混杂,本博客如果让你非常满意或解决了大家的根本性问题,希望多多支持在下方点赞和回复一下,举手之劳方便大家。

 

思路:

首先我们需要修改url静态常量+静态代码块完全可以实现

其次我们不想在听到“帮我打一个xx”了,所以我们应该有一个position来标识当前是正式还是其他环境,SharedPreferences自然当之无愧了,然后写一个view给他们点就可以完美解决了

写完之后感觉自己萌萌哒,但是又有问题出现了:class不可能省略的“public static final Sting”。作为程序猿怎么能容忍这么繁杂而又冗余的东西呢,我们知道Interface可以省略这些,但Interface不能写逻辑,这似乎是个死循环...但Interface可以调用其他class,Interface+辅助class当之无愧

so:Interface+辅助class静态代码块+SharedPreferences+自定义view你值得拥有

效果:

public interface MyUrls {
    String HTTP = SysUrl.URL_HTTP;
    String H5 = SysUrl.URL_H5;
    String IMG = SysUrl.URL_IMG;

    //登录
    String LOGIN = HTTP + "login";
}
class SysUrl {
    public static final String[][] mUrl = {{"正式", "http://abc.net/", "h5", "img"},
            {"测试", "接口测试", "h5测试", "img测试"},
            {"预发布", "接口预发布", "h5预发布", "img预发布"}};
    //前缀
    public static final String URL_HTTP, URL_H5, URL_IMG;

    static {
        if (BuildConfig.DEBUG && mUrl.length > 1) {//只有debug模式才会切换
            int huanJing = SPUtilImpl.getHuanJing();//从sp中获取环境值,见下方说明
            URL_HTTP = mUrl[huanJing][1];
            URL_H5 = mUrl[huanJing][2];
            URL_IMG = mUrl[huanJing][3];
        } else {
            URL_HTTP = mUrl[0][1];
            URL_H5 = mUrl[0][2];
            URL_IMG = mUrl[0][3];
        }
    }
}
/**
 * 切换环境的view
 */
public final class HuanJingView extends FlowLayout {
    //{"描述","账号","密码"}
    final String[][] mZhangHao = {
            {"账号1", "1", "密码1"},
            {"账号2", "2", "密码2"},
            {"账号3", "3", "密码3"}
    };

    public HuanJingView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initData();
    }

    public HuanJingView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HuanJingView(Context context) {
        this(context, null, 0);
    }

    private void initData() {
        try {
            //只有debug的包才能看到
            if (BuildConfig.DEBUG) {
                //环境切换,核心功能
                final int huanJing = SPUtilImpl.getHuanJing();
                View.OnClickListener clickHuanJing = new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        SPUtilImpl.setHuanJing((int) v.getTag());
                        Utils.toast("正在退出");
                        TimeUtil.mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                System.exit(0);
                            }
                        }, 500);
                    }
                };

                for (int i = 0; i < SysUrl.mUrl.length; i++) {
                    String[] sts = SysUrl.mUrl[i];
                    if (huanJing == i) {
                        addTv("正在" + sts[0] + "中", R.color.c_w_000, 15, i, null);
                    } else {
                        addTv(sts[0], R.color.c_w_999, 12, i, clickHuanJing);
                    }
                }


                //账号切换,一键切换登录账号
                View.OnClickListener clickZhangHao = new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int i = (int) v.getTag();
                        //登录逻辑
                    }
                };

                for (int i = 0; i < mZhangHao.length; i++) {
                    addTv(mZhangHao[i][0], R.color.c_w_999, 12, i, clickZhangHao);
                }

                //activity跳转,制造假数据强制跳转过去
                final Intent[] intents = {
                        new Intent(getContext(), XXXActivity.class).putExtra("I_A", 123456)
                };
                View.OnClickListener clickIntent = new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int i = (int) v.getTag();
                        getContext().startActivity(intents[i]);
                    }
                };
                for (int i = 0; i < intents.length; i++) {
                    String cn = intents[i].getComponent().getClassName();
                    addTv("跳" + cn.substring(cn.lastIndexOf(".") + 1), R.color.c_w_999, 12, i, clickIntent);
                }

                //自定义区
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加一个TextView
     */
    private TextView addTv(String text, @ColorRes int colorRes, int textSizeSp, int tag, View.OnClickListener listener) {
        TextView tv = new AppCompatTextView(getContext());
        tv.setText(text);
        tv.setTextColor(CompatUtil.getColor(colorRes));
        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSp);
        tv.setTag(tag);
        tv.setPadding(10, 10, 10, 10);
        tv.setOnClickListener(listener);
        addView(tv);
        return tv;
    }
}

 至于如何实现任意文件使用sp见:https://blog.csdn.net/weimingjue/article/details/89175978

如果app的正式和测试包名不一样(不知道你是怎么想的,这有什么用,建议删掉),接口不仅仅有基类等更复杂的操作,可以使用强大的gradle实现,由于篇幅和时间有限目前也没有这样的案例,暂时不写

你可能感兴趣的:(android教程,不做框架只做UI,Android,环境切换,Android,静态常量修改环境切换,Android,发布环境切换)