Androiod多进程

为何使用多进程

 什么情况下,我们会去想到使用多进程呢? 就我个人开发实践中就多次使用了Android多进程机制,如项目中的推送业务开发,提出要求如下:  - 不能影响主业务的代码稳定运行   - 不能占用主业务的进程内存   - 不受主业务进程生命周期影响,独立存在和运行    要满足这3个需求下,不由就会想到在应用内开辟一个新进程单独给推送业务使用,因为其特点明显:  - 独立进程运行出现了崩溃和异常而退出并不会影响其他进程运行  - 独立进程意味着有系统开辟的独立内存空间,不会和其他进程产生占用内存,影响其内存分配问题  - 独立进程的启动和退出可以完全不依赖用户对应用的使用,可以独立启动、退出,也可以不会因应用退出而结束了进程。   可以看出明显满足上述要求,那如何开辟呢。Android系统中使用多进程配置还是挺简单的,只要在Manifest中组件(如Service、Activity)直接配置android:process=“”属性即可完成配置。 Android下的多进程使用虽然很简单,但是如果不注意细节就很容易出现一些细节上的问题。

开发细节

android:process=”:XXX”与android:process=”XXX”区别

  android:process=":xxx"与android:process="XXX"不仅仅是用来定义当前进程的名字,一般情况各组件的进程名均为当前应用的包名。那有":"开头意味着:  - 1、进程名字是在当前进程名(即包名)下追加命名,如当前包名为com.terminal.a,那么第一种情况下的进程名就是com.terminal.a:xxx而第二种就直接以"xxx"来命名;  - 2、":"表示当前新进程为主进程(进程名为包名)的私有子进程,其他应用的组件不可以和它跑在同一个进程中。而后者则是全局的进程,其他应用通过设置相同的ShareUID可以和它跑在同一个进程。

如何判断是当前应用主进程,方法如下

 private boolean isLocalAppProcess(String packName) {    int myPid = Process.myPid();    ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);    ActivityManager.RunningAppProcessInfo myProcess = null;    List runningProcesses = activityManager.getRunningAppProcesses();    if (runningProcesses != null) {        Iterator var11 = runningProcesses.iterator();        while (var11.hasNext()) {            ActivityManager.RunningAppProcessInfo process = (ActivityManager.RunningAppProcessInfo) var11.next();            Log.i("chuan", "process=" + process.processName + " pid=" + process.pid);            if (process.pid == myPid) {                myProcess = process;                break;            }        }    }    if (myProcess == null) {        Log.i("chuan", "Could not find running process for %d" + myPid);        return false;    } else {        return myProcess.processName.equals(packName);    }}

多应用同名进程过滤,保活一个

 假如我们开发的是一个Sdk,需要给多个应用使用,如果多个应用都嵌入了我们的Sdk并且都装在了同一个手机上,如果同时让多个相同业务的进程一起在后台嗨着,这样不仅给用户带来头疼和影响(想想那么多的推广消息和广告同时间而来,以及严重耗电),也给Sdk后端带来负载压力,故此我们只能独活一个进程,让其他应用相同业务进程休眠。 如何实现,这里只讲思路,不便公开代码。不论用什么手段唤起进程,系统fork新进程以及对进程的管理都是有序有规则,不会乱象丛生,因为系统不仅fork进程,还要维护管理其生命周期,对每个进程的生命周期管理,当内存不足,还会根据优先级来杀死进程。但它们都有一个统一编制的Id,这个是有序的,不会重复,故我们根据遍历的方式来查找这些进程,并且只保留一个进程。

进程间通信方法

 这块知识点详细展开很多,后面有计划专门写个AIDL进程间的通信。进程间实现通信的方法可以是: -  通过Intent/Bundle传递数据,如在4大组件间,通过Intent向service传递数据 -  通过文件缓存方式,一个进程写过之后,另一个进程来读,但不能同时 -  通过Socket方式,例如系统中进程服务也有用如此方式 -  通过AIDL来实现进程间通信,可以做到多端连接,异步通信,避免阻塞  - 通过四大组件实现进程间通信:广播、Activity、Service、ContentProvider

