第十八周:AIDL使用及其異步操作

一、Android中AIDL的作用是什么?

用于Android跨進程通信

二、它所支持的參數(shù)類型是?

1、所有的Java基本數(shù)據(jù)類型,比如int,long,boolean,char,float等。

2、String

3、CharSequence

4、List,List當中的數(shù)據(jù)元素必須能夠被AIDL支持

5、Map:只支持HashMap,里面的每個元素都必須被AIDL支持,包括key和value

6、Parcelable:實現(xiàn)了Parcelable接口的對象

7、AIDL接口:所有的AIDL接口本身也可以在AIDL文件中使用。

三、默認情況下AIDL的調(diào)用過程是同步還是異步?如何指定AIDL為異步調(diào)用?

默認情況時同步調(diào)用。所以客戶端調(diào)用服務(wù)端的耗時操作時會報ANR,反之同理。
1、自行實現(xiàn)多線程
當服務(wù)端(客戶端)需要做耗時操作時,手動開啟線程或利用線程池等做異步操作。
2、利用oneway關(guān)鍵字實現(xiàn)
當使用oneway的時候,遠程調(diào)用不會阻塞,會立即返回。
與手動實現(xiàn)的區(qū)別就是oneway調(diào)用遠程后立刻返回,不會管遠程具體實現(xiàn)。而前者會進入遠程方法。下面我們來寫一個demo理解。

為了簡化代碼,activity代碼就貼一下點擊事件,service也只貼binder部分了,由于kotlin老是忘,所以現(xiàn)在寫demo一般都用kotlin,代碼比較簡單相信大家能看明白

activity:

override fun onClick(v: View?) {
    when (v?.id) {
        R.id.get_connect -> {
            val mIntent = Intent(this, AService::class.java)
            bindService(mIntent, connection, Context.BIND_AUTO_CREATE)
        }

        R.id.do_thing -> {
            Log.e("test", "client click")
            binder?.longTimeAction()
        }
    }
}

service:

val test = object : ITestInterface.Stub() {
    override fun longTimeAction() {
        Log.e("test", "threadName:" + Thread.currentThread().name)
        var j = i
        i++
        Log.e("test", "sleep_start" + j)
        Thread.sleep(10000)
        Log.e("test", "sleep_finish" + j)
    }
};

AIDL:

interface ITestInterface {

 oneway void longTimeAction();
}

首先我們嘗試oneway方式異步,我們連續(xù)點擊3次按鈕IPC通信,log如下:


點擊log
service_log

觀察log時間點,可以看出點擊是在同一時間發(fā)生的,而服務(wù)端是在binder_1這個binder線程池里單線程執(zhí)行的,所以達到了異步需求,注意這里并不是主線程哦,藝術(shù)探索里也提到了。

接下來稍微修改一下service 的代碼,把他換到自己的線程池里執(zhí)行:

lateinit var execute : ExecutorService
val test = object : ITestInterface.Stub() {
    override fun longTimeAction() {
        execute.execute{
            Log.e("test", "threadName:" + Thread.currentThread().name)
            var j = i
            i++
            Log.e("test", "sleep_start" + j)
            Thread.sleep(10000)
            Log.e("test", "sleep_finish" + j)
        }
    }
};
var i: Int = 0

override fun onCreate() {
    super.onCreate()
    execute = Executors.newFixedThreadPool(5, Executors.defaultThreadFactory())
}

log如下:


點擊_log

service_log

依舊看時間點,這個很好理解吧。
所以區(qū)別就是oneway就是交給binder線程池處理,所以還是自己處理比較靈活。
至于回調(diào)就用RemoteCallbackList啦,具體使用就看藝術(shù)探索吧,不是今天的主題,溜了溜了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容