欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

android通訊,android通訊錄論文

Android通信方式篇(七)-Binder機(jī)制(Native層(下))

本篇文章針對(duì)向ServiceManager注冊(cè)服務(wù) 和 獲取服務(wù)兩個(gè)流程來(lái)做總結(jié)。在這兩個(gè)過(guò)程中,ServiceManager都扮演的是服務(wù)端,與客戶端之間的通信也是通過(guò)Binder IPC。

我們提供的服務(wù)有:成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、華寧ssl等。為成百上千企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的華寧網(wǎng)站制作公司

在此之前先了解下Binder的進(jìn)程與線程的關(guān)系:

用戶空間 :ProcessState描述一個(gè)進(jìn)程,IPCThreadState對(duì)應(yīng)一個(gè)進(jìn)程中的一個(gè)線程。

內(nèi)核空間 :binder_proc描述一個(gè)進(jìn)程,統(tǒng)一由binder_procs全局鏈表保存,binder_thread對(duì)應(yīng)進(jìn)程的一個(gè)線程。

ProcessState與binder_proc是一一對(duì)應(yīng)的。

Binder線程池 :每個(gè)Server進(jìn)程在啟動(dòng)時(shí)會(huì)創(chuàng)建一個(gè)binder線程池,并向其中注冊(cè)一個(gè)Binder線程;之后Server進(jìn)程也可以向binder線程池注冊(cè)新的線程,或者Binder驅(qū)動(dòng)在探測(cè)到?jīng)]有空閑binder線程時(shí)會(huì)主動(dòng)向Server進(jìn)程注冊(cè)新的的binder線程。對(duì)于一個(gè)Server進(jìn)程有一個(gè)最大Binder線程數(shù)限制15,(#define DEFAULT_MAX_BINDER_THREADS 15)。對(duì)于所有Client端進(jìn)程的binder請(qǐng)求都是交由Server端進(jìn)程的binder線程來(lái)處理的。我的理解是:binder線程是進(jìn)程進(jìn)行binder ipc時(shí)的一條數(shù)據(jù)處理路徑。

MediaPlayerService向ServiceManager注冊(cè)過(guò)程如下:

相關(guān)類:

整個(gè)過(guò)程總結(jié)如下:

1 獲取BpServiceManager 與 BpBinder

由defaultServiceManager()返回的是BpServiceManager,同時(shí)會(huì)創(chuàng)建ProcessState對(duì)象和BpBinder對(duì)象。然后通過(guò)BpBinder執(zhí)行transact,把真正工作交給IPCThreadState來(lái)處理。

2 BpBinder transact

Binder代理類調(diào)用transact()方法,真正工作還是交給IPCThreadState來(lái)進(jìn)行transact工作。

3 通過(guò)IPCThreadState 包裝并轉(zhuǎn)換數(shù)據(jù)并進(jìn)行transact事務(wù)處理

每個(gè)線程都有一個(gè)IPCThreadState,每個(gè)IPCThreadState中都有一對(duì)Parcel變量:mIn、mOut。相當(dāng)于兩根數(shù)據(jù)管道:

最后執(zhí)行talkWithDriver。

writeTransactionData:將BC Protocol + binder_transaction_data結(jié)構(gòu)體 寫入mOut, 然后執(zhí)行waitForResponse:

由talkWithDriver將數(shù)據(jù)進(jìn)一步封裝到binder_write_read結(jié)構(gòu)體,通過(guò)ioctl(BINDER_WRITE_READ)與驅(qū)動(dòng)通信。同時(shí)等待驅(qū)動(dòng)返回的接收BR命令,從mIn取出返回的數(shù)據(jù)。

mIn包裝的數(shù)據(jù)結(jié)構(gòu)(注冊(cè)服務(wù)handle = 0 ,code 為ADD_SERVICE_TRANSACTION):

4 Binder Driver

把binder_write_read結(jié)構(gòu)體write_buffer里數(shù)據(jù)取出來(lái),分別得到BC命令和封裝好數(shù)據(jù)的事務(wù)binder_transaction_data, 然后根據(jù)handler,在當(dāng)前binder_proc中,找到相應(yīng)的binder_ref,由binder_ref再找到目標(biāo)binder_node實(shí)體,由目標(biāo)binder_node再找到目標(biāo)進(jìn)程binder_proc。然后就是插入數(shù)據(jù):當(dāng)binder驅(qū)動(dòng)可以找到合適的線程,就會(huì)把binder_transaction節(jié)點(diǎn)插入到servciemanager的線程的todo隊(duì)列中,如果找不到合適的線程,就把節(jié)點(diǎn)之間插入servciemanager的binder_proc的todo隊(duì)列。

5 ServiceManager

經(jīng)過(guò)Binder Driver的處理,數(shù)據(jù)已經(jīng)到了ServiceManager進(jìn)程,在BR_TRANSACTION的引導(dǎo)下,在binder_loop()中執(zhí)行binder_parser()取出數(shù)據(jù),執(zhí)行do_add_service()操作,最終向 svcinfo 列表中添加已經(jīng)注冊(cè)的服務(wù)(沒(méi)有數(shù)據(jù)的返回)。最后發(fā)送 BR_REPLY 命令喚醒等待的線程,通知注冊(cè)成功。結(jié)束MediaPlayerService進(jìn)程 waitForResponse()的狀態(tài),整個(gè)注冊(cè)過(guò)程結(jié)束。

獲取服務(wù)的過(guò)程與注冊(cè)類似,首先 ServiceManager 向 Binder 驅(qū)動(dòng)發(fā)送 BC_TRANSACTION 命令攜帶 CHECK_SERVICE_TRANSACTION 命令,同時(shí)獲取服務(wù)的線程進(jìn)入等待狀態(tài) waitForResponse()。Binder 驅(qū)動(dòng)收到請(qǐng)求命令向 ServiceManager 的發(fā)送 BC_TRANSACTION 查詢已注冊(cè)的服務(wù),會(huì)區(qū)分請(qǐng)求服務(wù)所屬進(jìn)程情況。

查詢到直接響應(yīng) BR_REPLY 喚醒等待的線程。若查詢不到將與 binder_procs 鏈表中的服務(wù)進(jìn)行一次通訊再響應(yīng)。

以startService為例來(lái)簡(jiǎn)單總結(jié)下執(zhí)行流程:

3.1 從方法執(zhí)行流程來(lái)看:

Client :

1 AMP.startService 標(biāo)記方法以及通過(guò)Parcel包裝數(shù)據(jù);

2 BinderProxy.transact 實(shí)際調(diào)用native的 android_os_BinderProxy_transact 傳遞數(shù)據(jù);

3 獲取BpServiceManager 與 BpBinder 同時(shí)會(huì)創(chuàng)建ProcessState。然后通過(guò)BpBinder執(zhí)行transact,把真正工作交給IPCThreadState來(lái)處理;

4 IPC.transact 主要執(zhí)行writeTransactionData,將上層傳來(lái)的數(shù)據(jù)重新包裝成binder_transaction_data,并將BC Protocol + binder_transaction_data結(jié)構(gòu)體 寫入mOut;

5 IPC waitForResponse talkWithDriver + 等待返回?cái)?shù)據(jù);

