背景(摘自維基百科)
進程間通信(IPC扁远,Inter-Process Communication),指至少兩個進程或線程間傳送數(shù)據(jù)或信號的一些技術(shù)或方法汇在。進程是計算機系統(tǒng)分配資源的最小單位(嚴格說來是線程)煮嫌。每個進程都有自己的一部分獨立的系統(tǒng)資源,彼此是隔離的碗暗。為了能使不同的進程互相訪問資源并進行協(xié)調(diào)工作颈将,才有了進程間通信。舉一個典型的例子言疗,使用進程間通信的兩個應(yīng)用可以被分類為客戶端和服務(wù)器(見主從式架構(gòu))晴圾,客戶端進程請求數(shù)據(jù),服務(wù)端回復(fù)客戶端的數(shù)據(jù)請求噪奄。有一些應(yīng)用本身既是服務(wù)器又是客戶端死姚,這在分布式計算中人乓,時常可以見到都毒。這些進程可以運行在同一計算機上或網(wǎng)絡(luò)連接的不同計算機上色罚。
進程間通信技術(shù)包括消息傳遞、同步温鸽、共享內(nèi)存和遠程過程調(diào)用保屯。IPC是一種標準的Unix通信機制。
使用IPC 的理由:
1.信息共享:Web服務(wù)器涤垫,通過網(wǎng)頁瀏覽器使用進程間通信來共享web文件(網(wǎng)頁等)和多媒體姑尺;
2.加速:維基百科使用通過進程間通信進行交流的多服務(wù)器來滿足用戶的請求;
3.模塊化;
4.私有權(quán)分離.
與直接共享內(nèi)存地址空間的多線程編程相比蝠猬,IPC的缺點:
采用了某種形式的內(nèi)核開銷切蟋,降低了性能;
幾乎大部分IPC都不是程序設(shè)計的自然擴展,往往會大大地增加程序的復(fù)雜度榆芦。
好了下面就直接進入正題柄粹。
既然是進程間的通信那就至少有兩個程序,這里我們新建兩個工程匆绣,一個是 Client驻右,負責發(fā)送消息。一個是Server崎淳,負責接收消息堪夭。
搭建Server項目
1.新建一個AIDL文件
創(chuàng)建完AIDL文件后,細心的你會發(fā)現(xiàn)basicTypes()這么一個方法拣凹,這個方法主要是告訴你在AIDL中你可以使用的基本類型(int, long, boolean, float, double, String)森爽,可以直接刪除,然后寫自己的方法嚣镜,這里我們先寫一個簡單的例子爬迟,就直接返回一個字符串
interface IMyAidlInterface {
String getResult();
}
2.構(gòu)建項目
定義好之后,我們重新Make一下項目(Build->Make Project或者Build->Make Module 'app'都可以)菊匿,這時你就會在build中發(fā)現(xiàn)IMyAidlInterface這樣一個文件
這個是我debug版本下的付呕,如果你是release的會在release包下!跌捆!
3.建立Service
在Service里面創(chuàng)建一個內(nèi)部類凡涩,繼承你剛才創(chuàng)建的AIDL的名稱里的Stub類,并實現(xiàn)接口方法,在onBind返回內(nèi)部類的實例。
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";
}
}
}
配置服務(wù)
<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.把客戶端程序與服務(wù)連接起來
為了建立這樣的一個鏈接可款,我們需要實現(xiàn)ServiceConnection類育韩。
我們在MainActivity.java中創(chuàng)建一個內(nèi)部類 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(客戶端)連接到服務(wù)(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小程序就這樣完成啦!C小悉罕!??是不是迫不及待想試一下了呢,快快動起手去完成吧:)
總結(jié)
經(jīng)過一上午的努力終于把小例子和這篇算是記錄的文章弄完了立镶,算是自己的知識鞏固吧壁袄。
“學(xué)習如逆水行舟,不進則退”,進入這行就要不斷的學(xué)習媚媒,不斷的吸收新的東西嗜逻,真正的是活到老學(xué)到老啊,和各位共勉之g哉佟U磺辍!