2025年2024年Android 基于Message的进程间通信 Messenger完全解析,2024年最新面试考点安排

2024年Android 基于Message的进程间通信 Messenger完全解析,2024年最新面试考点安排最后 如果你看到了这里 觉得文章写得不错就给个赞呗 如果你觉得那里值得改进的 请给我留言 一定会认真查询 修正不足 谢谢 最后针对 Android 程序员 我这边给大家整理了一些资料 包括不限于高级 UI 性能优化 移动架构师 NDK 混合式开发 ReactNative

大家好,我是讯享网,很高兴认识大家。

最后

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。


讯享网

最后针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

可以看到,我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。

这样的进程间通信是不是很爽呢?

  • 基于Message,相信大家都很熟悉
  • 支持回调的方式,也就是服务端处理完成长任务可以和客户端交互
  • 不需要编写aidl文件

此外,还支持,记录客户端对象的Messenger,然后可以实现一对多的通信;甚至作为一个转接处,任意两个进程都能通过服务端进行通信,这个后面再说。

看到这,有没有一些的小激动,我们可以不写aidl文件,方便的实现进程间通信了,是不是又可以装一下了。哈,下面看个简单的例子。


二、通信实例

这个例子,通过两个apk演示,一个apk是Server端,一个是Client端;

(1) Server端

代码

package com.imooc.messenger_server;

import android.app.Service;

import android.content.Intent;

import android.os.Handler;

import android.os.IBinder;

import android.os.Message;

import android.os.Messenger;

import android.os.RemoteException;

public class MessengerService extends Service

{

private static final int MSG_SUM = 0x110;

//最好换成HandlerThread的形式

private Messenger mMessenger = new Messenger(new Handler()

{

@Override

public void handleMessage(Message msgfromClient)

{

Message msgToClient = Message.obtain(msgfromClient);//返回给客户端的消息

switch (msgfromClient.what)

{

//msg 客户端传来的消息

case MSG_SUM:

msgToClient.what = MSG_SUM;

try

{

//模拟耗时

Thread.sleep(2000);

msgToClient.arg2 = msgfromClient.arg1 + msgfromClient.arg2;

msgfromClient.replyTo.send(msgToClient);

} catch (InterruptedException e)

{

e.printStackTrace();

} catch (RemoteException e)

{

e.printStackTrace();

}

break;

}

super.handleMessage(msgfromClient);

}

});

@Override

public IBinder onBind(Intent intent)

{

return mMessenger.getBinder();

}

}

服务端就一个Service,可以看到代码相当的简单,只需要去声明一个Messenger对象,然后onBind方法返回mMessenger.getBinder();

然后坐等客户端将消息发送到handleMessage想法,根据message.what去判断进行什么操作,然后做对应的操作,最终将结果通过 msgfromClient.replyTo.send(msgToClient);返回。

可以看到我们这里主要是取出客户端传来的两个数字,然后求和返回,这里我有意添加了sleep(2000)模拟耗时,注意在实际使用过程中,可以换成在独立开辟的线程中完成耗时操作,比如和HandlerThread结合使用。

注册文件

<service

android:name=“.MessengerService”

android:enabled=“true”

android:exported=“true”>

别忘了注册service,写完以后直接安装。

(二)客户端

Activity

package com.imooc.messenger_client;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.Handler;

import android.os.IBinder;

import android.os.Message;

import android.os.Messenger;

import android.os.RemoteException;

import android.support.v7.app.AppCompatActivity;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.LinearLayout;

import android.widget.TextView;

public class MainActivity extends AppCompatActivity

