AIDL跨App(跨进程)通信

Posted by アライさん on 2019年10月22日

实测kotlin实现时,明明类存在,但会出现unresolved reference


模式:一个App开启Service服务,一个App绑定服务进行交互。

要点:

Service App和Client App要使用同一份aidl文件,包名也必须相同。
如果不是用基础数据而是要使用序列化后的Data,Data的包名也必须相同。


/———————————————————————————
/———————————————————————————


##

Service App

创建Data序列化数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.example.testaidl;

import android.os.Parcel;
import android.os.Parcelable;

public class BookData implements Parcelable {

private String name;

public BookData(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "BookData name:" + name;
}

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
}

public void readFromParcel(Parcel dest) {
name = dest.readString();
}

protected BookData(Parcel in) {
this.name = in.readString();
}

public static final Creator<BookData> CREATOR = new Creator<BookData>() {
@Override
public BookData createFromParcel(Parcel source) {
return new BookData(source);
}

@Override
public BookData[] newArray(int size) {
return new BookData[size];
}
};
}

右键点击项目,new->aidl,创建AIDl文件。

BookData.aidl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.testaidl;
parcelable BookData;
```
**BookController.aidl**
```java
package com.example.testaidl;

import com.example.testaidl.BookData;
// Declare any non-default types here with import statements

interface BookController {
List<BookData> getBookList();
void addBookInOut(inout BookData book);
}

创建Service类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.example.testaidl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;
import com.example.testaidl.BookController;

public class MyAIDLService extends Service {
private final String TAG = "Server";

private List<BookData> bookList;

public MyAIDLService() {
}

@Override
public void onCreate() {
super.onCreate();
bookList = new ArrayList<>();
initData();
}

private void initData() {
BookData book1 = new BookData("活着");
BookData book2 = new BookData("或者");
BookData book3 = new BookData("叶应是叶");
BookData book4 = new BookData("https://github.com/leavesC");
BookData book5 = new BookData("http://www.jianshu.com/u/9df45b87cfdf");
BookData book6 = new BookData("http://blog.csdn.net/new_one_object");
bookList.add(book1);
bookList.add(book2);
bookList.add(book3);
bookList.add(book4);
bookList.add(book5);
bookList.add(book6);
}

private final BookController.Stub stub = new BookController.Stub() {

@Override
public List<BookData> getBookList() throws RemoteException {
return bookList;
}

@Override
public void addBookInOut(BookData book) throws RemoteException {
if (book != null) {
book.setName("服务器改了新书的名字 InOut");
bookList.add(book);
} else {
Log.e(TAG, "接收到了一个空对象 InOut");
}
}

};

@Override
public IBinder onBind(Intent intent) {
return stub;
}
}


/--------------------------------------------------------------------------------- /---------------------------------------------------------------------------------
## Client App 拷贝aidl文件夹到app/src/main文件夹中,包名不变 创建Service App相同包名的Data类,拷贝代码。 **MainActivity** ```java package com.example.myapplication;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.example.testaidl.BookController;
import com.example.testaidl.BookData;

import java.util.ArrayList;

public class Main2Activity extends AppCompatActivity {
ArrayList bookList = new ArrayList<>();
boolean connected = false;
BookController bookController = null;

final ServiceConnection serviceConnection = new ServiceConnection(){
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        connected = true;
        bookController = BookController.Stub.asInterface(iBinder);
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        connected = false;
    }
};

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bindService();

    findViewById(R.id.btnAdd).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            try {
                bookController.addBookInOut(new BookData("新书"));
            }catch (Exception e){

            }
        }
    });

    findViewById(R.id.btnGet).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            try {
                bookList.clear();
                    bookList.addAll(bookController.getBookList());
                for(BookData book : bookList){
                    Log.d("zql","书名:"+book.getName());
                }
            }catch (Exception e){

            }
        }
    });
}

void  bindService(){
    Intent intent =new Intent();
    intent.setPackage("com.example.testaidl");
    intent.setAction("com.example.testaidl.action");
    bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if(connected){
        unbindService(serviceConnection);
    }
}

}