Android基础理解线程与进程

Android基础理解:进程与线程

Android中,当一个应用程序启动并且应用程序没有组件在运行时,系统会为应用程序创建一个新额单线程的进程。默认情况下,一个应用程序的所有组件都运行在同一个进程中,以及同一个 main 线程。

在系统中已经有应用程序正在运行时,被启动的组件会在这个应用程序的同一进程中运行。然而,组件的运行也可以被设计安排在一个不同的进程中执行,并且在任一进程中创建不同的线程。

进程

默认的情形下,一个应用程序的所有组件都运行在相同的进程,并且大多数的应用程序不会改变这种情形。但是,可以通过manifest的修改实现将某个组件运行的进程进行修改,使其运行在一个不同的进程中。

manifest文件中为每个组件(<activity><service><receiver><provider>)提供了 android:process 属性,修改这个属性值可以表示对应组件所述的运行进程。

manifest的 application 元素同样有 android:process 属性可以设置应用程序的所有组件运行的进程。

Android会为用户更加频繁交互的应用程序需求资源时,关闭其他进程。在关闭的进程中运行的组件就会被销毁(destroyed)。

要关闭哪个进程取决于Android系统评估的应用程序对于用户的重要性。

  • 相比于正在运行 可见activity 的进程,activity组件不可见进程更轻而易举地被关闭。

是否终止一个进程取决于进程中运行的组件状态。

进程和App生命周期

多数情况下,每个应用程序都运行在自己的Linux进程中。一个进程创建的取决于应用程序需要内存运行,并且保持运行,直到系统要求取回内存给其他应用程序运行,并且被回收内存的进程不再需要。

Android的不同寻常的基本特征,一个应用程序进程额生命周期不直接由进程自身决定。相反,由系统根据

  1. 系统所知的运行中的应用程序,
  2. 这些事务对用户的重要性,
  3. 系统中总体内存的可用性,

来决定进程的生命周期。

应用开发过程中,理解应用程序组件(尤其Activity, Service, BroadcastReceiver)对应用程序进程的影响很重要。无法正确使用这些组件可能导致系统直接查杀应用进程。

进程类别

系统因为内存低要求回收内存时,需要查杀进程。Android中进程都依据进程中组件的运行状态被赋予重要性值。按重要性顺序,进程类型被分为:

  1. 前台进程。 前台进程 是用户当前正在操作所需要的程序。应用进程内的各种组件可以以不同的方式使应用被视为 前台进程。一个进程被视为 前台进程 只要符合以下任一条:

    • 进程有一个可见的且用户正在与之交互的 Activity 正在运行( ActivityonResume()已经被调用)。
    • 进程有一个 BroadcastReceiver 正在运行( BroadcastReceiveronReceive() 方法正在执行)。
    • 进程有一个 Service 正在执行( ServiceonCreate() onStart()onDestroy() 方法被调用)。

    系统中只有少数一些进程是这样的,且只有当系统内存太低,以至于这些进程都无法继续运行时,才会被作为最后的手段被终止。通常,如果发生这种情况,设备已达到内存分页状态,因此需要此操作来保持用户界面的响应。

  2. 可见进程。 可见进程 是用户当前可感知到的进程。杀死 可见进程 对于用户体验只有负面影响。一个进程被视为 可见进程 符合以下任一条件:

    • 进程有一个 Activity 对用户可见,但不是 foreground 状态( ActivityonPause() 方法被调用)。这中场景是可能发生的,当前的 foreground Activity 显示一个dialog,导致前一个 Activity 被遮挡在后面。
    • 进程有一个 Service 通过 Service.startForeground() 调用而运行(通过这种方式启动的 Service 要求系统将其看做是 用户可感知 的或者基本上就好像它是可见的)。
    • 系统使用的,可以可感知的 Service ,例如 输入法服务。

    种类进程在系统中的数量比 前台进程 要少,但仍然相对受控。这些进程被视为非常重要,并且不会被杀掉除非这些进程的运行会保持所有 前台进程 的运行。

  3. 服务进程。 服务进程 是调用 startService() 启动一个 Service 的进程。尽管这类进程对用户不直接可见,但这类进程执行的是用户关注的任务(例如 后台进程的数据上传和下载),因此系统总是会保留这些运行的进程,直到系统声明回收内存给 前台进程可见进程 执行。

    长时间运行(超过30mins)的服务进程在重要性上会被降级,进程会被加入到 缓存进程 列表中。

    需要长时间运行的进程可以通过 setForeground 创建。如果若果是一个严格时间执行的周期性进程,可以通过 AlarmManager 执行。 了解更多耗时工作。 这有利于避免耗时 service 使用过多资源,例如,泄漏内存,有碍于用户体验。

  4. 缓存进程。 缓存进程 是当前不再需要的进程,系统可以根据需要,在其他进程需要更多内存时对 缓存进程 进行查杀。在一个正常运行的系统中,这类进程只在资源管理中存在。

    一个正常运行的系统总是有若干个 缓存进程 ,用以高效地切换应用程序,并且在需要时查杀最老的 缓存进程。只有在紧急的情况下,系统需要查杀所有的 缓存进程 并且开始查杀 服务进程

    缓存进程 通常保持有一个或多个当前对用户不可见的 Activity 实例(他们的 onStop() 方法已经被调用并返回)。假设系统查杀这类进程时, Activity 正确实现了生命周期,在回到应用程序时用户体验不会受到影响。在Activity实例在新进程中重新创建时,之前保存的状态会被恢复。要注意的是 系统查杀一个进程时,onDestroy() 方法不能保证被调用。

    缓存进程 被保存在一个列表内。列表的排队策略依据平台的实现。通常,列表中保留更多有用进程(例如 用户home应用程序,或用户最后看见Activity的进程) 优于其他类型进程。

