尊重每個人的付出,轉載請點這裏 : http://blog.csdn.net/hanj456/article/details/52433718
傳遞基本數據類型
簡單三步
Step 1
準備AIDL文件 ,注意:文件寫完後需要 Sync Project一下!
package cn.test.aidlb;
interface IRemoteService {
int getResult();
void setText(String content);
}
Step 2
準備service ,要點:新建service文件後馬上在清單文件中配置一下:
<service android:name=".MyService"
android:process="com.test.action">
<intent-filter>
<action android:name="com.test.action"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
服務端
public class MyService extends Service {
private static final String TAG = "MyService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
System.out.println("service onBind");
return mBinder;
}
private IRemoteService.Stub mBinder = new IRemoteService.Stub() {
@Override
public int getResult() throws RemoteException {
int sum=5*4/2;
return sum;
}
@Override
public void setText(String content) throws RemoteException {
Log.i(TAG, content+" 調用B應用的方法");
}
};
@Override
public void onCreate() {
super.onCreate();
System.out.println("service onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("service onDestroy");
}
}
Step 3
首先將service端應用中的aidl包複製到activity所在的應用中,在activity中進行綁定服務,注意:android 5.0以後 intent需要設置包名
客戶單
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private IRemoteService mService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 點擊按鈕後綁定服務
* @param view
*/
public void bind(View view){
Intent intent = new Intent();
intent.setAction("com.test.action");
intent.setPackage("cn.test.aidlb");
bindService(intent,sc, Context.BIND_AUTO_CREATE);
}
private ServiceConnection sc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IRemoteService.Stub.asInterface(service);
try {
int result = mService.getResult();
mService.setText("我在A應用 ");
Log.i(TAG, "onServiceConnected: result="+result);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
/**
* activity銷燬時解綁服務
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (sc!=null){
unbindService(sc);
}
}
}
傳遞對象
服務端簡單6步
Step1
創建對象文件Person.java,實現Parcelable接口
public class Person implements Parcelable{
private int age;
private String name;
protected Person(Parcel in) {
age = in.readInt();
name = in.readString();
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public Person() {
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
public void readFromParcel(Parcel dest) {
age = dest.readInt();
name = dest.readString();
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Step2
創建AIDL文件 Person.aidl ,聲明對象爲序列化
package com.xxx.xxxx;
parcelable Person;
注:parcelable第一個字母p爲小寫
Step3
創建AIDL接口文件 IPerson.aidl,聲明傳遞數據需要的方法,這裏需要重點說明的是數據流向的關鍵字聲明
in ,out , inout 三者的用法和區別:簡單點說就是當你的數據需要從Service端設置,Client端獲取時使用out,
反之使用 in ,如果需要雙向傳遞數據就使用 inout.
package com.test.myServer;
import com.test.myServer.Person;
interface IPerson {
String inPerson(in Person p);
String outPerson();
String inoutPerson(inout Person p);
}
Step4
這一步需要在Model下的 gradle 文件中 android 標籤下加上以下內容,否則完成第五步後編譯會報找不到
Person對象的錯誤:
sourceSets {
main {
java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
Step5
新建一個service文件,要點就是實現返回我們自己定義的AIDL接口
public class AidlService extends Service {
private MyBinder mBinder;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private class MyBinder extends IPerson.Stub{
@Override
public String inPerson(Person p) throws RemoteException {
String person = "age="+p.getAge()+",name="+p.getName();
Log.i("test", "inPerson: "+person);
return person;
}
@Override
public String outPerson() throws RemoteException {
Person p = new Person();
p.setAge(22);
p.setName("Tom");
return p.toString() ;
}
@Override
public String inoutPerson(Person p) throws RemoteException {
Log.i("test", "inPerson: "+p.toString());
return p.toString();
}
}
@Override
public void onCreate() {
super.onCreate();
mBinder = new MyBinder();
}
}
Step6
在清單文件中聲明創建的service文件,需要注意的是要加上action作爲唯一的意圖標記,最後將服務端創建的aidl文件及Person.java文件複製到客戶端。
<service android:name=".AidlService">
<intent-filter>
<action android:name="com.test.myServer.action.AIDL_SERVICE"/>
</intent-filter>
</service>
再來看看客戶端,這邊就比較簡單,重點是把服務端需要的文件複製過來之後需要clean一下project,如果在
(客戶端)/build/generated/source/aidl/debug下出現service文件所在的包和aidl文件,那麼恭喜你,下面
基本就沒有什麼難度了。
public class ComplexActivity extends AppCompatActivity{
private TextView mTv_content;
private EditText mEt_age;
private EditText mEt_name;
private IPerson mIPerson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_complex);
initView();
bind();
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mIPerson = IPerson.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mIPerson = null;
}
};
private void bind() {
Intent intent = new Intent();
intent.setAction("com.test.myServer.action.AIDL_SERVICE2");
intent.setPackage("com.test.myServer");
bindService(intent,conn, Service.BIND_AUTO_CREATE);
Log.i("test", "bind: 綁定服務");
}
private void initView() {
mTv_content = (TextView) findViewById(R.id.tv_content);
mEt_age = (EditText) findViewById(R.id.et_age);
mEt_name = (EditText) findViewById(R.id.et_name);
}
/**
* 調用aidl接口中的inPerson方法,該方法聲明的數據流向是 in,
* 表示由客戶端設置數據,服務端可以接收客戶端傳過來的數據
* @param v
*/
public void setInfo(View v){
String age = mEt_age.getText().toString().trim();
String name = mEt_name.getText().toString().trim();
try {
if (!TextUtils.isEmpty(age)&&!TextUtils.isEmpty(name)){
mIPerson.inPerson(new Person(Integer.parseInt(age),name));
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* 調用aidl接口中的outPerson方法,該方法聲明的數據流向是 out,
* 表示數據流向是從服務端傳輸到客戶端,所以在服務端中設置數據,
* 在客戶端中進行顯示數據
* @param v
*/
public void showInfo(View v){
try {
String content = mIPerson.outPerson();
mTv_content.setText(content);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* 調用aidl接口中的inoutPerson方法,該方法聲明的數據流向是 inout,
* 表示數據是可以雙向流動的,既可以在客戶端設置數據從服務端取數據,
* 也可以從服務端設置數據,在客戶端取數據
* @param v
*/
public void showDoubleInfo(View v){
String age = mEt_age.getText().toString().trim();
String name = mEt_name.getText().toString().trim();
try {
if (!TextUtils.isEmpty(age)&&!TextUtils.isEmpty(name)){
mIPerson.inoutPerson(new Person(Integer.parseInt(age),name));
//String content = mIPerson.inoutPerson();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}