6 talkWithDriver 將數(shù)據(jù)進(jìn)一步封裝成binder_write_read,通過(guò)ioctl(BINDER_WRITE_READ)與驅(qū)動(dòng)通信;

Kernel :

7 binder ioctl 接收BINDER_WRITE_READ ioctl命令;

8 binder_ioctl_write_read 把用戶空間數(shù)據(jù)ubuf拷貝到內(nèi)核空間bwr;

9 binder_thread_write 當(dāng)bwr寫緩存有數(shù)據(jù),則執(zhí)行binder_thread_write;當(dāng)寫失敗則將bwr數(shù)據(jù)寫回用戶空間并退出;

10 binder_transaction 找到目標(biāo)進(jìn)程binder_proc并插入數(shù)據(jù)到目標(biāo)進(jìn)程的線程todo隊(duì)列,最終執(zhí)行到它

時(shí),將發(fā)起端數(shù)據(jù)拷貝到接收端進(jìn)程的buffer結(jié)構(gòu)體;

11 binder_thread_read 根據(jù)binder_transaction結(jié)構(gòu)體和binder_buffer結(jié)構(gòu)體數(shù)據(jù)生成新的binder_transaction_data結(jié)構(gòu)體,寫入bwr的read_buffer,當(dāng)bwr讀緩存有數(shù)據(jù),則執(zhí)行binder_thread_read;當(dāng)讀失敗則再將bwr數(shù)據(jù)寫回用戶空間并退出;最后,把內(nèi)核數(shù)據(jù)bwr拷貝到用戶空間ubuf。