在对进程进行分类时,系统基于在存活的进程内所有组件中找到做中重要的级别作出决策。一个进程的优先级可以基于其他进程对它的依赖被提升。

耗时工作

WorkerManager 内置了对长期工作任务的支持。在这些情况下,WorkManager 会向系统提供一个信号,表明当前进程在执行时应该尽可能被保活。这些工作任务可以运行超过10mins。

在表面之下,WorkManager 管理并运行一个前台服务(foreground service)代表你执行一个 WorkRequest,同时显示可配置的通知。

代码使用示例

线程

在一个应用程序启动之后,系统会伴随着创建一个 main 线程(也叫 UI线程)。

Main线程非常重要:

  1. 它负责 UI与 用户交互时的事件分发工作,包含 绘制。
  2. 它是Android UI组件包 android.view android.widget 内组件运行所属的线程,也因此叫做 UI线程。

有时,特殊情形下,主线程也可能不是UI线程。

线程标注

线程标注检查一个方法是否在对应类型的线程中被调用。以下是支持的线程标注:

  • @MainThread
  • @UiThread
  • @WorkerThread
  • @BinderThread
  • @AnyThread

编译工具对待 @MainThread@UiThread 标注时,认为两者是可互换的。但在系统app有时在不同线程中有不同的界面,这种情况下 @UiThread 就有别于 @MainThread因此,与app界面结构有关联的方法应该标注 UiThread@MainThread 只被用以标注与app生命周期有关的方法。

假设一个类中所有的方法均要求在同一个线程中执行,那么可以在类声明上标注一个线程类型。

使用 WorkerThread 线程标注注解的方法或类用以检查是否在一个恰当的后台线程中被调用。

单UI线程缺点

应用程序运行过程时,系统不会为运行的组件创建一个单独的线程。应用程序所有组件都在 UI线程 中创建并初始化,系统回调到组件的事件分发也在 UI线程 中完成。

UI线程负责很重要,负责的工作在系统中已经确认好。应用程序负责的工作冗杂,在单线程工作模式下,很容易造成性能缺失。

场景:

  1. 用户交互时主线程处理负责工作。
  2. 在主线程中执行耗时操作,例如:网络访问,查询DB会阻塞UI。

线程阻塞,会阻止所有的事件分发,包含UI绘制事件。在界面上看到的现象是,在没有响应后一会儿,ANR弹窗会显示。

Android组件是非线程安全的。 所有的UI组件只能在UI线程中被更新,被操作。在一个工作线程中直接访问组件是非法操作,会造成应用程序crash。

在单UI线程操作时,谨记:

  1. 不要阻塞UI线程。
  2. 不要再UI线程外访问UI组件。

