在实际的开发工程中,一般会遇到开发环境测试环境,预发布环境,线上测试环境,线上环境多种环境互相切换的问题,而跟后台进行本地调试接口,又会加入其他的不可预料的环境配置,抛开用变量做环境配置的不说。下面就我遇到的几个问题及解决方式,做个总结,看官按需选择:
1.android studio中的bildcofig的环境编译配置,在编译的过程中,就会把gradle中的配置,生成一个buildcofig的类。
build.gradle的配置:
buildTypes {
DT1 {
buildConfigField 'String', 'SOCKETIO_URL', '"http://192.168.6.76:19082"'
}
DT2 {
buildConfigField 'String', 'SOCKETIO_URL', '"http://192.168.6.76:19082"'
}
}
在build工程之前选择下相应的环境:
在编译过后会生成一个类:
在url配置中,加入的buildconfig.base就是当前的环境配置。
该种方式,官方支持,但是在每次的build之前需要进行选择,不能在打包之后进行自由配置。
2.使用文件来构成环境选择的base配置。(例如sp,xml等等方式)
存在问题:从文件读出base环境之后,如果urlconstant中的配置是以static来进行的组装,那么会产生刷新不了static量的问题,如果是在使用中自行组装是没问题的。
3.使用urlconstant同时希望用static来事先组织好完整url的情况,就需要在用户打包好apk的时候用选择栏进行动态切换环境的情况。
那么我们需要多做一层操作:
import android.util.Log;
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;
public class reject_utls {
public static void reject(Object model){
String baseUrl = "BaseUrl";
List <String > allBase = new LinkedList<>();
Field[] fields = model.getClass().getDeclaredFields(); // 获取实体类的所有属性,返回Field数组
try {
for (int j = 0; j < fields.length; j++) { // 遍历所有属性
String name = fields[j].getName(); // 获取属性的名字
name = name.substring(0, 1).toUpperCase() + name.substring(1);
String type = fields[j].getGenericType().toString(); // 获取属性的类型
if (type.equals("class java.lang.String")) { // 如果type是类类型,则前面包含"class ",后面跟类名
if(judgeContain(name)){//不处理
Field field = fields[j];
String value = field.get(null).toString();
allBase.add(value);
}else{
Log.e("text",""+ name);
Field field = fields[j];
//将字段的访问权限设为true:即去除private修饰符的影响
field.setAccessible(true);
// /*去除final修饰符的影响,将字段设为可修改的*/
// Field modifiersField = Field.class.getDeclaredField("modifiers");
// modifiersField.setAccessible(true);
// modifiersField.set(field, field.getModifiers() & ~Modifier.FINAL);
String value = field.get(null).toString();
//把字段值设置为自己的值
// field.set(null, Constant.BaseUrl + value.replace(baseUrl,""));
}
}
}
} catch (SecurityException e) {
e.printStackTrace();
Log.e("text",""+ e.getStackTrace());
} catch (IllegalAccessException e) {
e.printStackTrace();
Log.e("text",""+ e.getStackTrace());
} catch (IllegalArgumentException e) {
e.printStackTrace();
Log.e("text",""+ e.getStackTrace());
}
}
//加入自己例外处理的base的那么
public static boolean judgeContain(String name){
String [] array = new String[]{"SOCKETIO_URL","UPLOAD_PIC","SALES","BASE","TRANSPORTION","WAREHOUSE","LABOR","SUPPLY","DATASYNC","H5"};
for(String dest: array){
if(name.contains(dest)){
return true;
}
}
return false;
}
}
在这里使用反射,在选择了baseurl之后,动态的将所有的static的属性都刷新一边,原因在于urlconstant的管理是如下的:
public static String url1 = SOCKETIO_URL1 + "/getInfo5";
public static String url2 = UPLOAD_PIC1 + "/getInfo5";
public static String url3 = SALES1 + "/getInfo5";
及时每次选择了base之后,的SOCKETIO_URL变了,但是因为是static类型,不会再次到url的拼接操作中,那么最终的url1,url2,url3都不会实时的变化。故需要加入一个反射刷新的操作。
同时在第二种文件方式中,若url也是拼接之后直接使用的话,也可以用上述的方式,进行刷新属性值的操作,来实现动态切换环境。
当然,客官使用了变量的方式来处理的话,另说不会有太多问题,或者在每次获取url的时候用方法在中间进行组装的话,因为会每次走一次拼接的操作,所以也不存在太多的问题。