12 binder_thread_write + binder_ioctl BR命令和數(shù)據(jù)傳遞

Server:

13 IPC.executeCommand 解析kernel傳過(guò)來(lái)的binder_transaction_data數(shù)據(jù),找到目標(biāo)BBinder并調(diào)用其transact()方法;

14 IPC.joinThreadPool 采用循環(huán)不斷地執(zhí)行g(shù)etAndExecuteCommand()方法, 處理事務(wù)。當(dāng)bwr的讀寫buffer都沒(méi)有數(shù)據(jù)時(shí),則阻塞在binder_thread_read的wait_event過(guò)程. 另外,正常情況下binder線程一旦創(chuàng)建則不會(huì)退出.

15 BBinder.transact 到Binder.exeTransact 調(diào)用 AMN.onTransact

16 AMN.onTransact 把數(shù)據(jù)傳遞到AMS.starService去執(zhí)行

17 AMS.starService Server處理了Client的請(qǐng)求了

然后原路replay回去,talkWithDriver 到Kernel ,然后找到Client進(jìn)程,把數(shù)據(jù)拷貝到read_buffer里,最終喚醒IPC,把反饋傳遞回AMP.startService。完成啟動(dòng)服務(wù)。

3.2 從通信協(xié)議流程來(lái)看:

非oneWay:

oneway:

oneway與非oneway區(qū)別: 都是需要等待Binder Driver的回應(yīng)消息BR_TRANSACTION_COMPLETE. 主要區(qū)別在于oneway的通信收到BR_TRANSACTION_COMPLETE則返回,而不會(huì)再等待BR_REPLY消息的到來(lái). 另外,oneway的binder IPC則接收端無(wú)法獲取對(duì)方的pid.

3.3 從數(shù)據(jù)流來(lái)看

從用戶空間開(kāi)始:

進(jìn)入驅(qū)動(dòng)后:

回到用戶空間:

參考:

android手機(jī)通訊錄以及通話記錄在哪個(gè)文件夾?

在內(nèi)部存儲(chǔ)卡的的data/com.android.provides.contacts里面。

以三星的s8為例

找到通訊錄以及通話記錄方法:

1、打開(kāi)三星的s8手機(jī),在系統(tǒng)界面找到“我的文件”。

2、進(jìn)入到三星的s8手機(jī)“我的文件”里面找到“內(nèi)部存儲(chǔ)”點(diǎn)擊進(jìn)入。

3、進(jìn)入“內(nèi)部存儲(chǔ)”下翻,在列表中找到“data”文件夾,點(diǎn)擊打開(kāi)。

4、進(jìn)入“data”文件夾后找到“com.android.provides.contacts”文件夾,點(diǎn)擊打開(kāi)。

5、在“com.android.provides.contacts”文件夾里面,把CSV文件導(dǎo)出,就可以看到通訊錄文件了。

Android串口通訊

1.打開(kāi)串口。

2.串口處于監(jiān)聽(tīng)狀態(tài)

3.想串口寫入數(shù)據(jù),串口接收到數(shù)據(jù)返回?cái)?shù)據(jù)

SerialPort類所在的包一定要和上圖包名一直,因?yàn)榇谕ㄓ嵭枰褂胘ni中的函數(shù)。

package android_serialport_api;

import java.io.File;

import java.io.FileDescriptor;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import com.fx.serialporttest.L;