{

private static final String TAG = “MainActivity”;

private static final int MSG_SUM = 0x110;

private Button mBtnAdd;

private LinearLayout mLyContainer;

//显示连接状态

private TextView mTvState;

private Messenger mService;

private boolean isConn;

private Messenger mMessenger = new Messenger(new Handler()

{

@Override

public void handleMessage(Message msgFromServer)

{

switch (msgFromServer.what)

{

case MSG_SUM:

TextView tv = (TextView) mLyContainer.findViewById(msgFromServer.arg1);

tv.setText(tv.getText() + “=>” + msgFromServer.arg2);

break;

}

super.handleMessage(msgFromServer);

}

});

private ServiceConnection mConn = new ServiceConnection()

{

@Override

public void onServiceConnected(ComponentName name, IBinder service)

{

mService = new Messenger(service);

isConn = true;

mTvState.setText(“connected!”);

}

@Override

public void onServiceDisconnected(ComponentName name)

{

mService = null;

isConn = false;

mTvState.setText(“disconnected!”);

}

};

private int mA;

@Override

protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//开始绑定服务

bindServiceInvoked();

mTvState = (TextView) findViewById(R.id.id_tv_callback);

mBtnAdd = (Button) findViewById(R.id.id_btn_add);

mLyContainer = (LinearLayout) findViewById(R.id.id_ll_container);

mBtnAdd.setOnClickListener(new View.OnClickListener()

{

@Override

public void onClick(View v)

{

try

{

int a = mA++;

int b = (int) (Math.random() * 100);

//创建一个tv,添加到LinearLayout中

TextView tv = new TextView(MainActivity.this);

tv.setText(a + " + " + b + " = caculating …");

tv.setId(a);

mLyContainer.addView(tv);

Message msgFromClient = Message.obtain(null, MSG_SUM, a, b);

msgFromClient.replyTo = mMessenger;

if (isConn)

{

//往服务端发送消息

mService.send(msgFromClient);

}

} catch (RemoteException e)

{

e.printStackTrace();

}

}

});

}

private void bindServiceInvoked()

{

Intent intent = new Intent();

intent.setAction(“com.zhy.aidl.calc”);

bindService(intent, mConn, Context.BIND_AUTO_CREATE);

Log.e(TAG, “bindService invoked !”);

}

@Override

protected void onDestroy()

{

super.onDestroy();

unbindService(mConn);

}

}

代码也不复杂,首先bindService,然后在onServiceConnected中拿到回调的service(IBinder)对象,通过service对象去构造一个mService =new Messenger(service);然后就可以使用mService.send(msg)给服务端了。

我们消息的发送在Btn.onclick里面:

Message msgFromClient = Message.obtain(null, MSG_SUM, a, b);

msgFromClient.replyTo = mMessenger;

if (isConn)

{

//往服务端发送消息

mService.send(msgFromClient);

}

那么服务端会收到消息,处理完成会将结果返回,传到Client端的mMessenger中的Handler的handleMessage方法中。

布局文件

<LinearLayout android:id=“@+id/id_ll_container”

xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:orientation=“vertical”

android:paddingBottom=“@dimen/activity_vertical_margin”

android:paddingLeft=“@dimen/activity_horizontal_margin”

android:paddingRight=“@dimen/activity_horizontal_margin”

android:paddingTop=“@dimen/activity_vertical_margin”

tools:context=“.MainActivity”>

<TextView

android:id=“@+id/id_tv_callback”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:text=“Messenger Test!”/>

<Button android:id=“@+id/id_btn_add”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“add”/>

效果图

可以看到,我们每点击一次按钮,就往服务器发送个消息,服务器拿到消息执行完成后,将结果返回。

整个通信的代码看起来还是相当的清爽的,那么大家有没有对其内部的原理有一丝的好奇呢?下面我们就来看下其内部是如何实现的。

对了,源码分析前,这里插一句,大家通过代码可以看到服务端往客户端传递数据是通过msg.replyTo这个对象的。那么服务端完全可以做到,使用一个List甚至Map去存储所有绑定的客户端的msg.replyTo对象,然后想给谁发消息都可以。甚至可以把A进程发来的消息,通过B进程的msg.replyTo发到B进程那里去。相关代码呢,可以参考官方的文档:service,注意下拉找:Remote Messenger Service Sample。


三、源码分析

其实Messenger的内部实现的,实际上也是依赖于aidl文件实现的。

(一)首先我们看客户端向服务端通信

服务端

服务端的onBind是这么写的:

public IBinder onBind(Intent intent)

{

return mMessenger.getBinder();

}

那么点进去:

public IBinder getBinder() {

return mTarget.asBinder();

最后

题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

Android开发8年,阿里、百度一面惨被吊打!我是否应该转行了?

【Android进阶学习视频】、【全套Android面试秘籍】

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

最后

题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

[外链图片转存中…(img-9korf6LM-12)]

【Android进阶学习视频】、【全套Android面试秘籍】

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

小讯
上一篇 2025-01-26 19:29
下一篇 2025-03-26 13:55

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/56492.html