Android Process and Thread 进程和线程

来源:互联网 发布:php简单计算器 编辑:程序博客网 时间:2024/05/17 06:42

http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html

当一个应用程序组件开启,而该应用程序没有其他组件在运行,那么Android系统会为这个应用程序启动一个新的Linux进程,一个单独线程来执行这些操作。一般来说,一个应用程序中的所有组件应该是跑在同一个进程和线程(主线程,called the "main" thread)。如果一个应用组件启动并且已经有相应的进程存在,那么这个组件就被在该组件中启动,并且用相同的那个主线程。但是,如果你安排不同的组件跑在不同的进程,也可以在进程中创建更多的线程。


Processes

一般来说,一个应用中的所有的组件都在同一个进程中允许,大多数应用不会去修改这个。但是,可以通过设置Manifest文件。组件运行的进程由manifest file控制。组件的节点 — <activity>, <service>, <receiver>, 和 <provider> — 都包含一个 process 属性。这个属性可以设置组件运行的进程:可以配置组件在一个独立进程运行,或者多个组件在同一个进程运行。甚至可以多个程序在一个进程中运行——如果这些程序共享一个User ID并给定同样的权限。<application> 节点也包含 process 属性,用来设置程序中所有组件的默认进程。

当系统的内存低,有时候会关闭一些进程,并且会保持一些相应的信息,应用程序的组件在同一进程的都会被销毁destroyed。觉得那个进程被kill的优先级描述如下:

可以通过adb shell dumpsys来查看一些进程的状态信息。

     1. foreground process
这类进程包括:

1,包含一个正在和用户交互的activity(onResume()方法被调用)

2,一个和前台的交互的activity绑定的Service

3,一个跑在“forground”状态的service,调用过startForeground()方法。1.6时为setForeground(true)。

4,一个Service正在执行一些回调方法(onCreate(), onStart(),onDestroy())

5,一个正在执行onReceive()方法的BroadcastReceiver。


     2. visible process

1,一个可见的但是不能和用户交互的activity。比如说被called了onPause()。

2,一个和上述activity绑定的service


     3. service process
一个通过startService()方法启动的service。并且不是上述的两类。他们一般做的工作不是用户直接能看到的,比如说播放音乐,后台下载一些数据等。


     4.  background process
一堆不可可见的activity,通常是调用过onStop()方法了。这些进程不直接影响到用户的感受。

     5. empty process

其中empty process是为了下次在启动该程序而缓存一些数据而保留的进程,这就是为什么当我们退出程序后,长按Home键还能看到该程序进程图标的原因。

Android在评定一个进程的优先级的时候是参考进程中所有组件中优先最高的一个。另外,因为service process比background process优先级高,所以一般来说用service来处理一些耗时操作更安全一些。


Threads


1,组件都在主线程

2,多线程thread或者handlerThread

3,ui只能在主线程内进程,刷新ui的几种方式。

4,AsyncTask,注意activity在onConfiguartion重置的时候的控制

5,ContentProvider目前只提供同步的增删查改,异步的交给AsyncQueryHandler

6,线程安全。


应用程序中每一个组件的构建和处理,都在同一个线程,主线程中进行,包括broadcastreceiver,service,activity都在同一个线程中,所以尽量不要做太多耗时型的操作,防止出现ANR。多线程是需要程序员自己来创建的,可以使用标准的线程类Thread或者Android的HandlerThread便捷类去对其它线程执行远程操作。UI事件是只能在主线程中处理的,通过其他线程来获取数据,然后需要调用主线程来进行刷新操作,方法有:

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

更复杂的可以用handler来配合。

另外还有android中异步工作的接口,AsyncTask,下面有个demo

[java] view plaincopy
  1. public void onClick(View v) {  
  2.     new DownloadImageTask().execute("http://example.com/image.png");  
  3. }  
  4.   
  5. private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {  
  6.     /** The system calls this to perform work in a worker thread and 
  7.       * delivers it the parameters given to AsyncTask.execute() */  
  8.     protected Bitmap doInBackground(String... urls) {  
  9.         return loadImageFromNetwork(urls[0]);  
  10.     }  
  11.       
  12.     /** The system calls this to perform work in the UI thread and delivers 
  13.       * the result from doInBackground() */  
  14.     protected void onPostExecute(Bitmap result) {  
  15.         mImageView.setImageBitmap(result);  
  16.     }  
  17. }  

这个task就可以被取消的,有个问题就是在activity等遇到configuration change的时候,如果不进行设置,就进行activity的restart,也会导致worker thread被销毁,destroyed。


Content Provider为了保持更多的灵活性,本身只提供了同步调用的接口,而由于异步对Content Provider进行增删改查是一个常做操作,Android通过AsyncQueryHandler对象,提供了异步接口。这是一个Handler的子类,开发人员可以调用startXXX方法发起操作,通过派生onXXXComplete方法,等待执行完毕后的回调,从而完成整个异步调用的流程,十分的简约明了。


Thread-safe methods

在某些情况下,方法可能调用不止一个的线程,因此需要注意方法的线程安全。

对于可以远程调用的方法,也要注意这点。当一个调用在Ibinder对象中的方法的程序启动了和Ibinder对象相同的进程,方法就在Ibinder的进程中执行。但是,如果调用者发起另外一个进程,方法在另外一个线程中运行,这个线程在和IBinder对象在一个线程池中;它不会在进程的主线程中运行。例如,一个service从主线程被调用onBind() 方法,onBind() 返回的对象(如实现了RPC的Stub子类)中的方法会被从线程池中调用。因为一个服务可能有多个客户端请求,不止一个线程池会在同一时间调用IBinder的方法。因此IBinder必须线程安全。

简单来说,一个content provider 可以接收其他进程的数据请求。即使ContentResolver和ContentProvider类没有隐藏了管理交互的细节,ContentProvider中响应这些请求的方法(query(), insert(), delete(), update(), and getType() )— 是在content provider的线程池中被调用的,而不是ContentProvider的本身进程。因为这些方法可能是同时从很多线程池运行的,所以这些方法必须要线程安全。

参考http://www.cnblogs.com/feisky/archive/2010/01/01/1637409.html

0 0
原创粉丝点击