public class SerialPort {

/*

* Do not remove or rename the field mFd: it is used by native method

* close();

*/

private FileDescriptor mFd;

private FileInputStream mFileInputStream;

private FileOutputStream mFileOutputStream;

/**

* 構(gòu)造方法

* @param device 串口地址

* @param baurate 波特率

* @param flags

* @throws IOException

* @throws InterruptedException

*/

public SerialPort(File device,int baudrate,int flags) {

/*

* 檢測(cè)是否有訪問(wèn)權(quán)限

*/

if(!device.canRead()||!device.canWrite()){

//如果沒(méi)有讀寫權(quán)限,嘗試chmod命令這個(gè)文件

L.tag("沒(méi)有讀寫權(quán)限");

Process su;

try {

su = Runtime.getRuntime().exec("/system/bin/su");//獲取root讀寫權(quán)限

String cmd = "chmod 777"+device.getAbsolutePath()+"\n"+"exit\n";

su.getOutputStream().write(cmd.getBytes()); //向此路徑文件寫入命令

if((su.waitFor()!=0||!device.canRead()||!device.canWrite())){

throw new SecurityException();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

mFd = open(device.getAbsolutePath(),baudrate,flags);

if(mFd==null){

mFd = open(device.getAbsolutePath(),baudrate,flags);

L.tag("native open return null");

}

mFileInputStream = new FileInputStream(mFd);

mFileOutputStream = new FileOutputStream(mFd);

}

public FileInputStream getmFileInputStream() {

return mFileInputStream;

}

public void setmFileInputStream(FileInputStream mFileInputStream) {

this.mFileInputStream = mFileInputStream;

}

public FileOutputStream getmFileOutputStream() {

return mFileOutputStream;

}

public void setmFileOutputStream(FileOutputStream mFileOutputStream) {

this.mFileOutputStream = mFileOutputStream;

}

//JNI

private native static FileDescriptor open(String path,int baudrate,int flags);

public native void close();

static {

System.loadLibrary("serial_port");

}

}

package android_serialport_api;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import com.fx.serialporttest.L;

public? class SerialPortFinger {

private static ReadThread readThread;

private static FileInputStream mFileInputStream;

private static FileOutputStream mFileOutputStream;

static String path = "/dev/ttyS0";//設(shè)備主板的串口地址,地址有所不同

public? void startListener(){

SerialPort serialPort = new SerialPort(new File(path), 9600, 0);//9600是波特率,這個(gè)也是有所不同,具體要看設(shè)備

mFileInputStream = serialPort.getmFileInputStream();

mFileOutputStream = serialPort.getmFileOutputStream();//獲取串口寫入流

readThread? = new ReadThread();

readThread.start();//開(kāi)啟監(jiān)聽(tīng)

}

/**

* 發(fā)送指令到串口

*

* @param cmd

* @return

*/

public boolean sendCmds(String cmd) {

boolean result = true;

byte[] mBuffer = (cmd+"\r\n").getBytes();

try {

if (mFileOutputStream != null) {

mFileOutputStream.write(mBuffer);

} else {

result = false;

}

} catch (IOException e) {

e.printStackTrace();

result = false;

}

return result;

}

static class ReadThread extends Thread{

@Override

public void run() {

// TODO Auto-generated method stub

super.run();

int len;

StringBuffer sb = new StringBuffer("");

while(true){ //循環(huán)監(jiān)聽(tīng)串口,讀取返回的數(shù)據(jù)

byte[] buffer = new byte[1024];

if(mFileInputStream==null){

return;

}

try {

len = mFileInputStream.read(buffer);

if(len0){

sb.append(new String(buffer, 0, len));

}

if(!sb.toString().equals(""))

{

L.tag(sb.toString());//收到串口的返回?cái)?shù)據(jù),在日志中打印出來(lái)

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

L.tag("接受完成");

}

}

}

}

當(dāng)前名稱:android通訊,android通訊錄論文
網(wǎng)站鏈接:http://chinadenli.net/article25/dsgpcji.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航軟件開(kāi)發(fā)品牌網(wǎng)站建設(shè)面包屑導(dǎo)航建站公司服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司