Application 优化
下面附上我的 Application
的代码
public class App extends Application { private static Context context; private static String sCurProcessName = null; private String processName; private String packageName; /** * Set the base context for this ContextWrapper. All calls will then be * delegated to the base context. Throws * IllegalStateException if a base context has already been set. * * @param base The new base context for this wrapper. */ @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); processName = getCurProcessName(base); packageName = getPackageName(); } private boolean isMainProcess() { return !TextUtils.isEmpty(packageName) && TextUtils.equals(packageName, processName); } @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); if (isMainProcess()){ MMKV.initialize(this); MMKV.mmkvWithID("MyID", MMKV.SINGLE_PROCESS_MODE, GlobalConstant.MMKV_KEY); //载入Dokit监测 new DoKit.Builder(this) .productId(context.getString(R.string.value_dokit_pid)) .build(); //使用订阅索引,加快编译速度 EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus(); // 抖音授权 String clientkey = context.getString(R.string.value_client_key); DouYinOpenApiFactory.init(new DouYinOpenConfig(clientkey)); //初始化 MyUtil.initialize(this); //设置UI工具 RxTool.init(this); //网络缓存 RetrofitCache.getInstance().init(this); }else { QbSdk.initX5Environment(getContext(), new QbSdk.PreInitCallback() { @Override public void onCoreInitFinished() { // 内核初始化完成,可能为系统内核,也可能为系统内核 } /** * 预初始化结束 * 由于X5内核体积较大,需要依赖网络动态下发,所以当内核不存在的时候,默认会回调false,此时将会使用系统内核代替 * @param isX5 是否使用X5内核 */ @Override public void onViewInitFinished(boolean isX5) { LogUtil.i("是否使用腾讯内核:" + isX5); } }); } //设置打印开关 LogUtil.setIsLog(true); //注册Activity生命周期 registerActivityLifecycleCallbacks(ActivityUtil.getActivityLifecycleCallbacks()); } public static Context getContext() { return context; } private static String getCurProcessName(Context context) { if (!TextUtils.isEmpty(sCurProcessName)) { return sCurProcessName; } sCurProcessName = getProcessName(android.os.Process.myPid()); if (!TextUtils.isEmpty(sCurProcessName)) { return sCurProcessName; } try { int pid = android.os.Process.myPid(); sCurProcessName = getProcessName(pid); if (!TextUtils.isEmpty(sCurProcessName)) { return sCurProcessName; } //获取系统的ActivityManager服务 ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); if (am == null) { return sCurProcessName; } for (ActivityManager.RunningAppProcessInfo appProcess : am.getRunningAppProcesses()) { if (appProcess.pid == pid) { sCurProcessName = appProcess.processName; break; } } } catch (Exception e) { e.printStackTrace(); } return sCurProcessName; } private static String getProcessName(int pid) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline")); String processName = reader.readLine(); if (!TextUtils.isEmpty(processName)) { processName = processName.trim(); } return processName; } catch (Throwable throwable) { throwable.printStackTrace(); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } } 复制代码
在 Application 中,我对当前进程进行判断,在对应的进程中才加载对应的资源,避免资源的过度加载
进程的预加载
对应多进程中,我们进行一个预加载,可以让APP需要启用到这个进程的时候,检测到有对应的进程已经创建了,就不会再次重新启用这个进程了,这样子就和打开一个普通的 Activity
的界面速度是一样的了。
进程预加载,我们需要使用到不可的服务或者广播,只需要将其绑定在同一个进程中,且对应服务为空即可。
<!--AndroidManifest.xml--> <activity android:name=".module.mine.activity.WebViewActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:exported="false" android:process=":h5" android:screenOrientation="portrait" android:theme="@style/BlackTheme" /> <service android:name=".module.mine.service.PreLoadService" android:process=":h5" android:enabled="true" android:exported="false" > </service> 复制代码
public class PreLoadService extends Service { public PreLoadService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } } 复制代码
//在对应的生命周期启用即可 private void startHideService(){ Intent intent = new Intent(this, PreLoadService.class); this.startService(intent); } private void stopHideService(){ Intent intent = new Intent(this, PreLoadService.class); this.stopService(intent); } 复制代码
WebView启动白屏
关于启动页白屏问题,和 初次启动白屏 的解决方案一致,我们设置这个Activity的背景为黑色,与抖音页面的背景一个颜色即可。
同时,我们需要注意的是,WebView
的背景也请记得设置为黑色