最近发现项目的一个界面里面逻辑特别复杂,页面的层级和结构也特复杂。页面大致是有进入这个界面是看见一个夹杂动画的封面,动画开始的同时走网络,然后加载html,然后加载个底部弹幕,底部一行一行往上弹弹幕,里面包含了许多自定义的控件,最后导致页面会有点小卡顿,让人感觉很不爽,之后决定搞它。
多进程的好处:
- 减少OOM的发生,每个进程的资源分配是有限的,资源的占用过多就会发生OOM,开启另一个进程可以分担主进程的内存分配。
- 可以增加程序的运行的效率,毕竟进程多了可以分摊主进程的工作。
- 可以减少程序的崩溃,增强用户体验,子进程崩溃了,并不会影响主进程。
- 可以利用这种特殊的机制来进行双进程的守护,一些消息的发送,让我们在后台仍能收到消息。所谓的双进程守护就行,子进程与主进程之间的相互监控,由一方被关闭就会被另一方重启。
当然了,这玩意也不能乱用,也需要注意很多的东西。
多进程开发需要注意的东西:
- 不能实现完全退出所有Activity的功能;
- 增加手机系统的负担,可能会导致手机变慢、变卡、提升手机耗电量。
- 首次进入新启动进程的页面时会有延时的现象(有可能黑屏、白屏几秒,是白屏还是黑屏和新Activity的主题有关);
- 应用内多进程时,Application实例化多次,需要考虑各个模块是否都需要在所有进程中初始化;
- 多进程间通过SharedPreferences共享数据时不稳定,虽然官方给出了可以在多进程之间进行数据的共享,但是官方已经不推荐,应当禁止这么做。
- 断点调试,也要根据具体的进程和逻辑进行调试,要选择正确的进程才能调试。
下面就举个例子如何开启一个子进程:
首先先在清单文件中添加Service:
<service android:name=".service.ProcessService"
android:enabled="true"
android:exported="false"
android:process=":html"/>
这里面值得注意的是android:process=":html"这行代码指为Service设置了一个进程,前面的冒号代表的是自由进程,不加冒号是全局进程。看情况使用,通常使用的都是私有进程,慎用全局进程。
在Application类中的onCreate方法设置根据包名来分别初始化不同的进程:
@Override
public void onCreate() {
super.onCreate();
mPackAgeName = getPackageName();
String curProgressName = AppUtil.getCurProcessName(this);
if (TextUtils.equals(curProgressName, mPackAgeName)) {
initMain();
} else if (TextUtils.equals(curProgressName, mPackAgeName + ":html")) {
initHtmlProcess();
}
}
在getCurProcessName方法中:
public static String getCurProcessName(Context context) {
int pid = android.os.Process.myPid();
ActivityManager mActivityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> processes = mActivityManager.getRunningAppProcesses();
if (!DataTypeUtils.isEmpty(processes)) {
for (ActivityManager.RunningAppProcessInfo appProcess : processes) {
if (appProcess.pid == pid) {
return appProcess.processName;
}
}
}
return null;
}
在initMain方法中开启服务:
private void initMain() {
//初始化主进程
...
//开启子进程Service
Intent intent = new Intent(this, ProcessService.class);
startService(intent);
}
private void initHtmlProcess(){
//初始化HTMLProcess
...
}
ProcessService:
public class StubService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
//在退出Service的同时也结束这个进程 Process.killProcess(Process.myPid());
System.exit(0);
}
}
要在合适的时机调用stopService()来结束ProcessService服务。
最后在什么地方使用到就在什么地方就在清单文件添加android:process=":html"就好。
多进程基本使用大致就是这些了,多进程使用还是比较简单的,若有错误请指正。