背景(摘自維基百科)
進程間通信(IPC,Inter-Process Communication),指至少兩個進程或線程間傳送數據或信號的一些技術或方法。進程是計算機系統分配資源的最小單位(嚴格說來是線程)。每個進程都有自己的一部分獨立的系統資源,彼此是隔離的。為了能使不同的進程互相訪問資源并進行協調工作,才有了進程間通信。舉一個典型的例子,使用進程間通信的兩個應用可以被分類為客戶端和服務器(見主從式架構),客戶端進程請求數據,服務端回復客戶端的數據請求。有一些應用本身既是服務器又是客戶端,這在分布式計算中,時常可以見到。這些進程可以運行在同一計算機上或網絡連接的不同計算機上。
進程間通信技術包括消息傳遞、同步、共享內存和遠程過程調用。IPC是一種標準的Unix通信機制。
使用IPC 的理由:
1.信息共享:Web服務器,通過網頁瀏覽器使用進程間通信來共享web文件(網頁等)和多媒體;
2.加速:維基百科使用通過進程間通信進行交流的多服務器來滿足用戶的請求;
3.模塊化;
4.私有權分離.
與直接共享內存地址空間的多線程編程相比,IPC的缺點:
采用了某種形式的內核開銷,降低了性能;
幾乎大部分IPC都不是程序設計的自然擴展,往往會大大地增加程序的復雜度。
好了下面就直接進入正題。
既然是進程間的通信那就至少有兩個程序,這里我們新建兩個工程,一個是 Client,負責發送消息。一個是Server,負責接收消息。
搭建Server項目
1.新建一個AIDL文件
創建完AIDL文件后,細心的你會發現basicTypes()這么一個方法,這個方法主要是告訴你在AIDL中你可以使用的基本類型(int, long, boolean, float, double, String),可以直接刪除,然后寫自己的方法,這里我們先寫一個簡單的例子,就直接返回一個字符串
interface IMyAidlInterface {
String getResult();
}
2.構建項目
定義好之后,我們重新Make一下項目(Build->Make Project或者Build->Make Module 'app'都可以),這時你就會在build中發現IMyAidlInterface這樣一個文件
這個是我debug版本下的,如果你是release的會在release包下!!
3.建立Service
在Service里面創建一個內部類,繼承你剛才創建的AIDL的名稱里的Stub類,并實現接口方法,在onBind返回內部類的實例。
package co.lk.android.testserviceaidl.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import co.lk.android.testserviceaidl.IMyAidlInterface;
public class TestAidlService extends Service {
public TestAidlService() {
}
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
private class MyBinder extends IMyAidlInterface.Stub {
@Override
public String getResult() throws RemoteException {
return "testAidl";
}
}
}
配置服務
<service
android:name=".service.TestAidlService"
android:exported="true">
<intent-filter>
<action android:name="co.lk.aidl"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
搭建Client項目
1.將我們的AIDL文件拷貝到第二個項目,然后在重新Make一下項目。拷貝完如下圖:
2.把客戶端程序與服務連接起來
為了建立這樣的一個鏈接,我們需要實現ServiceConnection類。
我們在MainActivity.java中創建一個內部類 MyServiceConnection,這個類繼承ServiceConnection類,并且重寫了它的兩個方法:onServiceConnected和onServiceDisconnected。
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
Toast.makeText(MainActivity.this, "Service connected", Toast.LENGTH_LONG).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mIMyAidlInterface = null;
Toast.makeText(MainActivity.this, "Service disconnected", Toast.LENGTH_LONG).show();
}
}
3.完整的MainActivity代碼
package co.lk.android.testclientaidl;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import co.lk.android.testserviceaidl.IMyAidlInterface;
public class MainActivity extends AppCompatActivity {
private IMyAidlInterface mIMyAidlInterface;
private MyServiceConnection mConnection;
private TextView mResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initService();
initView();
}
private void initView() {
Button buttonCalc = (Button) findViewById(R.id.bt_get);
mResult = (TextView) findViewById(R.id.tv_result);
buttonCalc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String res = "";
try {
res = mIMyAidlInterface.getResult();
} catch (RemoteException e) {
e.printStackTrace();
}
mResult.setText(res);
}
});
}
/*
這個方法使Activity(客戶端)連接到服務(service)
*/
private void initService() {
mConnection = new MyServiceConnection();
Intent intent = new Intent();
intent.setAction("co.lk.aidl");
intent.setPackage("co.lk.android.testserviceaidl");
bindService(intent, mConnection, BIND_AUTO_CREATE);
}
private void releaseService() {
unbindService(mConnection);
mConnection = null;
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseService();
}
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
Toast.makeText(MainActivity.this, "Service connected", Toast.LENGTH_LONG).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mIMyAidlInterface = null;
Toast.makeText(MainActivity.this, "Service disconnected", Toast.LENGTH_LONG).show();
}
}
}
就這樣一個簡單的AIDL小程序就這樣完成啦!!!??是不是迫不及待想試一下了呢,快快動起手去完成吧:)
總結
經過一上午的努力終于把小例子和這篇算是記錄的文章弄完了,算是自己的知識鞏固吧。
“學習如逆水行舟,不進則退”,進入這行就要不斷的學習,不斷的吸收新的東西,真正的是活到老學到老啊,和各位共勉之!!!