IPC-Messenger

IPC传递的都是序列化的数据(序列化和反序列化的核心思想是对象状态的保存和重建),序列化有两种,Parcelable、Serializable

知识点

  • 同一个app如果有多个进程,每个进程会对应创建一个application对象,每一个系统都会单独分配一个虚拟机。进程间无法直接进行数据传递,需要通过aidl,binder,网络,文件共享等方式传递数据。静态成员和单例模式在不同进程间作用失效。
  • 序列化
    • Serializable或者Externalizable,非static和transient修饰的,核心类:ObjectOutputStream、ObjcetInputStream
    • Parcelable,核心类:Parcel
    • 网络传输:服务器将Java对象序列化为json/xml文件,文件以流的方式传输,客户端再将json/xml文件反序列化为对应语言的对象
  • Binder
  • AIDL(使用的对象必须是实现了Parcelable的类)
    • 远程Service
      • aidl:底层都是使用AIDL,用于不同进程的服务端和客户端通讯,可以处理多线程的进程间通讯
      • Messenger:Messenger实现Parcelable接口,是一种封装好的AIDL,方便开发者进行跨进程通讯,主要用于不同进程的服务端和客户端的单线程通讯,不能处理多线程的进程间通讯

Messenger使用demo

    需要注意如果传递的是序列化对象,bundle.getXXX之前调用bundle.setClassLoader(getClass().getClassLoader()),不然会报错ClassNotFoundException,应用中存在两种类加载器它们分别是BootClassLoader和PathClassLoader。

<--清单文件配置-->
<--客户端,在app默认进程-->
<activity
    android:name="com.hxx.arouter.messenger.TestMasengerClient"
    android:label="@string/app_name"
    android:screenOrientation="portrait" >
    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<--服务端,指定不同进程-->
<service android:name="com.hxx.arouter.messenger.TestMessengerService"
    android:process=":school"/>
/**
 * 客户端activity代码,1.绑定服务 2.创建handler,接收服务端消息 
 * 3.获取服务端的messenger 4.创建消息,messenger回复服务端消息
 * 5.传递的消息类都是实现了Parcelable接口的
 */
public class TestMasengerClient extends Activity {

    private TextView recieve;
    private ServiceConnection serviceConnection;
    private Messenger serviceMessenger;
    private Messenger clientMassenger;

    private Handler mHandler = new Handler(){
        @Override public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            Bundle bundle = msg.getData();
            // bundle.getXXX之前调用,不然会报错ClassNotFoundException,应用中存在两种类加载器它们分别是BootClassLoader和PathClassLoader.
            bundle.setClassLoader(getClass().getClassLoader());

            TeacherBean teacher = bundle.getParcelable("teacher");
            String say = bundle.getString("say");

            //服务端返回的消息
            if (teacher != null){
                Log.e("msg-client-接收消息", teacher.toString()+" >>> "+say);
                recieve.setText("接收消息:"+teacher.toString()+" >>> "+say);
            }
        }
    };
    @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_masenger);
        TextView send = findViewById(R.id.send);
        recieve = findViewById(R.id.recieve);

        //1.绑定服务
        Intent intent = new Intent();
        intent.setClassName(this,"com.hxx.arouter.messenger.TestMessengerService");

        serviceConnection = new ServiceConnection() {
            @Override public void onServiceConnected(ComponentName name, IBinder service) {
                Toast.makeText(TestMasengerClient.this, "bind success", Toast.LENGTH_SHORT).show();
                //2.获取服务端的messenger,用于发消息
                serviceMessenger = new Messenger(service);
            }
            @Override public void onServiceDisconnected(ComponentName name) {
                Toast.makeText(TestMasengerClient.this, "Disconnected", Toast.LENGTH_SHORT).show();
                serviceMessenger = null;
            }
        };
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

        //创建客户端的messenger,发送给服务器端
        clientMassenger = new Messenger(mHandler);

        send.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                //2. 客户端发送消息 Messenger handler message
                Message message = Message.obtain(null,1);
                Bundle bundle = new Bundle();
                StudentBean studentBean = new StudentBean("张三", "幼稚园");
                String s_say = "我英语不好";
                bundle.putParcelable("student", studentBean);
                bundle.putString("say",s_say);
                message.setData(bundle);

                message.replyTo = clientMassenger;
                try {
                    if (serviceMessenger != null){
                        serviceMessenger.send(message);
                    }
                    Log.e("msg-client-发送消息",studentBean.toString()+" >>> "+s_say);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

    }


    @Override public void finish() {
        super.finish();
        unbindService(serviceConnection);
    }
}
/**
 * 1.继承service 2.创建handler 3.创建相应的Messenger,设置IBinder 4.接收客户端消息 
 * 5.回复客 户端消息
 */
public class TestMessengerService extends Service {

    //1.创建handler
    private Handler mHandler = new Handler(){
        @Override public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            switch (msg.what){
                case 1:
                    //收到客户端消息
                    // bundle.getXXX之前调用,不然会报错
                    Bundle data = msg.getData();
                    data.setClassLoader(getClass().getClassLoader());
                    String s_say = data.getString("say");
                    StudentBean student = data.getParcelable("student");
                    Toast.makeText(TestMessengerService.this, student.toString()+" >>> "+s_say, Toast.LENGTH_SHORT).show();
                    Log.e("msg-service-接收消息",student.toString()+" >>> "+s_say);


                    //给客户端发消息
                    Message serviceMsg = Message.obtain(null,2);
                    Bundle bundle = new Bundle();
                    TeacherBean teacherBean = new TeacherBean("王老师", "英语老师");
                    String t_say = "每天做英语阅读题";
                    bundle.putParcelable("teacher", teacherBean);
                    bundle.putString("say",t_say);
                    serviceMsg.setData(bundle);

                    Log.e("msg-service-发送消息",teacherBean.toString()+" >>> "+t_say);

                    try {
                        if (msg.replyTo != null){
                            msg.replyTo.send(serviceMsg);
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
            }

        }
    };

    //2.通过刚刚创建的Handler创建相应的Messenger
    private final Messenger messenger = new Messenger(mHandler);


    @Nullable @Override public IBinder onBind(Intent intent) {
        //3.将设置binder
        return messenger.getBinder();
    }
}
<--简单布局-->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"     
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/send"
        android:text="客户端发送消息"
        android:layout_marginTop="20dp"
        android:background="@drawable/base_17c6cf_5"
        android:textColor="#ffffff"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:text="客户端接收消息"
        android:layout_marginTop="20dp"
        android:background="@drawable/base_ff7c29_5"
        android:textColor="#ffffff"
        android:layout_gravity="right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/recieve"
        android:text="Msg:"
        android:layout_marginLeft="25dp"
        android:layout_marginTop="10dp"
        android:textColor="#333333"
        android:layout_gravity="right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值