详解Android 进程

所属分类: 软件编程 / Android 阅读数: 102
收藏 0 赞 0 分享

多进程

如果需要的时候,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())
  }
}

以上就是详解Android 进程的详细内容,更多关于Android 进程的资料请关注脚本之家其它相关文章!

更多精彩内容其他人还在看

Android框架学习之Volley和Glide详解

这篇文章主要给大家介绍了关于Android框架学习之Volley和Glide的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Android中Fragment的基本用法示例总结

Fragment是activity的界面中的一部分或一种行为,下面这篇文章主要给大家介绍了关于Android中Fragment的基本用法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
收藏 0 赞 0 分享

Android.mk引入第三方jar包和so库文件的方法

这篇文章主要介绍了Android.mk引入第三方jar包和so库文件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android仿微信录制小视频

这篇文章主要为大家详细介绍了Android仿微信录制小视频,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

android实现一键锁屏和一键卸载的方法实例

这篇文章主要给大家介绍了关于android如何实现一键锁屏和一键卸载的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
收藏 0 赞 0 分享

Android手势密码--设置和校验功能的实现代码

这篇文章主要介绍了Android手势密码--设置和校验功能的实现代码,非常不错,具有一定的参考校验价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Kotlin学习笔记之const val与val

这篇文章主要给大家介绍了关于Kotlin学习笔记之const val与val的相关资料,并给大家介绍了const val和val区别以及Kotlin中var和val的区别,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Android实现调用系统分享功能示例的总结

这篇文章主要介绍了通过Android调用系统分享文本信息、单张图片、多个文件和指定分享到微信、QQ,同时分享图片和文字的功能示例,小编觉得挺不错,一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android自定义view实现输入控件

这篇文章主要为大家详细介绍了Android自定义view实现输入控件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android使用Intent.ACTION_SEND分享图片和文字内容的示例代码

这篇文章主要介绍了Android使用Intent.ACTION_SEND分享图片和文字内容的示例代码的实例代码,具有很好的参考价值,希望对大家有所帮助,一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多