多进程通信方式以及带来一系列问题

网络 通信技术
Android中开启多进程只有一种方法,就是在AndroidManifest.xml中注册Service、Activity、Receiver、ContentProvider时指定android:process属性。

[[434195]]

本文转载自微信公众号「Android开发编程」,作者 Android开发编程。转载本文请联系Android开发编程公众号。

前言

今天来讲解下:多进程通信方式以及带来的问题,方便在项目中遇到问题及时的处理;

一、Android中多进程详解

1、定义

  • Android的多进程通信即IPC是指两个进程之间进行数据交换;
  • 进程一般指一个执行单元,在PC和移动设备中指一个程序或应用;
  • 最简单的情况下,Android应用中只有一个进程,包含一个线程,即主线程,也叫作UI线程,只能在此线程更新操作UI;
  • 普通情况下是不需要多进程的,但是当应用需要更多的内存或者某些特殊的Module或特殊的需求需要运行在多进程条件下;

2、开启多进程

Android中开启多进程只有一种方法,就是在AndroidManifest.xml中注册Service、Activity、Receiver、ContentProvider时指定android:process属性,例如:

<service 
    android:name=".MyService" 
    android:process=":remote"
</service> 
<activity 
    android:name=".MyActivity" 
    android:process="com.test.remote2"
</activity> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

 

我们为MyService和MyActivity指定的android:process属性值有所不同,它们的区别如下:

  • :remote:以:开头是一种简写,系统会在当前进程名前附件当前包名,完整的进程名为:com.test:remote,同时以:开头的进程属于当前应用的私有进程,其它应用的组件不能和它跑在同一进程;
  • com.test.remote2:这是完整的命名方式,不会附加包名,其它应用如果和该进程的ShareUID、签名相同,则可以和它跑在同一个进程,实现数据共享;

3、Android中的多进程通信方式

多进程通信方式主要有以下几种,它们之间各有优缺点,可根据使用场景选择选择:

  • AIDL:功能强大,支持进程间一对多的实时并发通信,并可实现 RPC (远程过程调用);
  • Messenger:支持一对多的串行实时通信, AIDL 的简化版本;
  • Bundle:四大组件的进程通信方式,只能传输 Bundle 支持的数据类型;
  • ContentProvider:强大的数据源访问支持,主要支持 CRUD 操作,一对多的进程间数据共享,例如我们的应用访问系统的通讯录数据;
  • BroadcastReceiver:即广播,但只能单向通信,接收者只能被动的接收消息;
  • 文件共享:在非高并发情况下共享简单的数据;
  • Socket:通过网络传输数据;

二、 多进程带来的问题

1、静态变量失效

在一个Activity中新建一个静态变量TEST_STATIC,并在RemoteActivity1中的onStartOtherRemoteActivity方法中自增,之后启动RemoteActivity2,并在2中打印TEST_STATIC的值;

public static int TEST_STATIC = 21; 
public void onStartOtherRemoteActivity(View view) { 
    TEST_STATIC++; 
    Log.e(TAG, "onStartOtherRemoteActivity: " + TEST_STATIC); 
    startActivity(new Intent(this, RemoteActivity2.class)); 

结果: 
// RemoteActivity1 log 
E/RemoteActivity1: onStartOtherRemoteActivity: 22 
// RemoteActivity2 log 
E/RemoteActivity2: onCreate: 21 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

并不相同的数值说明在多进程中静态变量是失效的,同样的因为静态变量带来的问题是单例模式的失效;

原因就是多进程时Android为其他进程分配了一个新的虚拟机,导致不同的虚拟机在内存上有不同的内存地址, 当在新的进程访问变量时,访问的其实是这个类在新的虚拟机中的副本,也就是相当于在:remote和.remote中各有一个RemoteActivity1类,而.remote访问的那个副本中的TEST_STATIC是没有进行自增操作的,所以还是会打印出21的初始数值,而在:remote中是自增过的22;

单例模式也是同样的解释,当在另一个进程中访问单例类时,在此进程中其实并没有进行初始化,所以才会失效;

2、线程同步机制失效

本质上跟静态变量类似,在一个进程锁住的是副本的对象,而在另一个副本中,内存都不同,所以肯定是无效的;

3、SharedPreferences可靠性下降

SharedPreferences不支持两个进程同时去执行写操作,否则会导致一定几率的数据丢失;

SharedPreferences的底层是通过读写XML文件实现的,并发写很可能导致问题,并发读写都不能保证不会出问题;

4、Application会被创建多次

当一个组件跑在一个新的进程中时,系统给新的进程分配一个新的虚拟机,就相当于应用又一次的重新启动,Application作为应用基础肯定也会被重新创建;

新建Application类,继承自Application,并在onCreate方法中输出当前进程的PID:

public class LApplication extends Application { 
    private static final String TAG = "LApplication"
    @Override 
    public void onCreate() { 
        super.onCreate(); 
        Log.e(TAG, "onCreate: " + android.os.Process.myPid()); 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

当依次开启进程后输出如下:

// Main 
E/LApplication: onCreate: 16031 
// RemoteActivity1 
E/LApplication: onCreate: 16127 
// RemoteActivity2 
E/LApplication: onCreate: 16202 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

Application被创建多次带来的问题是,有些时候会需要在Application中初始化些依赖,但是多进程就会随着Application的创建而重复初始化,可以在Application中设置一些条件跳过重复初始化部分;

// 根据pid获取进程名 
private String getAppName(int pid) { 
    String processName = null
    ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); 
    List<ActivityManager.RunningAppProcessInfo> list = am.getRunningAppProcesses(); 
    for (ActivityManager.RunningAppProcessInfo info : list) { 
        try { 
            if (info.pid == pid) { 
                processName = info.processName; 
                return processName; 
            } 
        } catch (Exception e) { 
            e.printStackTrace(); 
            return null
        } 
    } 
    return null

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

通过PID获取进程名,与包名做对比,只有跟包名一致时才做一些初始化工作;

总结

多进程实现今天没有讲,以后会讲解的;

多进程不难的,难的在于要克服困难,战胜自己;

【责任编辑:武晓燕 TEL:(010)68476606】

 

责任编辑:武晓燕 来源: Android开发编程
相关推荐

2010-01-06 10:44:36

2010-07-15 14:49:05

AIX TELNET

2023-03-13 17:10:48

2010-03-30 09:40:30

IE系统补丁

2018-03-29 08:25:54

主存储优化系列

2017-09-22 22:30:39

网络

2020-10-22 06:29:39

编程前端开发

2023-05-19 12:54:33

StabilityAI开源

2009-12-11 10:09:30

PHP INCLUDE

2011-06-16 10:46:50

思科网真

2021-11-16 15:04:39

物联网云计算网络安全

2020-04-08 08:32:05

腾讯数字政府智慧城市.人工智能

2021-02-07 12:42:27

Firefox火狐浏览器浏览器

2015-09-16 13:36:58

功能Edge浏览器

2021-07-08 11:34:04

微软Windows 11功能

2021-10-26 05:38:55

苹果 iOS 15.1 AirPods 3

2010-03-15 09:43:51

2022-03-24 14:20:52

Edge浏览器PDF 功能

2011-04-03 07:51:57

CCBN斐讯

2015-10-23 13:54:07

RFID技术FRAM物联网
点赞
收藏

51CTO技术栈公众号