android studio AIDL的使用(五)Messager的使用

1.全部代码:

1.MainActivity

package com.kunminx.exampleaidlmukewang;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.kunminx.exampleaidlmukewang.entity.Message;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "MainActivity";
    private Button mBtConect;
    private Button mBtDisconnect;
    private Button mBtIsConnected;

    private IConnectionService connectionServiceProxy;
    private IServiceManager serviceManagerProxy;
    private IMessageService messageServiceProxy;
    private Button mBtSendMessage;
    private Button mBtRegisterListener;
    private Button mBtUnregister;
    private Button mBtMessenger;

    //信使来进行通信
    private Messenger messengerProxy;

    private Handler handle=new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(@NonNull android.os.Message msg) {
            super.handleMessage(msg);
            Bundle bundle = msg.getData();//获取数据
            bundle.setClassLoader(Message.class.getClassLoader());//注意,这句可以解决序列化问题
            final Message message = bundle.getParcelable("message");//key获取值
            handle.postDelayed(new Runnable() {//延迟执行
                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, "MainActivity打印了:"+message.getContent(), Toast.LENGTH_SHORT).show();
                }
            }, 1000);
        }
    };
    //接收子进程的消息
    private Messenger clientMessenger =new Messenger(handle);
    /**IPC
     * 对AIDL创建的类的方法的实现
     * remoteService对main方法的调用,相当于反向调用
     */
    private MessageReceiverListener messageReceiverListener=new MessageReceiverListener.Stub() {
        @Override
        public void onReceiveMessage(final Message message) throws RemoteException {
            new Handler(Looper.getMainLooper()).post(new Runnable() {//实现方法
                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, message.getContent(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        Intent mIntent = new Intent(this, RemoteService.class);
        bindService(mIntent, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {

                try {
                    serviceManagerProxy = IServiceManager.Stub.asInterface(service);//获取代理

                    //获取连接代理
                    connectionServiceProxy = IConnectionService.Stub.asInterface(serviceManagerProxy.getService(IConnectionService.class.getSimpleName()));
                    //获取消息代理
                    messageServiceProxy = IMessageService.Stub.asInterface(serviceManagerProxy.getService(IMessageService.class.getSimpleName()));
                    //信使代理初始化
                    messengerProxy=new Messenger(serviceManagerProxy.getService(Messenger.class.getSimpleName()));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        }, BIND_AUTO_CREATE);
    }

    private void initView() {
        mBtConect = (Button) findViewById(R.id.bt_conect);
        mBtDisconnect = (Button) findViewById(R.id.bt_disconnect);
        mBtIsConnected = (Button) findViewById(R.id.bt_isConnected);
        mBtSendMessage = (Button) findViewById(R.id.bt_send_message);
        mBtRegisterListener = (Button) findViewById(R.id.bt_register_listener);
        mBtUnregister = (Button) findViewById(R.id.bt_unregister);
        mBtConect.setOnClickListener(this);

        mBtMessenger = (Button) findViewById(R.id.bt_messenger);
        mBtMessenger.setOnClickListener(this);
        mBtDisconnect.setOnClickListener(this);
        mBtIsConnected.setOnClickListener(this);
        mBtSendMessage.setOnClickListener(this);
        mBtRegisterListener.setOnClickListener(this);
        mBtUnregister.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_conect:
                try {
                    connectionServiceProxy.connect();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.bt_disconnect:
                try {
                    connectionServiceProxy.disconnect();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.bt_isConnected:
                boolean isConnection = false;
                try {
                    isConnection = connectionServiceProxy.isConnection();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                Toast.makeText(this, String.valueOf(isConnection), Toast.LENGTH_SHORT).show();
                break;
            case R.id.bt_send_message:
                Message message=new Message();
                message.setContent("这个消息来自main");
                try {
                    messageServiceProxy.sendMessage(message);
                    Log.d(TAG, "onClick: "+String.valueOf(message.isSendSuccess()));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.bt_register_listener:
                try {
                    messageServiceProxy.registerMessageReceiveListener(messageReceiverListener);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.bt_unregister:
                try {
                    messageServiceProxy.unRegisterMessageReceiveListener(messageReceiverListener);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.bt_messenger:
                try {
                    Message message1=new Message();//自定义的序列化消息
                    message1.setContent("hello! 我是来自Main,Messager乘车员");//消息内容
                    Bundle bundleData=new Bundle();//初始化Bundle
                    bundleData.putParcelable("message",message1);//Bundle可以传递序列化数据
                    android.os.Message mMessage=new android.os.Message();//初始化android.os.Message
                    mMessage.replyTo= clientMessenger;
                    mMessage.setData(bundleData);//android.os.Message的参数是Bundle
                    messengerProxy.send(mMessage);//这里是信使代理发送消息,参数是android.os.Message,不要搞错成message
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
        }
    }
}

2.RemoteService

package com.kunminx.exampleaidlmukewang;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Messenger;
import android.os.Parcelable;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.kunminx.exampleaidlmukewang.entity.Message;

import java.util.ArrayList;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class RemoteService extends Service {
    private static final String TAG = "RemoteService";
    private boolean isConnected = false;
    //用arrayList来储存消息的监听
    private RemoteCallbackList<MessageReceiverListener> messageReceiverListenerRemoteCallbackList = new RemoteCallbackList<>();
    private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
    //模拟消息接收的过程,通过定时任务
    private ScheduledFuture scheduledFuture;


    public RemoteService() {
    }


    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull android.os.Message msg) {
            super.handleMessage(msg);

            Bundle bundle = msg.getData();
            bundle.setClassLoader(Message.class.getClassLoader());//注意,这句可以解决序列化问题
            Message message = bundle.getParcelable("message");
            Toast.makeText(RemoteService.this, "remoteServiceToast了:" + message.getContent(), Toast.LENGTH_SHORT).show();
            /**
             * 回复
             */
            try {
                Messenger clientMessenger = msg.replyTo;//初始化msg的消息回复,这个是消息回复用的,可以发回给MainActivity
                Message reply = new Message();
                reply.setContent("来之remoteService的回复");
                android.os.Message data = new android.os.Message();
                data.replyTo = clientMessenger;//令android.os.Message的replaceTo等于msg.replayTo
                bundle = new Bundle();
                bundle.putParcelable("message", reply);
                data.setData(bundle);
                clientMessenger.send(data);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };
    //注意:下面这些都是运行在子线程中的,所有Toast要线程通信
    private Messenger messenger = new Messenger(handler);

    private IConnectionService connectionService = new IConnectionService.Stub() {
        @Override
        public void connect() throws RemoteException {
            try {
                Thread.sleep(5000);
                isConnected = true;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(RemoteService.this, "connect", Toast.LENGTH_SHORT).show();
                    }
                });
                //单位:s
                scheduledFuture = scheduledThreadPoolExecutor.scheduleAtFixedRate(
                        new Runnable() {
                            @Override
                            public void run() {
                                //遍历消息接收的监听
                                int size = messageReceiverListenerRemoteCallbackList.beginBroadcast();
                                for (int i = 0; i < size; i++) {
                                    Message message = new Message();
                                    message.setContent("这个消息来自remoteService");
                                    try {
                                        messageReceiverListenerRemoteCallbackList.getBroadcastItem(i).onReceiveMessage(message);
                                    } catch (RemoteException e) {
                                        e.printStackTrace();
                                    }
                                }
                                messageReceiverListenerRemoteCallbackList.finishBroadcast();
                            }
                        }//执行的方法
                        , 5000//第一次执行的时间
                        , 5000//执行时间间隔
                        , TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void disconnect() throws RemoteException {
            isConnected = false;

            handler.post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(RemoteService.this, "idsconnect", Toast.LENGTH_SHORT).show();
                }
            });
            //断联后把定时任务停掉
            scheduledFuture.cancel(true);

        }

        @Override
        public boolean isConnection() throws RemoteException {
            return isConnected;
        }
    };
    //消息服务
    private IMessageService messageService = new IMessageService.Stub() {
        @Override
        public void sendMessage(final Message message) throws RemoteException {
            Log.d(TAG, "sendMessage: " + message.getContent());
            //打印消息内容
            handler.post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(RemoteService.this, message.getContent(), Toast.LENGTH_SHORT).show();
                }
            });
            if (isConnected) {
                message.setSendSuccess(true);
            } else {
                message.setSendSuccess(false);
            }
        }

        @Override
        public void registerMessageReceiveListener(MessageReceiverListener messageReceiverListener) throws RemoteException {
            if (messageReceiverListener != null) {//如果消息监听不为空,就把它添加进来(注册)
                messageReceiverListenerRemoteCallbackList.register(messageReceiverListener);
            }
        }

        @Override
        public void unRegisterMessageReceiveListener(MessageReceiverListener messageReceiverListener) throws RemoteException {
            if (messageReceiverListener != null) {//取消注册
                messageReceiverListenerRemoteCallbackList.unregister(messageReceiverListener);
            }
        }
    };
    private IServiceManager serviceManager = new IServiceManager.Stub() {
        @Override
        public IBinder getService(String serviceName) throws RemoteException {
            if (IConnectionService.class.getSimpleName().equals(serviceName)) {
                return connectionService.asBinder();
            } else if (IMessageService.class.getSimpleName().equals(serviceName)) {
                return messageService.asBinder();
            } else if (Messenger.class.getSimpleName().equals(serviceName)) {
                return messenger.getBinder();
            } else {
                return null;
            }
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return serviceManager.asBinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
        IConnectionService.Default aDefault = new IConnectionService.Default() {
            @Override
            public void connect() throws RemoteException {
                super.connect();
            }

            @Override
            public void disconnect() throws RemoteException {
                super.disconnect();
            }

            @Override
            public boolean isConnection() throws RemoteException {
                return super.isConnection();
            }

            @Override
            public IBinder asBinder() {
                return super.asBinder();
            }
        };
    }
}

3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">


    <Button
        android:id="@+id/bt_conect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="connect" />

    <Button
        android:id="@+id/bt_disconnect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="disconnect" />

    <Button
        android:id="@+id/bt_isConnected"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="isConnected" />


    <Button
        android:id="@+id/bt_send_message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="send" />

    <Button
        android:id="@+id/bt_register_listener"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="register" />

    <Button
        android:id="@+id/bt_unregister"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unregister" />
    <Button
        android:id="@+id/bt_messenger"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="messenger" />
</LinearLayout>

4.Message

package com.kunminx.exampleaidlmukewang.entity;

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

/**
 * @ClassName Message
 * @Description TODO
 * @Author ${孙伟豪}
 * @Date 2020/11/6 14:54
 * @Version 1.0
 */
public class Message implements Parcelable {//实现序列化,不然不行
    private String content;//发送的内容
    private boolean isSendSuccess;//发送的状态


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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.content);
        dest.writeByte(this.isSendSuccess ? (byte) 1 : (byte) 0);
    }

    public Message() {
    }

    protected Message(Parcel in) {
        this.content = in.readString();
        this.isSendSuccess = in.readByte() != 0;
    }

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

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public boolean isSendSuccess() {
        return isSendSuccess;
    }

    public void setSendSuccess(boolean sendSuccess) {
        isSendSuccess = sendSuccess;
    }
    //inout的时候添加
    public void readFromParcel(Parcel parcel){
        content=parcel.readString();
        isSendSuccess=parcel.readByte()==1;
    }
}

2.步骤:

1.初始化信使代理

在RemoteService初始化之后,MainActivity就可以获取到它

//注意:下面这些都是运行在子线程中的,所有Toast要线程通信
    private Messenger messenger = new Messenger(handler);

在这里插入图片描述

else if (Messenger.class.getSimpleName().equals(serviceName)) {
                return messenger.getBinder();
            }

2.在MainActivity(客户端)中获取Messager

在这里插入图片描述

//信使来进行通信
    private Messenger messengerProxy;
//信使代理初始化
                    messengerProxy=new Messenger(serviceManagerProxy.getService(Messenger.class.getSimpleName()));

3.在MainActivity中执行消息发送,发送到RemoteService

Message message1=new Message();//自定义的序列化消息
                    message1.setContent("hello! 我是来自Main,Messager乘车员");//消息内容
                    Bundle bundleData=new Bundle();//初始化Bundle
                    bundleData.putParcelable("message",message1);//Bundle可以传递序列化数据
                    android.os.Message mMessage=new android.os.Message();//初始化android.os.Message
                    mMessage.setData(bundleData);//android.os.Message的参数是Bundle
                    messengerProxy.send(mMessage);//这里是信使代理发送消息,参数是android.os.Message,不要搞错成message

4.在Remote中打印出来

因为相当于在子线程中执行的,所以要用在这里插入图片描述

Bundle bundle = msg.getData();
            bundle.setClassLoader(Message.class.getClassLoader());//注意,这句可以解决序列化问题
            Message message = bundle.getParcelable("message");
            Toast.makeText(RemoteService.this, "remoteServiceToast了:" + message.getContent(), Toast.LENGTH_SHORT).show();
在此,消息发送就成功了,下面是消息的回复,remoteService发送消息回MainActivity

图解:在这里插入图片描述

5.在RemoteService的Handle中执行消息发送

try {
                Messenger clientMessenger = msg.replyTo;//初始化msg的消息回复,这个是消息回复用的,可以发回给MainActivity
                Message reply = new Message();
                reply.setContent("来之remoteService的回复");
                android.os.Message data = new android.os.Message();
                data.replyTo = clientMessenger;//令android.os.Message的replaceTo等于msg.replayTo
                bundle = new Bundle();
                bundle.putParcelable("message", reply);
                data.setData(bundle);
                clientMessenger.send(data);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

在这里插入图片描述

6.MainActivity接收消息,并Toast出来

在这里插入图片描述

Bundle bundle = msg.getData();//获取数据
            bundle.setClassLoader(Message.class.getClassLoader());//注意,这句可以解决序列化问题
            final Message message = bundle.getParcelable("message");//key获取值
            handle.postDelayed(new Runnable() {//延迟执行
                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, "MainActivity打印了:"+message.getContent(), Toast.LENGTH_SHORT).show();
                }
            }, 1000);

7.最后加上这一句与添加到Messenger中在这里插入图片描述

mMessage.replyTo=clientMessager;

把handle添加到Handle中

//接收子进程的消息
    private Messenger clientMessenger =new Messenger(handle);//参数,Handle

图解:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android Studio中的AIDLAndroid接口定义语言的缩写,它是一种用于定义Android应用程序中的进程间通信(IPC)接口的语言。使用AIDL,您可以定义客户端和服务之间的接口,以便它们可以相互通信和交换数据。在Android应用程序中,AIDL通常用于实现跨进程通信,例如在应用程序中使用服务来执行后台任务。 ### 回答2: Android Studio AIDLAndroid Interface Definition Language)是一种用于在Android应用程序中进行进程间通信(IPC)的技术。它允许不同应用程序或同一应用程序中的不同进程之间进行数据和指令的传输和共享。AIDL基于Binder机制实现,是许多Android系统服务和框架中广泛使用的IPC技术。 在Android Studio使用AIDL,首先需要创建一个AIDL接口,该接口定义了可用于在不同进程之间进行通信的方法。一旦创建了该接口,它可以在应用程序中使用,与其他进程交换数据和指令。AIDLAndroid系统自动创建和管理,不需要手动实现Binder机制。 使用AIDL的主要优点是实现非常方便,而且可以跨多个进程使用。它使得应用程序能够高效地共享数据和指令,并允许不同进程之间进行通信,从而扩展了Android应用程序的功能和交互性。 一些开发人员可能认为AIDL的学习和使用有一定的难度,但是一旦了解了AIDL的基本原理和使用方法,就能够轻松实现IPC功能,并创建更高效的Android应用程序。总之,通过使用AIDLAndroid应用程序开发人员可以实现更好的应用程序设计和创新,并提高应用程序的性能和用户体验。 ### 回答3: Android Studio AIDLAndroid Interface Definition Language)是一种跨进程通信的机制,用于在不同的Android组件之间进行通信。 AIDL类似于SOAP(Simple Object Access Protocol),RPC(Remote Procedure Call)或CORBA(Common Object Request Broker Architecture),它是一种高级的RPC机制,允许不同的应用程序使用相同的接口来进行通信。 AIDL的主要作用是允许一个应用程序通过一个中间层向另外的一个应用程序发送请求,并且读取响应信息。它是Android操作系统提供的默认RPC机制,由于基于Binder实现,因此具备更高的性能和更好的稳定性。 AIDL可以让你定义一组接口,用来描述应用组件之间的通信方法,包括输入和输出参数。AIDL文件定义完毕后,你可以使用Android Studio自动生成AIDL接口的Java类,以便你可以跨进程访问该接口。 使用AIDL的好处是,可以将系统拆分成独立的组件,这些组件可以在不同的进程之间进行通信,从而实现了更好的资源利用和更加灵活的架构设计。 总之,Android Studio AIDL是一种强大的跨进程通信机制,有助于提高应用程序的性能和稳定性,从而让我们能够更好地设计和开发更高效的Android应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值