安卓进程间通信及 App 保活

简介

多进程以及进程间通信机制虽然不是所有的app都能用到,但是这些知识必须要了解,同时app保活也是给用户提供更好的服务的方式,本文大家一起来了解一下。

多进程

1.一般情况下,一个应用程序就是一个进程,这个进程名称就是应用程序包名。每个进程都有自己独立的资源和内存空间,别的进程是不能任意访问其他进程的内存和资源的。
2.单进程的局限:每个进程所能使用的资源是有限,特别是内存,安卓系统对用户进程有严格的内存要求,超过此内存限制时,应用将OOM和崩溃。所以,Android引入了多进程的概念,它允许在同一个应用内,为了分担主进程的压力,将占用内存的某些页面单独开一个进程。
3.Android多进程创建很简单,只需要在AndroidManifest.xml的声明四大组件的标签中增加”android:process”属性即可。命名之后,就成了一个单独的进程。”android:process”属性以【:】开头为是有进程,否则为公共进程(必须含【.】)
4.多进程应用运行时application的onCreate()会执行多次,所以使用的时候就要根据进程名判断当前所处的进程来进行对应的初始化操作。
5.静态成员和单例失效:每个进程保持各自的静态成员和单例,相互独立。

进程间通信IPC方式

一、Intent/Bundle

Activity,Service,Receiver 都支持在 Intent 中传递 Bundle 数据,而 Bundle 实现了 Parcelable 接口,可以在不同的进程间进行传输。所以,在一个进程中启动了另一个进程的 Activity,Service 和 Receiver ,可以在 Bundle 中附加要传递的数据通过 Intent 发送出去。

二、文件共享

1.可以在进程中序列化数据对象到文件中,然后在另一个进程中反序列化这个对象。
2.SharedPreferences 由于系统对SP的读写有一定的缓存策略,使内存中有一份SP文件,导致系统对它的读写不可靠。当高频读写操作是,SP会有数据丢失的风险,所以IPC不建议采用这种方式。
3.使用三方的SP,进程安全—Tray - a SharedPreferences replacement for Android

三、Messager

Messager是基于AIDL实现的,客户端通过handler创建一个Messager,向服务器端通过message为载体把Messager传给服务端【在ServiceConnection对象中发送Messager】,服务端需要先获取到客户端发送来的Messager,然后通过这个Mesager给客户端发送message【onBind(messager.getBinder())】。
Messager里面 有一个Handler以串行的方式处理数据,不存在并发执行,也就不存在线程同步的问题了。

四、AIDL

AIDL 可以解决并发和跨进程调用方法的问题,其实Messenger 本质上也是 AIDL ,只不过Messager不适合处理大量并发的消息处理,也不支持跨进程调用方法。

通过编写aidl文件来设计想要暴露的接口,编译后会自动生成对应的java文件,服务器将接口的具体实现写在Stub中,用iBinder对象传递给客户端,客户端bindService的时候,用asInterface的形式将iBinder还原成接口,再调用其中的方法。

五、ContentProvider

系统四大组件之一,底层也是Binder实现,主要用来为其他APP提供数据,可以说天生就是为进程通信而生的。自己实现一个ContentProvider需要实现6个方法,其中onCreate是主线程中回调的,其他方法是运行在Binder之中的。ContentProvider有query,delete,insert等方法,看起来貌似是一个数据库管理类,但其实可以用文件,内存数据等等一切来充当数据源,query返回的是一个Cursor,可以自定义继承AbstractCursor的类来实现。

六、 Socket

Socket 是连接应用层与传输层之间的接口,常用的 Socket 类型有两种:流式 Socket(SOCK_STREAM)和数据报式 Socket(SOCK_DGRAM)。流式是一种面向连接的 Socket,针对于面向连接的 TCP 服务应用;数据报式 Socket 是一种无连接的 Socket ,对应于无连接的 UDP 服务应用。

保活策略

为了应对系统的内存回收导致的进程被杀死,派生出很多的进程保活策略,基本都是提升进程的等级,或者重启进程。

进程种类&优先级

进程的优先级取决于oom_adj的值,系统进程<0 普通进程>=0.
前台进程–等级最高0 屏幕上展示的
可视进程–等级1 屏幕上显示,但是被透明布局覆盖或者部分遮挡
服务进程–服务的进程,一般不会被kill,它们通常执行一些在后台播放或网络下载
后台进程–当内存不足容易被干掉
空进程–极易被干掉 用作缓存,以缩短下次在其中运行组件所需的启动时间。

方案一: 1像素Activity方案

监控手机锁屏解锁事件(广播接收者),在屏幕锁屏时启动1个像素的 Activity,在用户解锁时将 Activity 销毁掉。注意该 Activity 需设计成用户无感知的透明。
通过该方案,可以使进程的优先级在屏幕锁屏时间由4提升为最高优先级1。

方案二: 提升Service为前台Service,通过Notification

对于(4.3) API level < 18 :调用startForeground(ID, new Notification()),发送空的Notification ,图标则不会显示。 对于 API level >= 18:在需要提优先级的service A启动一个InnerService,两个服务同时startForeground,且绑定同样的 ID。Stop 掉InnerService ,这样通知栏图标即被移除。
但是安卓7之就失效了。

方案三:进程相互换性

不同进程,不同app之间相互唤起

方案四: JobSheduler

JobSheduler是作为进程死后复活的一种手段,native进程方式最大缺点是费电, Native 进程费电的原因是感知主进程是否存活有两种实现方式,在 Native 进程中通过死循环或定时器,轮训判断主进程是否存活,当主进程不存活时进行拉活。其次5.0以上系统不支持。 但是JobSheduler可以替代在Android5.0以上native进程方式,这种方式即使用户强制关闭,也能被拉起来。这种方案虽然可以,但是在某些情况or某些定制ROM上可能失效,认为可以多做一种保保守方案。

总结

使用多进程可以使用更多的系统内存空间,减少内存不足导致的OOM,提升应用性能。但是使用多进程也会有很多问题,所以在使用多进程的时候要好好衡量。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值