Android中的多进程

在Android中也可以像pc一样开启多进程,这在android的编程中通常是比较少见的,以为在一个app基本上都是单进程工作就已经足够了,有一些特殊的场景,我们需要用多进程来做一些额外的工作,比如下载工作等。

在Android的AndroidManifest.xml 中,每一个activity或者service 都可以指定一个进程名称android:process,当这个activity或者service 被调用时,该进程自动启动。

因此在android中启动一个进程是比较简单的,如果需要看一个app有几个进程,看AndroidManifest.xmlandroid:process 就能知道有几个进程。

建立一个其他进程的service

这里用一个service建立其他的一个进程。RemoteService 是一个空的service。代码如下:

kotlin 复制代码
class RemoteService : Service() {

    private var TAG = "RemoteService"

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onCreate() {
        //Debug.waitForDebugger();
        super.onCreate()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return super.onStartCommand(intent, flags, startId)
    }
}

AndroidManifest.xmlandroid:process 的值取为:

android:process=":remote"

这时候,只需要在代码中启动这个服务,进程自然就建立了。

kotlin 复制代码
val serviceIntent = Intent(this, RemoteService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(serviceIntent)
            } else {
                startService(serviceIntent)
            }

可以看到 com.first66.multi_process:remote的进程已经启动了。

进程间的通讯AIDL

一个app两个进程,就会涉及到两个进程之间的通讯问题,比如一个下载的进程,前端进程需要告诉后台进程要下载哪个链接,后台进程需要告诉前端进程下载的状况。

在android中进程间的通讯可以使用AIDL进行,相当于对服务进行对象的bind

创建 IMessageInterface.aidl 的aidl,用来进行两进程间的通讯。

kotlin 复制代码
interface IMessageInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void loadData(in String message);
}

这个时候IMessageInterface 只是一个接口而已,相当于一个Binder需要进行实例化。

RemoteService.kt 中创建一个Binder,当每个对象要来绑定这个服务的时候,我们返回这个Binder给他。

kotlin 复制代码
    private var binder:Binder = object : IMessageInterface.Stub() {
        override fun loadData(message: String?) {
            message?.let {
                Log.d(TAG,it)
            }
        }
    }

绑定的时候,把这个Binder 给另一个进程。

kotlin 复制代码
    override fun onBind(intent: Intent?): IBinder? {
        return binder
    }

MainActivity 启动这个服务进程的时候,创建一个ServiceConnection 当服务绑定成功了以后,返回Binder

kotlin 复制代码
private var iMessageAidlInterface: IMessageInterface? = null

    private var serviceConnection: ServiceConnection = object  : ServiceConnection{

        override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
            iMessageAidlInterface = IMessageInterface.Stub.asInterface(p1)
            iMessageAidlInterface?.loadData("Hello Message")
        }
        override fun onServiceDisconnected(p0: ComponentName?) {
        }
    }

onServiceConnected 连接成功了以后会IBinder 返回给启动的进程,这个就能给另外一个进程传递消息了。

进程间的调试

在调试的时候,下的断点必须是在同一个进程间才能够停的住,如果是处在不同的进程,即使下了断点也是会变黑的。

可以在另外一个进程服务中onCreate 加入:

kotlin 复制代码
Debug.waitForDebugger();

当启动服务的时候,点击另外一个进程,断点才能起作用。

查看进程:

点击 com.first66.multi_process:remote 进入调试。

相关推荐
LSL666_3 小时前
5 Repository 层接口
android·运维·elasticsearch·jenkins·repository
alexhilton7 小时前
在Jetpack Compose中创建CRT屏幕效果
android·kotlin·android jetpack
2501_940094029 小时前
emu系列模拟器最新汉化版 安卓版 怀旧游戏模拟器全集附可运行游戏ROM
android·游戏·安卓·模拟器
下位子9 小时前
『OpenGL学习滤镜相机』- Day9: CameraX 基础集成
android·opengl
参宿四南河三11 小时前
Android Compose SideEffect(副作用)实例加倍详解
android·app
火柴就是我12 小时前
mmkv的 mmap 的理解
android
没有了遇见12 小时前
Android之直播宽高比和相机宽高比不支持后动态获取所支持的宽高比
android
shenshizhong12 小时前
揭开 kotlin 中协程的神秘面纱
android·kotlin
vivo高启强13 小时前
如何简单 hack agp 执行过程中的某个类
android
沐怡旸13 小时前
【底层机制】 Android ION内存分配器深度解析
android·面试