首页 > 编程语言 > 详解Android 进程
2020
10-09

详解Android 进程

多进程

如果需要的时候,app可以创建多进程。

在进程里面

各类组件元素的清单文件条目 、 、 和
— 均支持 android:process 属性,此属性可以指定该组件应在哪个进程运行。

默认进程就是主进程。其他进程一般来说都是子进程。

2个activity在不同的进程里面,可以刷新UI吗?

1
2
<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以后,不允许后台进程启动后台页面了。也就是想启动一个前台页面

使用前台服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
  }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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())
  }
}

以上就是详解Android 进程的详细内容,更多关于Android 进程的资料请关注自学编程网其它相关文章!

编程技巧