【Android学习笔记】Android中的进程和线程

一、进程和线程概述

如果某个应用程序组件是第一次被启动,且这时应用程序也没有其他组件在运行,则Android系统会为应用程序创建一个包含单个线程的linux进程。默认情况下,同一个应用程序的所有组件都运行在同一个进程和线程里(叫做“main”主线程)。如果组件启动时,已经存在应用程序的进程了(因为应用程序的其它组件已经在运行了),则此组件会在已有的进程和线程中启动运行。不过,可以指定组件运行在其他进程里,也可以为任何进程创建额外的线程。
二、进程

默认情况下,同一个应用程序内的所有组件都是运行在同一个进程中的,大部分应用程序也不会去改变它。不过,如果需要指定某个特定组件所属的进程,则可以利用manifest 文件来达到目的。

manifest文件中的每种组件元素——<activity>、 <service>、 <receiver>和<provider>——都支持定义android:process属性,用于指定组件运行的进程。设置此属性即可实现每个组件在各自的进程中运行,或者某几个组件共享一个进程而其它组件运行于独立的进程。设置此属性也可以让不同应用程序的组件运行在同一个进程中——实现多个应用程序共享同一个Linux用户ID、赋予同样的权限。

<application>元素也支持android:process属性,用于指定所有组件的默认进程。


如果内存不足,可又有其它为用户提供更紧急服务的进程需要更多内存,Android可能会决定关闭一个进程。在此进程中运行着的应用程序组件也会因此被销毁。当需要再次工作时,会为这些组件重新创建一个进程。

系统在回收进程的时候会考虑进程的生命周期,按照他们的迫切性来进行回收处理,进程的优先级如下依次递减

1. 前台进程
用户当前操作所必须的进程。满足以下任一条件时,进程被视作处于前台:
其中运行着正与用户交互的Activity(Activity对象的onResume()]方法已被调用)。
其中运行着被正与用户交互的activity绑定的服务。
其中运行着“前台”服务——服务以[startForeground()方式被调用。
其中运行着正在执行生命周期回调方法(onCreate()、onStart()或onDestroy())的服务。

其中运行着正在执行onReceive()方法的BroadcastReceiver。
一般而言,任何时刻前台进程都是为数不多的,只有迫不得已——当内存不足以维持它们同时运行时——才会被终止。通常,设备这时候已经到了使用虚拟内存的地步,终止一些前台进程是为了保证用户界面的及时响应。
2. 可见进程
没有前台组件、但仍会影响用户在屏幕上所见内容的进程。满足以下任一条件时,进程被认为是可见的:
其中运行着不在前台的Activity,但用户仍然可见到此activity(onPause()方法被调用了)。比如以下场合就可能发生这种情况:前台activity打开了一个对话框,而之前的activity还允许显示在后面。
其中运行着被可见(或前台)activity绑定的服务。
可见进程被认为是非常重要的进程,除非无法维持所有前台进程同时运行了,它们是不会被终止的。
3. 服务进程
此进程运行着由startService()方法启动的服务,它不会升级为上述两级别。尽管服务进程不直接和用户所见内容关联,但他们通常在执行一些用户关心的操作(比如在后台播放音乐或从网络下载数据)。因此,除非内存不足以维持所有前台、可见进程同时运行,系统会保持服务进程的运行。
4. 后台进程

包含目前用户不可见activity(Activity对象的onStop()方法已被调用)的进程。这些进程对用户体验没有直接的影响,系统可能在任意时间终止它们,以回收内存供前台进程、可见进程及服务进程使用。通常会有很多后台进程在运行,所以它们被保存在一个LRU(最近最少使用)列表中,以确保最近被用户使用的activity最后一个被终止。如果一个activity正确实现了生命周期方法,并保存了当前的状态,则终止此类进程不会对用户体验产生可见的影响。因为在用户返回时,activity会恢复所有可见的状态。关于保存和恢复状态的详细信息,请参阅Activity文档。
5. 空进程
不含任何活动应用程序组件的进程。保留这种进程的唯一目的就是用作缓存,以改善下次在此进程中运行组件的启动时间。为了在进程缓存和内核缓存间平衡系统整体资源,系统经常会终止这种进程。

三、线程

应用程序启动时,系统会为它创建一个名为“main”的主线程。主线程非常重要,因为它负责把事件分发给相应的用户界面widget——包括屏幕绘图事件。它也是应用程序与Android UI组件包(来自android.widget和android.view包)进行交互的线程。因此,主线程有时也被叫做UI线程。

这里有两个原则必须遵守

1.不能阻塞UI线程

2.不能在UI线程之外访问Android的UI组件

Android提供了几种途径来从其它线程中访问UI线程。下面列出了有助于解决问题的几种方法:

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

这里有两种常用的解决方案:handler和asyncTask


四、其他

参考文献:官方文档

你可能感兴趣的:(android,线程)