最近发现项目的一个界面里面逻辑特别复杂,页面的层级和结构也特复杂。页面大致是有进入这个界面是看见一个夹杂动画的封面,动画开始的同时走网络,然后加载html,然后加载个底部弹幕,底部一行一行往上弹弹幕,里面包含了许多自定义的控件,最后导致页面会有点小卡顿,让人感觉很不爽,之后决定搞它。

多进程的好处:

  1. 减少OOM的发生,每个进程的资源分配是有限的,资源的占用过多就会发生OOM,开启另一个进程可以分担主进程的内存分配。
  2. 可以增加程序的运行的效率,毕竟进程多了可以分摊主进程的工作。
  3. 可以减少程序的崩溃,增强用户体验,子进程崩溃了,并不会影响主进程。
  4. 可以利用这种特殊的机制来进行双进程的守护,一些消息的发送,让我们在后台仍能收到消息。所谓的双进程守护就行,子进程与主进程之间的相互监控,由一方被关闭就会被另一方重启。

当然了,这玩意也不能乱用,也需要注意很多的东西。

多进程开发需要注意的东西:

下面就举个例子如何开启一个子进程:

首先先在清单文件中添加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"就好。

多进程基本使用大致就是这些了,多进程使用还是比较简单的,若有错误请指正。