Data data = new Data(10,"这是主进程写的数据");
try {
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("/storage/emulated/0/1/sina/sdadas.txt"));
out.writeObject(data);
out.close();
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "ssss: 序列化的时候失败" + e.toString());
}
Data data = null;
try {
ObjectInputStream in = new ObjectInputStream(
new FileInputStream("/storage/emulated/0/1/sina/sdadas.txt"));
data = (Data) in.readObject();
}catch (IOException e){
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if(data != null){
Log.d(TAG, "onClick: 读取成功 , data.id = " + data.id + "data.name = " + data.name);
}else {
Log.d(TAG, "onClick: 错误");
}
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
private static class Messengerhandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
Log.d(TAG, "handleMessage: receive msg from Client " + msg.getData().getString("msg"));
break;
}
super.handleMessage(msg);
}
}
private final Messenger mMessenger = new Messenger(new Messengerhandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
void bindMyMessengerService(){
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
sendData();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
};
Intent intent = new Intent(this,MessengerService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
}
void sendData(){
Message msg = Message.obtain(null,1);
Bundle data = new Bundle();
data.putString("msg","这是客户端的消息");
msg.setData(data);
try{
mService.send(msg);
}catch (RemoteException e) {
e.printStackTrace();
}
}
private static class Messengerhandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
Log.d(TAG, "handleMessage: receive msg from Client " + msg.getData().getString("msg"));
Messenger client = msg.replyTo;
Message clientData = Message.obtain(null,1);
Bundle bundle = new Bundle();
bundle.putString("reply","嗯,我收到了你的消息,我是服务端");
clientData.setData(bundle);
try {
client.send(clientData);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
super.handleMessage(msg);
}
}
private Messenger mCilentMessenger = new Messenger(new ClientMessenger());
private static class ClientMessenger extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
Log.d(TAG, "handleMessage: 接收到服务端的消息 = " +msg.getData().getString("reply"));
break;
}
super.handleMessage(msg);
}
}
void sendData(){
Message msg = Message.obtain(null,1);
msg.replyTo = mCilentMessenger;
Bundle data = new Bundle();
data.putString("msg","这是客户端的消息");
msg.setData(data);
try{
mService.send(msg);
}catch (RemoteException e) {
e.printStackTrace();
}
}
// IBookManager.aidl
package com.example.learnretrofit.LearnMoreProcess;
import com.example.learnretrofit.LearnMoreProcess.Book;
interface IBookManager {
List getBookList();
void addBook(in Book book);
}
在AIDL文件中,并不是所有类型都可使用,他所能使用的数据类型如下
- 基本数据类型
- String和CharSequence
- List:只支持ArrayList,里面每个元素都必须能被AIDL支持
- Map:只支持HashMap,里面每个元素都必须能被AIDL支持
- Parcelable:所有实现了Parcelable接口的对象,使用时需要手动import
- AIDL:所有的AIDL接口本身也可以在AIDL文件中使用,使用时需要手动import
这里由于在AIDL接口中使用了Book类,所以必须在前面import,另外如果AIDL文件用到了自定义的Parcelable对象,必须新建一个和他同名的AIDL文件,并在其中声明他为Parcelable类型,因为在上面的接口定义中,我们使用了Book类,所以我们必须定义一个aidl文件去声明他
// Book.aidl
package com.example.learnretrofit.LearnMoreProcess;
parcelable Book;
public class BookManagerService extends Service {
private static final String TAG = "BookManagerService";
private CopyOnWriteArrayList mAppleList = new CopyOnWriteArrayList<>();
private Binder mBinder = new IAppleManager.Stub() {
@Override
public List getAppleList() throws RemoteException {
return mAppleList;
}
@Override
public void addApple(Apple apple) throws RemoteException {
mAppleList.add(apple);
}
};
@Override
public void onCreate() {
super.onCreate();
mAppleList.add(new Apple(10,"红富士"));
mAppleList.add(new Apple(10,"早熟苹果"));
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
void bindMyAppleService(){
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IAppleManager appleManager = IAppleManager.Stub.asInterface(service);
try {
List list = appleManager.getAppleList();
Log.d(TAG, "onServiceConnected: query apple list ,list type is " + list.getClass().getCanonicalName());
for(Apple apple : list){
Log.d(TAG, "onServiceConnected: apple.color = " + apple.color + ",apple.size = " + apple.size);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {}
};
bindService(new Intent(this,AppleManagerService.class),mConnection,Context.BIND_AUTO_CREATE);
}
onServiceConnected: query apple list ,list type is java.util.ArrayList
onServiceConnected: apple.color = 红富士,apple.size = 10
onServiceConnected: apple.color = 早熟苹果,apple.size = 10
public void onServiceConnected(ComponentName name, IBinder service) {
IAppleManager appleManager = IAppleManager.Stub.asInterface(service);
try {
List<Apple> list = appleManager.getAppleList();
Log.d(TAG, "onServiceConnected: query apple list ,list type is " + list.getClass().getCanonicalName());
for(Apple apple : list){
Log.d(TAG, "onServiceConnected: apple.color = " + apple.color + ",apple.size = " + apple.size);
}
Apple apple = new Apple(10,"绿色的苹果");
appleManager.addApple(apple);
list = appleManager.getAppleList();
Log.d(TAG, "onServiceConnected: 重新接收");
for(Apple apple1 : list){
Log.d(TAG, "onServiceConnected: apple.color = " + apple1.color + ",apple.size = " + apple1.size);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
onServiceConnected: query apple list ,list type is java.util.ArrayL
onServiceConnected: apple.color = 红富士,apple.size = 10
onServiceConnected: apple.color = 早熟苹果,apple.size = 10
onServiceConnected: 重新接收
onServiceConnected: apple.color = 红富士,apple.size = 10
onServiceConnected: apple.color = 早熟苹果,apple.size = 10
onServiceConnected: apple.color = 绿色的苹果,apple.size = 10
// InewDataListener.aidl
package com.example.learnretrofit.LearnMoreProcess;
import com.example.learnretrofit.LearnMoreProcess.Apple;
interface InewDataListener {
void DataUpdata(in Apple apple);
}
// IBookManager.aidl
package com.example.learnretrofit.LearnMoreProcess;
import com.example.learnretrofit.LearnMoreProcess.Apple;
import com.example.learnretrofit.LearnMoreProcess.InewDataListener;
interface IAppleManager {
List getAppleList();
void addApple(in Apple apple);
void registerListener(InewDataListener listener);
void unRegisterListener(InewDataListener listener);
}
private AtomicBoolean mAtomicBoolean = new AtomicBoolean(false);
private CopyOnWriteArrayList mListeners = new CopyOnWriteArrayList<>();
private Binder mBinder = new IAppleManager.Stub() {
@Override
public List getAppleList() throws RemoteException {
return mAppleList;
}
@Override
public void addApple(Apple apple) throws RemoteException {
mAppleList.add(apple);
}
@Override
public void registerListener(InewDataListener listener) throws RemoteException {
if(!mListeners.contains(listener)){
mListeners.add(listener);
}
}
@Override
public void unRegisterListener(InewDataListener listener) throws RemoteException {
if(mListeners.contains(listener)){
mListeners.remove(listener);
}
}
};
public void onCreate() {
super.onCreate();
mAppleList.add(new Apple(10,"红富士"));
mAppleList.add(new Apple(10,"早熟苹果"));
new Thread(new ServiceWorker()).start();
}
private class ServiceWorker implements Runnable{
@Override
public void run() {
while (!mAtomicBoolean.get()){
try{
Thread.sleep(5000);
int appleId = mAppleList.size() + 1;
Apple apple = new Apple(appleId,"苹果 " + appleId + " 号");
addNewApple(apple);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void addNewApple(Apple apple) {
mAppleList.add(apple);
for(int i = 0;i < mListeners.size() ; i ++) {
InewDataListener listener = mListeners.get(i);
try {
listener.DataUpdata(apple);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
private InewDataListener mInewDataListener = new InewDataListener.Stub() {
@Override
public void DataUpdata(Apple apple) throws RemoteException {
mHandler.obtainMessage(10,apple).sendToTarget();
}
};
void bindMyAppleService(){
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IAppleManager appleManager = IAppleManager.Stub.asInterface(service);
try {
List list = appleManager.getAppleList();
Log.d(TAG, "onServiceConnected: query apple list ,list type is " + list.getClass().getCanonicalName());
for(Apple apple : list){
Log.d(TAG, "onServiceConnected: apple.color = " + apple.color + ",apple.size = " + apple.size);
}
Apple apple = new Apple(10,"绿色的苹果");
appleManager.addApple(apple);
list = appleManager.getAppleList();
Log.d(TAG, "onServiceConnected: 重新接收");
for(Apple apple1 : list){
Log.d(TAG, "onServiceConnected: apple.color = " + apple1.color + ",apple.size = " + apple1.size);
}
appleManager.registerListener(mInewDataListener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {}
};
bindService(new Intent(this,AppleManagerService.class),mConnection,Context.BIND_AUTO_CREATE);
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 10:
Log.d(TAG, "handleMessage: receive The new Data " + msg.obj);
}
super.handleMessage(msg);
}
};
onServiceConnected: query apple list ,list type is java.util.ArrayList
onServiceConnected: apple.color = 红富士,apple.size = 10
onServiceConnected: apple.color = 早熟苹果,apple.size = 10
onServiceConnected: 重新接收
onServiceConnected: apple.color = 红富士,apple.size = 10
onServiceConnected: apple.color = 早熟苹果,apple.size = 10
onServiceConnected: apple.color = 绿色的苹果,apple.size = 10
handleMessage: receive The new Data 苹果 4 号
handleMessage: receive The new Data 苹果 5 号
handleMessage: receive The new Data 苹果 6 号
public class RemoteCallbackList<E extends IInterface>
ArrayMap<IBinder, Callback> mCallbacks = new ArrayMap<IBinder, Callback>();
其中Callback中封装了真正的远程Listener,当客户端注册listener的时候,他会把这个listener信息存入mCallback中,其中key和value分别通过下面的方式获得
private RemoteCallbackList mCallbackList = new RemoteCallbackList<>();
// private CopyOnWriteArrayList mListeners = new CopyOnWriteArrayList<>();
public void registerListener(InewDataListener listener) throws RemoteException {
// if(!mListeners.contains(listener)){
// mListeners.add(listener);
// }
mCallbackList.register(listener);
}
@Override
public void unRegisterListener(InewDataListener listener) throws RemoteException {
// if(mListeners.contains(listener)){
// mListeners.remove(listener);
// }
mCallbackList.unregister(listener);
}
private void addNewApple(Apple apple) {
mAppleList.add(apple);
// for(int i = 0;i < mListeners.size() ; i ++) {
// InewDataListener listener = mListeners.get(i);
// try {
// listener.DataUpdata(apple);
// } catch (RemoteException e) {
// e.printStackTrace();
// }
// }
final int N = mCallbackList.beginBroadcast();
for (int i = 0;i < N;i++){
InewDataListener listener = mCallbackList.getBroadcastItem(i);
if(listener != null){
try{
listener.DataUpdata(apple);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
mCallbackList.finishBroadcast();
}
unRegisterListener: 取消之前的数量是 1
unRegisterListener: 取消之后的数量是 0
final int N = mCallbackList.beginBroadcast();
for (int i = 0;i < N;i++){
InewDataListener listener = mCallbackList.getBroadcastItem(i);
if(listener != null){
try{
listener.DataUpdata(apple);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
mCallbackList.finishBroadcast();
到这里关于AIDL的基本东西就说完了,这里说几点注意
- 我们必须清楚什么方法执行在主线程,什么方法执行在Binder线程池,一些耗时的或者不可知的操作尽可能放在多线程中解决
- 涉及到UI操作的,如果当前线程非主线程,要使用Handler切换到主线程再进行操作
- 还有,binder是有可能意外死亡的,为了我们程序的健壮性,我们有必要给Binder设置死亡监听
"string resource"
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permissionGroup="string"
android:protectionLevel=["normal" | "dangerous" |"signature" | "signatureOrSystem"] />
属性 | 说明 | 是否必须 |
---|---|---|
name | 自定义的权限名称,需要遵循Android权限定义命名方案:.permission. | 是 |
protectionLevel | 与权限相关的”风险级别”。必须是以下值之一:normal, dangerous, signature, signatureOrSystem ,取决于保护级别,在确定是否授予权限时,系统可能采取不同的操作。 | 是 |
permissionGroup | 可以将权限放在一个组中,但对于自定期义权限,应该避免设置此属性。如果确实希望设置此属性,可能使用以下属性代替:android.permisson-group.SYSTEM_TOOLS | 否 |
label | 对权限的一个简短描述 | 否 |
description | 对权限的描述,一般是两句话,第一句话描述这个权限所针对的操作,第二句话告诉用户授予app这个权限会带来的后果 | 否 |
icon | 权限可以与资源目录以外的图标相关联 ( 比如@drawable/myicon) | 否 |
protectionLevel权限 | 说明 |
---|---|
normal | 权限被声明为Normal级别,任何应用都可以申请,在安装应用时,不会直接提示给用户,点击全部才会展示。 |
dangerous | 权限被声明为Dangerous级别,任何应用都可以申请,在安装应用时,会直接提示给用户。 |
signature | 权限被声明为Signature级别,只有和该apk(定义了这个权限的apk)用相同的私钥签名的应用才可以申请该权限。 |
signatureOrSystem | 权限被声明为SignatureOrSystem级别,有两种应用可以申请该权限。1) 和该apk(定义了这个权限的apk)用相同的私钥签名的应用;2) 在/system/app目录下的应用 |
<permission
android:name="com.example.learnretrofit.LearnMoreProcess.permission.ACCESS_APPLE_SERVICE"
android:protectionLevel="normal"/>
public IBinder onBind(Intent intent) {
int check = checkCallingOrSelfPermission("com.example.learnretrofit.LearnMoreProcess.permission.ACCESS_APPLE_SERVICE");
if(check == PackageManager.PERMISSION_DENIED){
return null;
}
return mBinder;
}
<uses-permission android:name="com.example.learnretrofit.LearnMoreProcess.permission.ACCESS_APPLE_SERVICE"/>
public class MyDataProvider extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
}
<provider
android:authorities="com.example.learnretrofit.LearnMoreProcess.MyContentProvider.MyDataProvider"
android:name=".LearnMoreProcess.MyContentProvider.MyDataProvider"
android:permission="com.example.permission.MyContentProvider.MyDataProvider"
android:process=":provider"
/>
Uri uri = Uri.parse("content://com.example.learnretrofit.LearnMoreProcess.MyContentProvider.MyDataProvider");
getContentResolver().query(uri,null,null,null,null);
getContentResolver().query(uri,null,null,null,null);
getContentResolver().query(uri,null,null,null,null);
provider D/MyDataProvider: onCreate: Thread.currentThread().getName() = main
provider D/MyDataProvider: query: current Thread : Binder:18054_3
provider D/MyDataProvider: query: current Thread : Binder:18054_3
provider D/MyDataProvider: query: current Thread : Binder:18054_3
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
public class SocketService extends Service {
private final static String TAG = "SocketService";
private List mSockets = new ArrayList<>();
private ServerSocket mServerSocket = null;
@Override
public void onCreate() {
new Thread(new TcpServer()).start();
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private class TcpServer implements Runnable{
@Override
public void run() {
//先启动服务端的30000端口号,如果不能启动就直接退出
try {
mServerSocket = new ServerSocket(30000);
Log.d(TAG, "run: 服务端启动成功");
} catch (IOException e) {
Log.d(TAG, "run: 不能使用30000端口");
e.printStackTrace();
return;
}
//创建完成服务端之后就等着客户端来请求连接了
while (!mServerSocket.isClosed()){
try {
final Socket socket = mServerSocket.accept();
Log.d(TAG, "run: 收到了一个客户端");
//将服务器这边的Socket添加到集合
mSockets.add(socket);
//当来一个客户端连接成功,就会启动一个线程来监听客户端发送消息
new Thread(new myThread(socket)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//监听客户端发消息的线程
private class myThread implements Runnable{
Socket mSocket = null;
public myThread(Socket socket) {
mSocket = socket;
}
@Override
public void run() {
try {
InputStream in = mSocket.getInputStream();
byte[] b = new byte[1024];
int i = -1;
while (true) {
if ((i = in.read(b)) > 0) {
String s = new String(b, 0, i);
Log.d(TAG, "服务端接收: " + s);
//一旦收到某个客户端发送消息,就将这条消息发送到所有的客户端,以达到多人聊天的操作
for (Socket socket : mSockets){
OutputStream out = socket.getOutputStream();
out.write("我给你回个消息吧,免得你尴尬".getBytes());
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class SocketService extends Service {
private final static String TAG = "SocketService";
private List mSockets = new ArrayList<>();
private ServerSocket mServerSocket = null;
@Override
public void onCreate() {
new Thread(new TcpServer()).start();
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private class TcpServer implements Runnable{
@Override
public void run() {
//先启动服务端的30000端口号,如果不能启动就直接退出
try {
mServerSocket = new ServerSocket(30000);
Log.d(TAG, "run: 服务端启动成功");
} catch (IOException e) {
Log.d(TAG, "run: 不能使用30000端口");
e.printStackTrace();
return;
}
//创建完成服务端之后就等着客户端来请求连接了
while (!mServerSocket.isClosed()){
try {
final Socket socket = mServerSocket.accept();
Log.d(TAG, "run: 收到了一个客户端");
//将服务器这边的Socket添加到集合
mSockets.add(socket);
//当来一个客户端连接成功,就会启动一个线程来监听客户端发送消息
new Thread(new myThread(socket)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//监听客户端发消息的线程
private class myThread implements Runnable{
Socket mSocket = null;
public myThread(Socket socket) {
mSocket = socket;
}
@Override
public void run() {
try {
InputStream in = mSocket.getInputStream();
byte[] b = new byte[1024];
int i = -1;
while (true) {
if ((i = in.read(b)) > 0) {
String s = new String(b, 0, i);
Log.d(TAG, "服务端接收: " + s);
//一旦收到某个客户端发送消息,就将这条消息发送到所有的客户端,以达到多人聊天的操作
for (Socket socket : mSockets){
OutputStream out = socket.getOutputStream();
out.write(("你发来了 "+ s+"\n 我给你回个消息吧,免得你尴尬").getBytes());
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
D/SocketService: run: 服务端启动成功
D/SocketService: run: 收到了一个客户端
D/SocketActivity: run: 连接成功 socket 30000,/127.0.0.1:56200
D/SocketService: 服务端接收: 我来啦
D/SocketActivity: 客户端接收: 我给你回个消息吧,免得你尴尬
D/SocketActivity: onClick: 给服务器发送 : baccalaureate
D/SocketService: 服务端接收: baccalaureate
D/SocketActivity: 客户端接收: 我给你回个消息吧,免得你尴尬
D/SocketActivity: onClick: 给服务器发送 : baccalaureate
D/SocketService: 服务端接收: baccalaureate
D/SocketActivity: 客户端接收: 我给你回个消息吧,免得你尴尬
大概是这样一个过程
// play.aidl
package com.example.learnretrofit.LearnMoreProcess.BinderPool;
// Declare any non-default types here with import statements
interface Play {
int playGames(String gameName);
}
// study.aidl
package com.example.learnretrofit.LearnMoreProcess.BinderPool;
// Declare any non-default types here with import statements
interface Study {
String readBook(String bookName);
}
// IBinderPool.aidl
package com.example.learnretrofit.LearnMoreProcess.BinderPool;
// Declare any non-default types here with import statements
interface IBinderPool {
IBinder queryBinder(int BinderCode);
}
public class PlayImpl extends Play.Stub {
public static final int PlayVeryGood = 1;
private static final String TAG = "playImpl";
@Override
public int playGames(String gameName) throws RemoteException {
Log.d(TAG, "playGames: 玩 " + gameName + " 很爽!");
return PlayVeryGood;
}
}
public class StudyImpl extends Study.Stub {
private static final String TAG = "studyImpl";
@Override
public String readBook(String bookName) throws RemoteException {
Log.d(TAG, "readBook: 来到这里读书了");
return "读 " + bookName + " 这本书真是太充实了!";
}
}
看一下代码(这段代码是Binderpool类中的,这个类就是我们单独写的操作子客户端的类)
- 先看一下单例模式部分
public static BinderPool getInstance(Context context) {
if(sInstance == null){
synchronized (BinderPool.class){
if(sInstance == null){
Log.d(TAG, "getInstance: 实例化单例对象");
sInstance = new BinderPool(context);
Log.d(TAG, "getInstance: 准备返回到客户端");
}
}
}
return sInstance;
}
private BinderPool(Context context){
mContext = context.getApplicationContext();
connectBinderService();
}
private synchronized void connectBinderService() {
mConnectBinderPoolCountDownLatch = new CountDownLatch(1);
Intent service = new Intent(mContext,BinderPoolService.class);
Log.d(TAG, "connectBinderService: 绑定服务");
mContext.bindService(service,mBinderPoolConnection,Context.BIND_AUTO_CREATE);
try {
Log.d(TAG, "connectBinderService: mConnectBinderPoolCountDownLatch.await()");
mConnectBinderPoolCountDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "connectBinderService: 绑定方法执行完毕");
}
public class BinderPoolService extends Service {
private static final String TAG = "BinderPoolService";
private Binder mBinderPool = new BinderPool.BinderPoolImpl();
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: 给客户端返回BinderPool");
return mBinderPool;
}
}
public static class BinderPoolImpl extends IBinderPool.Stub{
public BinderPoolImpl() {
super();
}
@Override
public IBinder queryBinder(int BinderCode) throws RemoteException {
IBinder binder = null;
switch (BinderCode){
case BINDER_STUDY:
//
Log.d(TAG, "queryBinder: 实例化学习功能的Binder");
binder = new StudyImpl();
break;
case BINDER_PLAY:{
binder = new PlayImpl();
break;
}
}
return binder;
}
}
private ServiceConnection mBinderPoolConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//拿到跨进程操作BinderPool的对象
Log.d(TAG, "onServiceConnected: 拿到跨进程操作BinderPool的对象");
mBinderPool = IBinderPool.Stub.asInterface(service);
try {
Log.d(TAG, "connectBinderService: 绑定死亡监听");
mBinderPool.asBinder().linkToDeath(mBinderPoolDeathRecipent,0);
} catch (RemoteException e) {
Log.d(TAG, "onServiceConnected: 错误了");
e.printStackTrace();
}
Log.d(TAG, "onServiceConnected: 连接完毕");
mConnectBinderPoolCountDownLatch.countDown();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
public static class BinderPoolImpl extends IBinderPool.Stub{
public BinderPoolImpl() {
super();
}
@Override
public IBinder queryBinder(int BinderCode) throws RemoteException {
IBinder binder = null;
switch (BinderCode){
case BINDER_STUDY:
//
Log.d(TAG, "queryBinder: 实例化学习功能的Binder");
binder = new StudyImpl();
break;
case BINDER_PLAY:{
binder = new PlayImpl();
break;
}
}
return binder;
}
}
IBinder playBinder = binderPool.queryBinder(BinderPool.BINDER_PLAY);
Play play = PlayImpl.asInterface(playBinder);
try {
play.playGames("率土之滨");
} catch (RemoteException e) {
e.printStackTrace();
}
private void doThings(){
Log.d(TAG, "doThings: 准备获取binder单例对象");
BinderPool binderPool = BinderPool.getInstance(BinderPoolActivity.this);
Log.d(TAG, "doThings: 获取学习Binder对象");
IBinder studyBinder = binderPool.queryBinder(BinderPool.BINDER_STUDY);
Log.d(TAG, "doThings: 包装studyBinder 跨进程传输对象");
Study study = StudyImpl.asInterface(studyBinder);
String bookName = "《鬼吹灯》";
try {
study.readBook(bookName);
} catch (RemoteException e) {
e.printStackTrace();
}
IBinder playBinder = binderPool.queryBinder(BinderPool.BINDER_PLAY);
Play play = PlayImpl.asInterface(playBinder);
try {
play.playGames("率土之滨");
} catch (RemoteException e) {
e.printStackTrace();
}
}
D/BinderPoolActivity: doThings: 准备获取binder单例对象
D/BinderPool: getInstance: 实例化单例对象
D/BinderPool: connectBinderService: 绑定服务
D/BinderPool: connectBinderService: mConnectBinderPoolCountDownLatch.await()
D/BinderPoolService: onBind: 给客户端返回BinderPool
D/BinderPool: onServiceConnected: 拿到跨进程操作BinderPool的对象
D/BinderPool: connectBinderService: 绑定死亡监听
D/BinderPool: onServiceConnected: 连接完毕
D/BinderPool: connectBinderService: 绑定方法执行完毕
D/BinderPool: getInstance: 准备返回到客户端
D/BinderPoolActivity: doThings: 获取学习Binder对象
D/BinderPool: queryBinder: 实例化学习功能的Binder
D/BinderPoolActivity: doThings: 包装studyBinder 跨进程传输对象
D/studyImpl: readBook: 来到这里读书了
D/playImpl: playGames: 玩 率土之滨 很爽!
名称 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
Bundle | 简单易用 | 只能传输Bundle支持的数据类型 | 四大组件的进程间通信 |
文件共享 | 简单易用 | 不适合高并发场景,并且无法做到进程间的即时通信 | 无并发访问情形,交换简单的数据,实时性不高的场景 |
AIDL | 功能强大,支持一对多并发通信 | 使用稍复杂,需要处理好线程同步 | 一对多通信且有RPC需求 |
Messenger | 功能一般,支持一对多串行通信,支持实时通信 | 不能很好处理高并发类型,不支持RPC,数据通过Message传输,因此只能传输Bundle支持的数据类型 | 低并发的一对多即时通信,无RPC需求,或者无需要返回结果的RPC需求 |
ContentProvider | 在数据访问方面功能强大,支持一对多并发数据共享,也可用Call方法扩展其他操作 | 可以理解为受约束的AIDL,主要提供数据源的CRUD操作 | 一对多的进程间数据共享 |
Socket | 功能强大,可以通过网络传输字节流,支持一对多并发实时通信 | 实现细节稍微有点繁琐,不支持直接的RPC | 网络数据交换 |