在开发APP过程中(这里只讨论android应用)常常会遇到4套环境["开发环境","测试环境","与生产环境","生产环境"]等,没此开发完,开发人员都需要打包想对对应的环境给测试人员,这个货程真心麻烦,流程重复,纯体力劳动.就想能不能在应用内部切换APP运行环境.有了想法就开始动手.具体实现想法如下:
- 在应用中使用多次点击召唤神龙大法
- 使用摇一摇实现切换.
- 环境切换后要进行数据重置,一般是采用APP自重启.
- 相关细节优化,避免OOM等异常
以上是初步想法,那么怎么具体实现,利用android自带的本地文件 存储SharedPreferences来实现,这里需要注意,SP提供的put方法有commit()和apply()都能存储数据,那么有什么区别(可以百度查看,下面只是简单说明),
- apply()是异步存储的,这边请求put后,apply就开始异步存储,在后面使用时,可能还没有存储完成,那么久会取不到需要是数据
- commit()是非异步,能保证数据存储的完整性,在后面取值是没有问题的.
具体实现:
- 定义 ''项目请求接口路径 "类UrlManger.java代码如下:
public class UrlManager { public static String BASE_URL = "http://release/"; public static void replaceHostManager(String hostType) { if (hostType ==null){ hostType = "release"; } switch (hostType) { case "test": BASE_URL = "http://test/"; break; case "pre": BASE_URL = "http://pre/"; break; case "release": default: BASE_URL = "http://release/"; break; } } }
这个方法在appLiication的onCreate中调用,第一次调用会走到release中;
-
在X页面某控件添加点击事件,多次点击弹出环境切换弹窗,具体实现如下:
case R.id.iv_app_icon: if (BuildConfig.SWITCHING_ENVIRONMENT) { count++; if (count >= 5) { count = 4; final String[] items3 = new String[]{"test", "pre", "release"};//创建item AlertDialog alertDialog3 = new AlertDialog.Builder(this) .setTitle("切换APP运行环境") .setIcon(R.drawable.bg_boy) .setItems(items3, (dialogInterface, i) -> { //需要自己封装个SharedPreferences的工具类,这里使用commit() SharedPreferences.put("HOST", items3[i]); Toast.makeText(SettingsActivity.this, "环境切换->" + items3[i], Toast.LENGTH_SHORT).show(); Intent intent = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName()); PendingIntent restartIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT); AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, restartIntent); // 1秒钟后重启应用 System.exit(0); }) .create(); alertDialog3.show(); } else { ToastUtil.showToastLong("在点击" + (5 - count) + "次切换环境"); } } break;
下来我们需要去完善application中怎么去调用:
String host = SharedPreferences.getString("HOST"); LogUtils.debugInfo("ly-001-3",host); if (BuildConfig.SWITCHING_ENVIRONMENT){ UrlManager.replaceHostManager( host); }else{ UrlManager.replaceHostManager( "release"); }
-
到这里改成已将开发完毕了,还需要在调整下,如果是线上生产环境,那么就不能切换APP环境,我们可以利用gradlew中添加想对应的buildConfigField来实现,就是个boolean变量具体做法如下:
defaultConfig { applicationId "xxxxxxx" minSdkVersion 16 targetSdkVersion 29 versionCode 139 versionName '1.3.9' buildConfigField "boolean", "SWITCHING_ENVIRONMENT", "true"//这里是是否启用环境切换 ndk { // 设置支持的SO库架构 abiFilters 'armeabi', 'armeabi-v7a','arm64-v8a', 'x86_64' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a' } }
到这里已经全部完成,在打包生产app时只需要将Boolean改成false,然后打包就ok.在开发和测试结算将这个值置位true就好.