详解Android 进程
作者:Deman的博客家园 发布时间:2023-04-26 07:37:55
多进程
如果需要的时候,app可以创建多进程。
在进程里面
各类组件元素的清单文件条目 、 、 和
— 均支持 android:process 属性,此属性可以指定该组件应在哪个进程运行。
默认进程就是主进程。其他进程一般来说都是子进程。
2个activity在不同的进程里面,可以刷新UI吗?
<activity android:name=".androidsample.ActivityProgressB"
android:process=":progressb"/>
测试结果:ActivityProgressB可以正常显示。这个其实很好理解,如果你打开系统相机页面,那个activity肯定与你的app不再一个进程,但是他可以很顺利的打开,所以可以支持。
保活
OOM_ADJ
这个就是oom 回kill进程的优先级。
进程kill的方式
场景 | 接口 | 范围 |
---|---|---|
LowMemoryKiller | LowMemoryKiller | 从进程的优先级依次kill,释放内存 |
三方kill(无root) | killbackgroundprogersss | kill oom_adj>4 |
三方kill(有root) | forcestop or kill | 理论上所有,一般是非系统和可见进程 |
厂商kill功能 | force stop or kill | 理论上所有,包括native |
进程保活的目的,就是提供进程的优先级,降低进程被kill的概率。
保活的套路
开启1个像素的activity
2020-08-14 14:29:48.630 1164-8504/system_process W/ActivityTaskManager: Background activity start [callingPackage: com.demanmath.androidms; callingUid: 10398; isCallingUidForeground: false; isCallingUidPersistentSystemProcess: false; realCallingUid: 10398; isRealCallingUidForeground: false; isRealCallingUidPersistentSystemProcess: false; originatingPendingIntent: null; isBgStartWhitelisted: false; intent: Intent { flg=0x10000000 cmp=com.demanmath.androidms/.androidsample.LiveActivity }; callerApp: ProcessRecord{a168b71 2429:com.demanmath.androidms/u0a398}]
在android Q以后,不允许后台进程启动后台页面了。也就是想启动一个前台页面
使用前台服务
package com.demanmath.androidms.androidsample
import android.annotation.TargetApi
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Handler
import android.os.IBinder
import androidx.core.app.NotificationCompat
import com.demanmath.androidms.AppLog
import com.demanmath.androidms.R
/**
* @author DemanMath
* @date 2020/8/14
*
*/
class KeepLiveService:Service() {
val NOTIFICATION_ID = 0x11
val NOTIFICATION_CHANNEL_ID = "demanmathId"
val channelName = "My Background Service"
companion object {
const val NOTIFICATION_ID = 0x11
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
startForeground(NOTIFICATION_ID, Notification())
} else {
startMyOwnForeground()
startService(Intent(this, InnerService::class.java))
}
}
@TargetApi(value = Build.VERSION_CODES.O)
private fun startMyOwnForeground() {
AppLog.d()
val chan = NotificationChannel(
NOTIFICATION_CHANNEL_ID,
channelName,
NotificationManager.IMPORTANCE_NONE
)
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val manager =
(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
manager.createNotificationChannel(chan)
val notificationBuilder =
NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build()
startForeground(NOTIFICATION_ID, notification)
}
class InnerService : Service() {
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
//使用channeId & channelName
//发送与KeepLiveService中ID相同的Notification,然后将其取消并取消自己的前台显示
// val builder: Notification.Builder = Notification.Builder(this)
// builder.setSmallIcon(R.mipmap.ic_launcher)
// startForeground(NOTIFICATION_ID, builder.build())
Handler().postDelayed(Runnable {
stopForeground(true)
val manager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.cancel(NOTIFICATION_ID)
stopSelf()
}, 100)
}
}
}
但是androidQ开始以后,禁止后台进程开启前台进程,这个也是android为了省电考虑的。
多进程相互唤醒
这个就是每个app,其多个进程,如果比kill掉了,可以通过另一个唤起。从上面的前台service的功效有些类似。
同样的问题,android Q以后无效。
JobSchedule
package com.demanmath.androidms.jobservice
import android.app.job.JobParameters
import android.app.job.JobService
import android.content.Intent
import android.os.Handler
import android.os.Message
import android.widget.Toast
import com.demanmath.androidms.AppLog
/**
* @author DemanMath
* @date 2020/8/20
*
*/
class JobDemoService:JobService() {
override fun onCreate() {
super.onCreate()
AppLog.i()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
AppLog.i()
return super.onStartCommand(intent, flags, startId)
}
private var mHandler = object:Handler(){
override fun handleMessage(msg: Message) {
AppLog.i()
Toast.makeText(
applicationContext,
"JobService task running", Toast.LENGTH_SHORT
).show()
//请注意,我们手动调用了jobFinished方法。
//当onStartJob返回true的时候,我们必须手动调用jobFinished方法
//否则该应用中的其他job将不会被执行
jobFinished(msg.obj as JobParameters, false)
}
}
override fun onStartJob(params: JobParameters?): Boolean {
AppLog.i()
mHandler.sendMessage(Message.obtain(mHandler,1,params))
return true
}
override fun onStopJob(params: JobParameters?): Boolean {
AppLog.i()
mHandler.removeMessages(1)
return false
}
}
package com.demanmath.androidms.jobservice
import android.app.job.JobInfo
import android.app.job.JobScheduler
import android.content.ComponentName
import android.content.Context
import com.demanmath.androidms.AppLog
/**
* @author DemanMath
* @date 2020/8/20
*
*/
class JobHelper(var context: Context) {
lateinit var jobScheduler:JobScheduler
fun startJob(){
AppLog.i()
jobScheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
var builder = JobInfo.Builder(1, ComponentName(context.packageName,JobDemoService::class.java.name))
// builder.setBackoffCriteria(1000L,JobInfo.BACKOFF_POLICY_LINEAR)
var boolean = jobScheduler.schedule(builder.build())
AppLog.i(boolean.toString())
}
}
来源:https://www.tuicool.com/articles/qEnQfi2


