Android中使用socket使底層和framework通信的實(shí)現(xiàn)方法
一般的native和framework的通信是通過(guò)jni,但是這一般只是framework調(diào)用native,native如果有消息要怎樣通知上層 呢?android中GSP模塊提供一種解決思路,但是實(shí)現(xiàn)有些復(fù)雜,這里介紹一種使用socket通信的方法可以使native和framework自 由通信,具體實(shí)現(xiàn)如下:
android中使用jni對(duì)linux中的socket進(jìn)行了封裝。使用起來(lái)十分的方便。
由于android是基于linux的,所以linux的代碼會(huì)在java之前先執(zhí)行,所以一般native端是服務(wù)器。framework端是客戶端。
java層主要代碼:
view sourceprint? LocalSocket s =null; LocalSocketAddress l; s = new LocalSocket(); l = new LocalSocketAddress(SOCKET_NAME,LocalSocketAddress.Namespace.RESERVED); s.connect(l);
到此時(shí)如果socket連接沒(méi)有問(wèn)題,就可以像正常的讀寫(xiě)了。
native層主要代碼:
view sourceprint? s_fdListen = android_get_control_socket(SOCKET_NAME); ret = listen(s_fdListen, n); s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
如果連接沒(méi)有問(wèn)題就可以使用linux中的write/read來(lái)對(duì)socket進(jìn)行讀和寫(xiě)了;
這里有必要解釋一下SOCKET_NAME,它的值是一個(gè)字符串,它在init.rc中定義的一個(gè)字符串。也就是說(shuō),我們可以通過(guò)修改init.rc中來(lái)申請(qǐng)我們需要的socket資源。
這里以ril為例來(lái)說(shuō)明:
service ril-daemon /system/bin/rild socket rild stream 660 root radio socket rild-debug stream 660 radio system user root group radio cache inet misc audio
以上是摘自android 2.2 源碼中的system\core\rootdir\init.rc中的片段。至于其具體含義可以參見(jiàn)init.c和system/core/init /readme.txt文件。他的作用是由init.c來(lái)解析init.rc,并為我們啟動(dòng)一個(gè)名為rild的守護(hù)進(jìn)程,它是一個(gè)可執(zhí)行程序,我們通過(guò) adb shell在system/bin中可以找到對(duì)應(yīng)的rild文件。socket表示為這個(gè)守護(hù)進(jìn)程分配一個(gè)socket資源,這個(gè)socket資源可以在 /dev/socket/下找到rild。也就是本文要這里最關(guān)鍵的地方,socket能不能通就看守護(hù)進(jìn)程能不能很好的起來(lái)。上面 SOCKET_NAME也就是這里定義的字符串(在ril.java和ril.cpp中就有一個(gè)字符串常量SOCKET_NAME_RIL,他的值就是 rild,和上面的對(duì)應(yīng))。
如果我們要自定義一個(gè)socket來(lái)進(jìn)行通信,我們可以在init.rc的最后面加上
service myserver-daemon /system/bin/server socket server stream 666 oneshot
system/bin/server就是我們編譯生成的服務(wù)器程序,在里面我們調(diào)用
s_fdListen = android_get_control_socket(“server”); ret = listen(s_fdListen, n); s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
就可以建立一個(gè)服務(wù)器端程序。
java只需要使用最上面的代碼就可以和native通信了,注意SOCKET_NAME值必須上下統(tǒng)一和init.rc中的相等,此處為“rild”。這里的oneshot必須有,沒(méi)有的話,你的server很可能起不來(lái)。
剩下的只剩下編譯了。
關(guān)于編譯可以參考ril中的中的Android.mk和rild.c和ril.cpp,自己把頭文件挑出即可。
先用mm編譯自己加的模塊,編譯好后,將添加的模塊考出,在源碼的根目錄下make snod。將編譯輸出文件加到system.img中。最后將system.img和randisk.img拷到sdk對(duì)應(yīng)的平臺(tái)中。即可。主要這兩個(gè) img文件都要拷,system.img中有你的可執(zhí)行程序,而randisk.img中有你的init.rc。userdata.img不確定。
此時(shí)只需要用java寫(xiě)一個(gè)客戶端程序即可。
以上所述是小編給大家介紹的Android中使用socket使底層和framework通信的實(shí)現(xiàn)方法 ,實(shí)現(xiàn)一個(gè)模擬后臺(tái)數(shù)據(jù)登入的效果,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Android提高之MediaPlayer播放網(wǎng)絡(luò)音頻的實(shí)現(xiàn)方法
這篇文章主要介紹了Android的MediaPlayer播放網(wǎng)絡(luò)音頻的實(shí)現(xiàn)方法,很實(shí)用的功能,需要的朋友可以參考下2014-08-08Android實(shí)現(xiàn)仿慕課網(wǎng)下拉加載動(dòng)畫(huà)
這篇文章是我在做動(dòng)畫(huà)的項(xiàng)目中整理出來(lái)的,在eoe看了篇帖子,然后仿慕課網(wǎng)做了一個(gè)下拉加載動(dòng)畫(huà)。此功能實(shí)現(xiàn)方法是AnimationDrawable類進(jìn)行 Animation-list中item的循環(huán)遍歷圖片,類似于flash里的幀幀動(dòng)畫(huà),需要的朋友可以參考下2015-07-07Android 獲取傳感器列表整理及簡(jiǎn)單實(shí)例
這篇文章主要介紹了Android 獲取傳感器列表整理及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-06-06Android編程之頁(yè)面切換測(cè)試實(shí)例
這篇文章主要介紹了Android編程之頁(yè)面切換測(cè)試,實(shí)例分析了Android實(shí)現(xiàn)頁(yè)面點(diǎn)擊切換的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04DrawerLayout結(jié)合Tollbar實(shí)現(xiàn)菜單側(cè)滑效果
這篇文章主要為大家詳細(xì)介紹了DrawerLayout結(jié)合Tollbar實(shí)現(xiàn)菜單側(cè)滑效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12