本文主要解决实际开发过程中各个环境之间繁琐的切换问题。
正式环境域名“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实现,由于篇幅和时间有限目前也没有这样的案例,暂时不写