代碼在評論中。 JNI: 為什麼需要JNI: 因為android是由【JAVA & C/C++】組成。Java運行在Dalvik虛擬機中。 沒有辦法直接訪問底層硬體。底層HW相關目前技術一般都用C語言,不會用java,C速度也比較快。 怎麼從JAVA語言傳送數據到C語言中: 1. java中會調用n
代碼在評論中。
JNI:
為什麼需要JNI:
因為android是由【JAVA & C/C++】組成。Java運行在Dalvik虛擬機中。
沒有辦法直接訪問底層硬體。底層HW相關目前技術一般都用C語言,不會用java,C速度也比較快。
怎麼從JAVA語言傳送數據到C語言中:
1. java中會調用native標識的函數,這個函數就是經典了。
2.當然這些native的函數怎麼調用,就得載入一個提供C函數包,叫共用庫(ex:libNewJNI.so)
3.問題來了,這.so文件怎麼來的? 從一下兩個文件編譯後產生的(.h & .c/cpp),當然Android.mk中設置編譯選項樓。
4.完成了,很簡單吧。
AIDL:
為什麼需要AIDL:
AIDL機制就是處理客戶端和服務端的通信,通過AIDL機制,客戶端通過調用服務端提供的介面便於跨進程調用其他應用程式.
Service分為本地服務和遠程服務,遠程服務就一定要用到AIDL技術實現,因為android的不同應用是在不同的進程中運行的,
也是彼此獨立的,如果在一個應用中訪問另一個應用,也就是調用遠程服務,就要把服務端定義的AIDL文件放到客戶端,
這樣才可以實現遠程服務調用。
怎麼從一個進程調動另一個進程:
1.首先AIDL代碼是?
很簡單,尾碼名僅僅是.aidl,內容就是interface class。
2.怎麼用AIDL?
也簡單,就是編譯後aidl文件就變成了,*.java文件
打開文件看的話,你又明白了,是一個Binder
static abstract class Stub extends android.os.Binder implements android.com.personservice.IPerson
3.客戶端怎麼調用這個Stub(調用server傳來的數據)
private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName arg0) { } // 因為有可能有多個應用同時進行RPC操作,所以同步該方法 @Override public synchronized void onServiceConnected(ComponentName arg0, IBinder binder) { // 獲得IPerson介面 person = IPerson.Stub.asInterface(binder); if (person != null) { try { // RPC方法調用 String name = person.getName(); Toast.makeText(MainActivity.this, "遠程進程調用成功!值為 : " + name, Toast.LENGTH_LONG).show(); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "遠程進程調用失敗! ", Toast.LENGTH_LONG).show(); } } } };
4.服務端和客戶端都必須有相同名字aidl文件嗎?
當然,客戶端包含的interface比服務端少是可以的,
因為服務端是提供interface的,所以必須包含客戶端請求的interface。
5.服務端比客戶端多的是什麼?
1) AIDL中的interface 函數
2) 實現類,實現aidl生成的抽象類(aidl編譯生成的java)
3) 還有一個service類。
6.服務端怎麼賦值給客戶端?
private ServiceConnection conn = new ServiceConnection() { // 斷開連接時調用 @Override public void onServiceDisconnected(ComponentName arg0) { } // 連接時調用 @Override public void onServiceConnected(ComponentName arg0, IBinder binder) { iPerson = IPerson.Stub.asInterface(binder); if (iPerson != null) { try { iPerson.setName("My name is 'Server AIDL'"); Toast.makeText(MainActivity.this, "賦值成功!", Toast.LENGTH_LONG).show(); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "賦值失敗!", Toast.LENGTH_LONG).show(); } } } };
7.這些IPerson的實現是什麼?
與一般的實現抽象類一樣。
public class PersonImpl extends IPerson.Stub { private String name; @Override public String getName() throws RemoteException { return name; } @Override public void setName(String name) throws RemoteException { this.name = name; } }
8. service是?
直接return那個實現類
public class MyService extends Service { private Stub iPerson = new PersonImpl(); @Override public IBinder onBind(Intent arg0) { Log.i("service", "onBind..."); return iPerson; } }