猜你喜欢
- 本文实例为大家分享了C#支付宝新版支付请求接口调用的具体代码,供大家参考,具体内容如下因为支付宝已经集成了完整的SDK,所以可以使用SDK直
- 前言在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,
- Result 类型是许多编程语言中处理错误的常用方式,包括 C# 的 dotNext 库。在本文中,我们将通过例子回顾 C# 中 using
- 本文实例为大家分享了Android实现布局全屏的具体代码,供大家参考,具体内容如下前言类似Launcher,希望占用的布局铺满全屏,以调整状
- 我的电脑环境win10vscode 1.36.1vscode安装插件安装完这个插件后会提示你安装 platformIOCore,按照提示安装
- Android 调用系统应用的方法总结1、调用系统拍照Intent intent = new Intent("andr
- 本文实例为大家分享了java实现画图板功能的具体代码,供大家参考,具体内容如下一、介绍这个画图板主要实现的功能是画矩形(矩形使用的是一个函数
- 最近工作遇到一个需求,需要下载excel模板,编辑后上传解析存储到数据库。因此为了更好的理解公司框架,我就自己先用spring mvc实现了
- Java中Static关键字的一些用法详解1. Static 修饰类属性,因为静态成员变量可以通过类名+属性名调用,非静态成员变量不能通过类
- public interface ICacheStrategy { &
- 1.首先是编辑器的乱码,这个很好解决,file->settings->appearence里面有个Name设置成支持中文的字 体
- 概述RocketMQ 支持发送延迟消息,但不支持任意时间的延迟消息的设置,仅支持内置预设值的延迟时间间隔的延迟消息;预设值的延迟时间间隔为:
- 1. Action/Service/DAO简介:Action是管理业务(Service)调度和管理跳转的。Service是管理具体的功能的。
- 添加jar包这里的Scala不是maven工程所以要找到项目结构(快捷键:同时按住Ctrl+shift+Alt+s)在模块里面添加添加MyS
- 一、JDK * Java 在 java.lang.reflect 包中有自己的代理支持,该类(Proxy.java)用于动态生成代理类,只
- 克隆,想必大家都有耳闻,世界上第一只克隆羊多莉就是利用细胞核移植技术将哺乳动物的成年体细胞培育出新个体,甚为神奇。其实在Java中也存在克隆
- createcriteria和or的区别mybatis generator插件生成的example中,有createcriteria和or方
- 本文实例讲述了Android编程开发之TextView单击链接弹出Activity的方法。分享给大家供大家参考,具体如下:话不多说直接上码:
- 在 Java 语言中的类初始化块 文章中我们简单的介绍了下 Java 中的实例初始化块 ( IIB )。不过我觉得介绍的有点简单了,于是,再
- 本文实例实现C#以一个收银付费的小程序演示switch case语法如何使用,读入用户选择,把用户的选择赋值给变量n,再根据用户的输入提示付