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 进入调试。

相关推荐
baidu_2474386119 小时前
Android ViewModel定时任务
android·开发语言·javascript
有位神秘人20 小时前
Android中Notification的使用详解
android·java·javascript
·云扬·20 小时前
MySQL Binlog落盘机制深度解析:性能与安全性的平衡艺术
android·mysql·adb
独自破碎E21 小时前
【BISHI9】田忌赛马
android·java·开发语言
代码s贝多芬的音符1 天前
android 两个人脸对比 mlkit
android
darkb1rd1 天前
五、PHP类型转换与类型安全
android·安全·php
gjxDaniel1 天前
Kotlin编程语言入门与常见问题
android·开发语言·kotlin
csj501 天前
安卓基础之《(22)—高级控件(4)碎片Fragment》
android
峥嵘life1 天前
Android16 【CTS】CtsMediaCodecTestCases等一些列Media测试存在Failed项
android·linux·学习
stevenzqzq1 天前
Compose 中的状态可变性体系
android·compose