开发中陷阱和坑

Application多次重建

 当新进程中组件被外部激活或者唤醒,系统会首先fork该组件所在进程,并创建该进程的Application对象并初始化,然后在启动该组件,这个和启动应用的流程一样。如上文Push进程启动的时候,就会导致应用的Aplication会被初始化一次。这个情况下就会出现一个应用的Aplication被多次创建并初始化,若应用配置定义自己的Aplication,并在oncreate()函数中进行了自己业务相关的逻辑,常见的是应用启动统计,这个时候就会由于其他进程如后台进程启动而导致了应用启动次数统计增加而且实际应用根本没有启动,这样就导致数据不准。这个时候怎么办呢?就可以利用上文中"如何判断是当前应用进程,方法如下"方法 在Application的onCreate()初始化中增加判断代码,当不是的当前应用进程直接return,不要走下面逻辑代码public void onCreate() {    super.onCreate();    if (!isLocalAppProcess(getPackageName())) {        return;    }    *******    应用内相关逻辑    ******}

Static静态变量缓存失效以及单实例

在实际开发中常用static变量来作为单实例,实际就是用来缓存唯一的对象,而在跨进程时候,如果希望引用其他进程中已经初始化过的static变量,会发现直接获取的是null。这个是因为进程间内存区域是独立的,系统进程沙箱模式。导致根本就访问不了另一个进程的变量内存地址,更获取不到其值。

SharePreferenc通信失效

 从上午可以多进程之间内存是不共享,那如何通信呢?刚开始的时候,尝试用过文件保存啊,用SharePreference来保存,但失效并没有用。可能好奇为何啊,又不是上述的内存变量访问方式,怎么不可以通过文件来访问。这个其实由于SharePreference实现机制导致的,sharePreference每次操作读写并非实时向文件同步,而是向进程中的缓存的Map对象的sharePrefenceImpl对象同步,每个进程维护的是当前的map对象,而非文件,只有当进程退出之后,才会写入文件,系统这样设计主要是为了性能着想,如果每次都进行IO操作必定阻塞,故视为轻量级的文件保存之一吧,所以还是不能通过sharePrefence来通信,如果应用进程没有退出,那么获取到的sharePrefence仅仅是文件中上一次保存的始值。 同时其他文件通信方式也要注意,不能同时进行读写操作。否则这就可能造成资源的竞争访问,导致诸如数据库损坏、数据丢失等。一般在多线程的情况下我们有锁机制控制资源的共享,但是在多进程中比较难,虽然有文件锁、排队等机制,但是在Android里很难实现。

更多相关文章

  1. Android中合多图片和文字合成PDF文件---路很长
  2. ANDROID XML图像资源文件详细讲解(一)
  3. Android多媒体学习七:访问网络上的Audio对应的M3U文件,实现网络音
  4. Layout___模块重用之include布局整合
  5. apk签名不一致终极解决方案
  6. 在Android(安卓)Studio上搭建OpenCV 开发环境
  7. android java进程管理(六)之apk进程的回收
  8. android遥控器新增自定义的键值+用遥控器按键实现软键盘字符键的
  9. Android上利用SDK的BluetoothAPI实现传送文件

随机推荐

  1. 房贷利率有没有套路?这是我见过最透彻的Py
  2. 突发!公信宝被查封一窝端,爬虫可能又惹祸了
  3. 推荐一些能能提高生产力的 Python 库
  4. Python 中更优雅的日志记录方案
  5. 这个 Python 库有必要好好学学
  6. Python一行代码搞定炫酷可视化,你需要了解
  7. 震惊了!每30秒学会一个Python小技巧,Github
  8. GitHub Actions,卧槽!牛批!
  9. 如何用 Python 给照片换色
  10. 原创丨我在 GitHub 上发现了哪些好的学习