Android跨进程通信,Android面试总结

本文详细介绍了Android中实现跨进程通信的几种常见方式,包括Bundle通过Intent传递数据、文件共享、使用ContentProvider、Socket通信以及通过Messenger实现的消息传递。每种方式都有其特点和适用场景,例如Bundle适合简单数据传递,ContentProvider提供统一的数据访问接口,Socket适用于网络通信,而Messenger则在应用内部服务间通信中发挥作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

随着业务的发展,工程的逐渐增大与开发人员增多,很多工程都走向了模块化、组件化、插件化道路,来方便大家的合作开发与降低业务之间的耦合度。现在就和大家谈谈模块化的交互问题,首先看下模块化的几个优势。

模块化的优势
  1. 结构清晰:业务独立,代码实现分离,不会搅在一起。

  2. 便于协作:每个开发同学只要自己负责的模块,没有太多的耦合。

  3. 便于维护:各模块管理自己的代码、布局、资源,主工程可以方便添加与移除。

    特点:高内聚、低耦合。

  • Bundle
  • 文件共享
  • ContentProvider
  • Socket
  • Messenger
  • AIDL

Bundle

先看下拨打电话的代码

Uri uri = Uri.parse(“smsto:10086”);
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
Bundle bundle = new Bundle();
bundle.putString(“sms_body”, “SMS Text”);
intent.putExtras(bundle);
// intent.putExtra(“sms_body”, “SMS Text”);
startActivity(intent);

可见,通过将数据存储在Intent的Bundle中,可以在不同进程/APP间传递数据。

文件共享

通过将数据写入到一个文件中,不同进程可以对这个文件进行读取访问,来达到跨进程通信目的。
不过,多进程同时访问一个文件,存在并发和IO性能低的问题。

ContentProvider

Android四大组件之一,提供访问数据的统一格式。数据来源可以是文件、数据库。
可以对外提供访问的接口,实现跨进程/APP访问。

private void readContacts() {
//用于查询电话号码的URI
Uri phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
// 查询的字段
String[] projection = {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,//通讯录姓名
ContactsContract.CommonDataKinds.Phone.DATA1, “sort_key”,//通讯录手机号
};
Cursor cursor = getContentResolver().query(phoneUri, projection, null, null, null);
while ((cursor.moveToNext())) {
String name = cursor.getString(0);
String phone = cursor.getString(1);
}
}

Socket

Socket主要分为两种

  • StreamSocket:基于TCP协议的封装,以流的方式提供数据交互服务,提供了稳定的双向通信,通过“三次握手”建立连接,传输数据具有较高的稳定性。
    Java中客户端使用Socket类,服务器端使用ServerSocket类。
  • DatagramSocket:基于UDP协议的封装,以数据报文的方式提供数据交互服务,提供了不稳定的单向通信,具有更好的执行效率,由于基于无连接的方式,传输数据不稳定,不保证数据的完整性。
    Java中使用DatagramPacket类,表示数据报包;DatagramSocket类,进行端到端通信。

Messager

底层也是通过封装AIDL来实现的,所以使用的方式和AIDL基本类似。

1.在服务端进程Service中创建Messenger对象,用来接收客户端发来的Message数据,和获取客户端Messenger对象,并给客户端发Message数据。
2.创建客户端Messenger对象,用来接收服务端数据。
3.客户端绑定服务端服务,并获取服务端Messenger对象,用来给服务端发Message数据。
4.通过服务端Messenger发消息,将客户端Messenger对象,添加到Message.replyTo。

public class MsgerService extends Service {
private Messenger mServerMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);

// 接收客户端发过来的消息
switch (msg.what) {
case 1000:

Toast.makeText(getBaseContext(), “” + msg.arg1, Toast.LENGTH_SHORT).show();

Message cMsg = Message.obtain();
cMsg.what = msg.what;
Bundle bundle = new Bundle();
bundle.putString(“name”, “Jim”);
cMsg.obj = bundle;

// 获取客户端的Messenger对象,需要客户端在发送消息时设置
Messenger cMsger = msg.replyTo;
try {
// 给客户端发送消息
cMsger.send(cMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
});
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mServerMessenger.getBinder();
}
}

public class ClientActivity extends Activity {
private TextView mNameTxt;

/**

  • 客户端Messenger对象,用来接收服务端数据
    */
    private Messenger mClientMessenger = new Messenger(new Handler() {
    @Override
    public void handleMessage(Message msg) {
    super.handleMessage(msg);
    switch (msg.what) {
    case 1000:
    // 接收服务端数据
    Bundle bundle = (Bundle) msg.obj;
    mNameTxt.setText(bundle.getString(“name”));
    break;
    }
    }
    });

/**

  • 服务端Messenger对象,建立连接时获取,用来给服务端发消息
    */
    private Messenger mServerMessenger;
    private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    // 获取服务端Messenger对象
    mServerMessenger = new Messenger(service);
    }

@Override
public void onServiceDisconnected(ComponentName name) {
mServerMessenger = null;
}
};

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

mNameTxt = (TextView) findViewById(R.id.name);

// 绑定远端服务
Intent intent = new Intent(this, MsgerService.class);
bindService(intent, mConnection, BIND_AUTO_CREATE);

findViewById(R.id.bind).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

int number = (int) (Math.random() * 100);
Message msg = Message.obtain();
msg.what = 1000;
msg.arg1 = number;
msg.replyTo = mClientMessenger;

// 给服务端发送消息
if (mServerMessenger != null) {
try {
mServerMessenger.send(msg);

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》开源

Android优秀开源项目:

  • ali1024.coding.net/public/P7/Android/git

最后

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

  • Android前沿技术大纲

  • 全套体系化高级架构视频

Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
h7-1649663679070)]

  • 全套体系化高级架构视频

    [外链图片转存中…(img-r326Ispd-1649663679071)]

Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值