Android基础知识整理(三) 线程与进程

三、线程/进程

进程
进程优先级

前台进程(Foreground process)。它表明用户正在与该进程进行交互操作,android系统依据下面的条件来将一个进程标记为前台进程:

  • 该进程持有一个用户正在与其交互的Activity(也就是这个activity的生命周期方法走到了onResume()方法)。

  • 该进程持有一个Service,并且这个Service与一个用户正在交互中的Activity进行绑定。

  • 该进程持有一个前台运行模式的Service(也就是这个Service调用了startForegroud()方法)。

  • 该进程持有一个正在执行生命周期方法(onCreate()、onStart()、onDestroy()等)的Service。

  • 该进程持有一个正在执行onReceive()方法的BroadcastReceiver。

    一般情况下,不会有太多的前台进程。杀死前台进程是操作系统最后无可奈何的做法。当内存严重不足的时候,前台进程一样会被杀死。

可见进程(Visible process)。它表明虽然该进程没有持有任何前台组件,但是它还是能够影响到用户看得到的界面。android系统依据下面的条件将一个进程标记为可见进程:

  • 该进程持有一个非前台Activity,但这个Activity依然能被用户看到(也就是这个Activity调用了onPause()方法)。例如,当一个activity启动了一个对话框,这个activity就被对话框挡在后面。
  • 该进程持有一个与可见(或者前台)Activity绑定的Service。

服务进程(Service process)。除了符合前台进程和可见进程条件的Service,其它的Service都会被归类为服务进程。

后台进程(Background process)。持有不可见Activity(调用了onStop()方法)的进程即为后台进程。通常情况下都会有很多后台进程,当内存不足的时候,在所有的后台进程里面,会按照LRU(最近使用)规则,优先回收最长时间没有使用过的进程。

空进程(Empty process)。不持有任何活动组件的进程。保持这种进程只有一个目的,就是为了缓存,以便下一次启动该进程中的组件时能够更快响应。当资源紧张的时候,系统会平衡进程缓存和底层的内核缓存情况进行回收。

LowMemoryKiller

OOM全称Out Of Memory,是Linux当中,内存保护机制的一种。该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核将该进程杀掉。

当Kernel遇到OOM的时候,可以有2种选择:

1) 产生kernelpanic(死机)

2) 启动OOM killer,选择一个或多个“合适”的进程,干掉那些选择中的进程,从而释放内存。

在Android中,及时用户退出当前应用程序后,应用程序还是会存在于系统当中,这是为了方便程序的再次启动。但是这样的话,随着打开的程序的数量的增加,系统的内存就会不足,从而需要杀掉一些进程来释放内存空间。至于是否需要杀进程以及杀什么进程,这个就是由Android的内部机制LowMemoryKiller机制来进行的。Andorid的Low Memory Killer是在标准的linux lernel的OOM基础上修改而来的一种内存管理机制。当系统内存不足时,杀死不必要的进程释放其内存。

img

线程
线程和线程池使用

在Java中,已经提供了2种实现线程的方式。

继承Thread类

class MyThread extends Thread{
    @Override
    public void run() {
        //耗时操作
    }
}
new MyThread().start();

实现Runnable接口

new Thread(new Runnable() {
    @Override
    public void run() {
        //耗时操作
    }
}).start();

两种方式虽然都可以实现,但是两者还是有一定的区别,因为Java的单继承性质,继承了Thread类则不能在继承其他的类,而实现Runnable接口则没有这种限制。另外在多线程去操作同一个资源的时候,也应该选择使用实现Runnable接口的方法来实现。

线程池

针对多线程并发的问题,引入线程池的好处就比较明显了:

  • 可以控制同一时间内线程的最大并发数,合理利用系统资源,提高应用性能。
  • 当任务完成后,可以重用已经创建的的线程,避免频繁创建新的线程而导致的GC。
  • 通过Executors工具类,可以更方便的使用线程池,控制线程的最大并发数、线程的定时任务、单线程的顺序执行等。
Handler / Looper /Message

1.MessageQueue

MessageQueue顾名思义,指的就是消息队列,说这个之前我们首先需要知道什么是Message,比如说我们在UI界面时点击一个按钮,或者是接收到了一条广播,其实都算是一条Message,这些事件都被封装成一条Message被添加到了MessageQueue队列当中,因为我们知道一个线程在一段时间只能对一种操作进行相关的处理,因此这些消息的处理就要有先后顺序,因此采用MessageQueue来管理,也就是消息队列。消息队列其实就是一堆需要处理的Message而形成的传送带。一旦有消息发送进来,那么直接执行enqueueMessage()方法。也就是将消息压入到队列当中,一旦线程空闲下来,那么直接从MessageQueue中取出消息,使得消息出队。

2.Looper

Looper的主要作用是与当前线程形成一种绑定的关系,同时创建一个MessageQueue,这样保证一个线程只能持有一个Looper和MessageQueue同时Looper使得MessageQueue循环起来,就好比水车和水一样,MessageQueue好比水车,当他有了Looper的时候,那么水车会随着水去转动也就是说Looper为MessageQueue提供了活力,使其循环起来,循环的动力往往就少不了Thread。一般而言子线程一般是没有MessageQueue,因此为了使线程和消息队列能够关联那么就需要有Looper来完成了,因此我们可以这样去实现

3.Handler

handler起到了处理MQ上的消息的作用(只处理由自己发出的消息),即通知MQ它要执行一个任务(sendMessage),并在loop到自己的时候执行该任务(handleMessage),整个过程是异步的。handler创建时会关联一个looper,默认的构造方法将关联当前线程的looper,不过这也是可以set的。

在这里插入图片描述

Loader

Android 3.0 中引入了 Loader 机制,让开发者能轻松在 Activity 和 Fragment 中异步加载数据,Loader 机制一般用于数据加载,特别是用于加载 ContentProvider 中的内容,比起 Handler + Thread 或者 AsyncTask 的实现方式,Loader 机制能让代码更加的简洁易懂,而且是 Android 3.0 之后最推荐的加载方式。

Loader 机制的 使用场景 有:

  • 展现某个 Android 手机有多少应用程序
  • 加载手机中的图片和视频资源
  • 访问用户联系人
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leisure-ZL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值