工作线程

上述说明,单UI线程模式下,应用程序很容易有性能问题,甚至ANR问题。因此应用程序的UI响应能力很重要。若应用程序执行的是非即时工作,确保这些工作在一个单独的后台/工作线程中被执行。

Android提供了在非UI线程中访问UI新程的方式:

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runanble, long)

上述的方式只适用于简单的场景中,随项目越复杂,推荐在工作线程中使用 Handler 处理 UI线程 的消息。Background Work Overview

[1] Processes and threads

[2] Processes and app lifecycle

[3] Support for long-running workers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《深入理解android卷3》是一本关于Android系统探索与应用的书籍,由作者百度出版。本书主要从技术角度对Android系统进行深入分析和解读,帮助读者更好地理解和应用Android。 《深入理解android卷3》的内容主要包括Android系统的架构、内核、驱动程序、系统服务、应用程序等方面。通过对这些内容的详细讲解,读者可以全面了解Android系统的各个部分的工作原理和作用,从而更好地进行Android应用的开发和优化。 本书的特点之一是对Android系统的底层原理进行了透彻的分析,对于有一定基础Android开发者来说,可以帮助他们进一步提升自己的技术水平和解决实际问题。此外,本书还包括了一些实际案例和经验总结,可以帮助读者更好地应对开发中的各种挑战。 总的来说,《深入理解android卷3》是一本适合具备一定Android开发经验的人阅读的书籍,通过对Android系统的深入理解,读者可以更好地应用这些知识,提高自己的开发效率和项目质量。无论是从学习还是实践的角度,这本书对于Android开发者来说都具有很高的参考价值。 ### 回答2: 《深入理解Android卷3》是一本由百度出版的Android开发教程,旨在帮助读者更深入地理解和掌握Android系统的原理和底层技术。 本书主要分为七个部分,包括了Android系统的基础知识、系统架构、进程线程管理、内存管理、输入输出管理、网络和通信以及安全性等方面的内容。通过逐步深入的讲解,读者可以更好地了解Android系统的各个层级和相关技术。 首先,本书从 Android系统架构的角度出发,介绍了Android系统的基本组成部分,包括应用层、应用框架层、系统运行库和内核等。接着,作者详细讲解了Android进程线程管理的原理,包括进程的创建与销毁、线程的创建与管理等。 其次,本书还介绍了Android内存管理的相关知识,包括内存的分配与回收、内存优化策略等。此外,本书还深入探讨了Android的输入输出管理,包括文件读写、数据库操作、多媒体处理等方面的内容。 另外,作者还介绍了Android的网络和通信技术,包括网络连接、数据传输、消息处理等方面的知识。最后,本书还对Android系统的安全性进行了详细解析,包括权限管理、应用签名验证等。 总的来说,《深入理解Android卷3》通过深入剖析Android系统的各个层面,帮助读者全面理解Android系统的原理和机制。无论是对于新手还是有一定经验的开发者,这本书都是一本非常实用的Android开发指南。非常推荐给对Android开发感兴趣的读者阅读。 ### 回答3: 《深入理解Android卷3》是一本由百度出版的技术书籍,主要讲解了Android系统的各个方面以及相关的开发技术。 这本书分为多个章节,首先从Android系统的底层原理开始介绍,包括Linux内核、系统启动、进程管理等内容。然后,逐步深入讲解了Android进程线程、Binder机制、内存管理以及输入输出等相关知识。 此外,书中还详细介绍了Android的系统服务框架,包括应用程序框架、资源管理、窗口管理、多媒体框架等方面。它还探讨了Android的网络通信、安全机制以及权限管理等重要主题。 《深入理解Android卷3》注重理论与实践相结合,书中配有大量的代码示例和实践案例,通过实际操作帮助读者更好地理解和掌握所学知识。此外,书中还提供了大量的开发技巧和调试技巧,帮助读者在Android开发中避免常见的问题和错误。 总的来说,《深入理解Android卷3》通过对Android系统和开发技术的全面解析,为Android开发者提供了一个全面、系统的学习和参考资料。无论是对于初学者还是有一定经验的开发者来说,都能从中获得深入的理解和实用的技巧。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

VoidHope

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

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

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

打赏作者

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

抵扣说明:

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

余额充值