Android系統中的進程之間不能共享內存,所以,須要提供一些機制在不一樣進程之間進行數據通訊。爲了使其餘的應用程序也能夠訪問本應用程序提供的服務,Android系統採用了遠程過程調用(Remote Procedure Call,RPC)方式來實現。與不少其餘的基於RPC的解決方案同樣,Android使用一種接口定義語言(Interface Definition Language,IDL)來公開服務的接口。咱們知道4個Android應用程序組件中的3個(Activity、BroadcastReceiver和ContentProvider)均可以進行跨進程訪問,另一個Android應用程序組件Service一樣能夠。所以,能夠將這種能夠跨進程訪問的服務稱爲AIDL(Android Interface Definition Language)服務。java
Aidl文件所在的包名和文件名要相同:android
應爲用到了parcelable接口,這裏先說說它: app
Parcelable接口ide
Android中實現序列化有兩個選擇:一是實現Serializable接口(是JavaSE自己就支持的),一是實現Parcelable接口(是Android特有功能,效率比實現Serializable接口高效,可用於Intent數據傳遞,也能夠用於進程間通訊(IPC))。實現Serializable接口很是簡單,聲明一下就能夠了,而實現Parcelable接口稍微複雜一些,但效率更高,推薦用這種方法提升性能。佈局
注:Android中Intent傳遞對象有兩種方法:一是Bundle.putSerializable(Key,Object),另外一種是Bundle.putParcelable(Key,Object)。固然這些Object是有必定的條件的,前者是實現了Serializable接口,然後者是實現了Parcelable接口。性能
HarlaInfo.Java:this
package com.harlan.demo.aidl;spa
import android.os.Parcel;server
import android.os.Parcelable;對象
public class HarlanInfo implements Parcelable {
private String name;
private int age;
private String place;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public HarlanInfo() {
}
public HarlanInfo(Parcel parcel) {
this.name = parcel.readString();
this.age = parcel.readInt();
this.place = parcel.readString();
}
public int describeContents() {
return 0;
}
/**
* 將對象序列化爲一個Parcel對象 能夠將Parcel當作是一個流,經過writeToParcel把對象寫到流裏面,
* 再經過createFromParcel從流裏讀取對象 注意:寫的順序和讀的順序必須一致。
*/
public void writeToParcel(Parcel parcel, int arg1) {
parcel.writeString(name);
parcel.writeInt(age);
parcel.writeString(place);
}
public static final Parcelable.Creator<HarlanInfo> CREATOR = new Creator<HarlanInfo>() {
public HarlanInfo createFromParcel(Parcel parcel) {
HarlanInfo harlan=new HarlanInfo(parcel);
return harlan;
}
@Override
public HarlanInfo[] newArray(int size) {
// TODO Auto-generated method stub
return new HarlanInfo [size];
}
};
HarlanInfo.aidl
package com.harlan.demo.aidl;
parcelable HarlanInfo;
定義一個aidl文件,使client端利用回調拿到service的param參數;而後設置到toast上顯示出來。
ICallBack.aidl:
package com.harlan.demo.aidl;
interface ICallBack{
void handleByServer(String param);
}
定義這個aidl文件,使client用harlanInfo(client)傳數據和到service,service用harlanInfo(service)取得數據;
ExecuteServiceAIDL.aidl:
package com.harlan.demo.aidl;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;
interface ExecuteServiceAIDL
{
/**
*get info from server and
*Transfer a callback methods handle;
*if occur error ,will be return null
*對於非基本數據類型和String和CharSequence類型,要加上方向指示
*包括in、out和inout,in表示由客戶端設置,out表示由服務端設置,inout是二者都可設置。
*/
HarlanInfo getServerHarlanInfo(in HarlanInfo info,ICallBack icallback);
}
ClientActivity.java:
package com.harlan.demo.activity;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.harlan.demo.aidl.ExecuteServiceAIDL;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;
public class ClientActivity extends Activity
{
public static final String TAG = "ClientActivity";
private static final String BIND_ACTION = "com.harlan.demo.aidl.service";
private EditText mEditTextName;
private EditText mEditTextAge;
private EditText mEditTextPlace;
private Button mButtonCommit;
private ExecuteServiceAIDL executeService;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
getView();
mButtonCommit.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
getServiceConnect();
}
});
}
private void getView()
{
mEditTextName = (EditText)findViewById(R.id.editText_name);
mEditTextAge = (EditText)findViewById(R.id.editText_age);
mEditTextPlace = (EditText)findViewById(R.id.editText_place);
mButtonCommit = (Button)findViewById(R.id.button_commit);
}
private void getServiceConnect()
{
Intent it = new Intent();
it.setAction(BIND_ACTION);
startService(it);
bindService(it, mserviceConnection, BIND_AUTO_CREATE);
}
ServiceConnection mserviceConnection = new ServiceConnection()
{
@Override
public void onServiceDisconnected(ComponentName name)
{
Log.d(TAG, "onServiceDisconnected");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.d(TAG, "onServiceConnected");
executeService = ExecuteServiceAIDL.Stub.asInterface(service);
if (executeService != null)
{
handlerInfo();
}
}
};
private void handlerInfo()
{
String mName;
int mAge;
String mPlace;
if (mEditTextName.getText().toString().equals(""))
{
mName = "孤獨";
}
else
{
mName = mEditTextName.getText().toString();
}
if (mEditTextAge.getText().toString().equals(""))
{
mAge = 23;
}
else
{
mAge = Integer.parseInt(mEditTextAge.getText().toString());
}
if (mEditTextPlace.getText().toString().equals(""))
{
mPlace = "世界";
}
else
{
mPlace = mEditTextPlace.getText().toString();
}
//將數據傳到harlanInfo中
HarlanInfo mInfo = new HarlanInfo();
mInfo.setName(mName);
mInfo.setAge(mAge);
mInfo.setPlace(mPlace);
try
{
HarlanInfo serverInfo = new HarlanInfo();
serverInfo = executeService.getServerHarlanInfo(mInfo, mCallBack);
//拿到service傳回的數據
mEditTextName.setText(serverInfo.getName());
mEditTextAge.setText(String.valueOf(serverInfo.getAge()));
mEditTextPlace.setText(serverInfo.getPlace());
unbindService(mserviceConnection);
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
ICallBack.Stub mCallBack = new ICallBack.Stub()
{
@Override
public void handleByServer(String param)
throws RemoteException
{
Toast.makeText(getApplicationContext(), param, Toast.LENGTH_LONG).show();
}
};
}
AIDLService.Java:
package com.harlan.demo.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.harlan.demo.aidl.ExecuteServiceAIDL;
import com.harlan.demo.aidl.HarlanInfo;
import com.harlan.demo.aidl.ICallBack;
public class AIDLService extends Service
{
public static final String TAG = "AIDLService";
private ICallBack mCallBack;
/**
* 綁定服務
*/
@Override
public IBinder onBind(Intent intent)
{
// TODO Auto-generated method stub
return mBinder;
}
/**
* 建立服務
*/
@Override
public void onCreate()
{
super.onCreate();
}
/**
* 銷燬服務
*/
@Override
public void onDestroy()
{
super.onDestroy();
}
/**
* 啓動服務
*/
@Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
}
/**
* 解綁服務
*/
@Override
public boolean onUnbind(Intent intent)
{
mCallBack = null;
return super.onUnbind(intent);
}
ExecuteServiceAIDL.Stub mBinder = new ExecuteServiceAIDL.Stub()
{
@Override
public HarlanInfo getServerHarlanInfo(HarlanInfo info, ICallBack icallback)
throws RemoteException
{
Log.d(TAG,"getServerHarlanInfo");
mCallBack = icallback;
//傳參數給client
mCallBack.handleByServer("The msg is from server");
HarlanInfo newInfo = new HarlanInfo();
//經過HarlanInfo序列化數據 再傳給client
newInfo.setName(info.getName()+"幸福");
newInfo.setAge(info.getAge() + 10);
newInfo.setPlace(info.getPlace()+"Home");
return newInfo;
}
};
}
效果圖,佈局文件本身寫
ps:本人也是參考別人的例子寫的,中間有解釋不對的地方,望輕噴。。。。