Processes and Threads

阅读:http://developer.android.com/guide/components/processes-and-threads.html

When an application component starts and the application does not have any other components running, the Android system starts a new Linux process for the application with a single thread of execution. By default, all components of the same application run in the same process and thread (called the "main" thread). If an application component starts and there already exists a process for that application (because another component from the application exists), then the component is started within that process and uses the same thread of execution. However, you can arrange for different components in your application to run in separate processes, and you can create additional threads for any process.

  程序启动(没有其他组件启动)的时候,系统会自动启动一个包含有一个进程的linux进程,默认情况下所有的操作都在一个线程里。

  而如果程序启动并且程序某组件已经启动,那么就会在原有的线程里进行操作。

 


 

 

The manifest entry for each type of component element—<activity>, <service>, <receiver>, and <provider>—supports an android:process attribute that can specify a process in which that component should run. You can set this attribute so that each component runs in its own process or so that some components share a process while others do not. You can also set android:process so that components of different applications run in the same process—provided that the applications share the same Linux user ID and are signed with the same certificates.

  在manifest里,也可以选择增加属性使得不同的组件在或者不在同一个进程。


  系统会给每个进程标识一个重要性,如果有必要,系统会自动完全结束掉那些重要性较低的进程。

  重要性分为以下几个层次:

  

  1. Foreground process

    A process that is required for what the user is currently doing. A process is considered to be in the foreground if any of the following conditions are true:

    Generally, only a few foreground processes exist at any given time. They are killed only as a last resort—if memory is so low that they cannot all continue to run. Generally, at that point, the device has reached a memory paging state, so killing some foreground processes is required to keep the user interface responsive.

  2. Visible process

    A process that doesn't have any foreground components, but still can affect what the user sees on screen. A process is considered to be visible if either of the following conditions are true:

    • It hosts an Activity that is not in the foreground, but is still visible to the user (its onPause() method has been called). This might occur, for example, if the foreground activity started a dialog, which allows the previous activity to be seen behind it.
    • It hosts a Service that's bound to a visible (or foreground) activity.

    A visible process is considered extremely important and will not be killed unless doing so is required to keep all foreground processes running.

  3. Service process

    A process that is running a service that has been started with the startService() method and does not fall into either of the two higher categories. Although service processes are not directly tied to anything the user sees, they are generally doing things that the user cares about (such as playing music in the background or downloading data on the network), so the system keeps them running unless there's not enough memory to retain them along with all foreground and visible processes.

  4. Background process

    A process holding an activity that's not currently visible to the user (the activity's onStop() method has been called). These processes have no direct impact on the user experience, and the system can kill them at any time to reclaim memory for a foreground, visible, or service process. Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state. See the Activities document for information about saving and restoring state.

  5. Empty process

    A process that doesn't hold any active application components. The only reason to keep this kind of process alive is for caching purposes, to improve startup time the next time a component needs to run in it. The system often kills these processes in order to balance overall system resources between process caches and the underlying kernel caches.

  系统会自动对这些进程进行安排分级。


 

 

The system does not create a separate thread for each instance of a component. All components that run in the same process are instantiated in the UI thread, and system calls to each component are dispatched from that thread. Consequently, methods that respond to system callbacks (such as onKeyDown() to report user actions or a lifecycle callback method) always run in the UI thread of the process.

For instance, when the user touches a button on the screen, your app's UI thread dispatches the touch event to the widget, which in turn sets its pressed state and posts an invalidate request to the event queue. The UI thread dequeues the request and notifies the widget that it should redraw itself.

When your app performs intensive work in response to user interaction, this single thread model can yield poor performance unless you implement your application properly. Specifically, if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI. When the thread is blocked, no events can be dispatched, including drawing events. From the user's perspective, the application appears to hang. Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog. The user might then decide to quit your application and uninstall it if they are unhappy.

  系统总是把任务安排在同一个线程里,就算是不同的组件;但是如果你要执行大量的任务,例如网络下载等,可能会导致UI线程被锁而失去响应,事件以及绘图都会停止,超过5秒就会出现ANR。

  因此你最好新建一些工作线程。


 

 

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            Bitmap b = loadImageFromNetwork("http://example.com/image.png");
            mImageView.setImageBitmap(b);
        }
    }).start();
}

改代码看似正确:它启动了一个线程去下载东西。但是它出了一个错误:从UI线程以外的线程操作控件,这是不允许的。

为了解决这个问题,可以使用下面的方法:

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

这样就能保证用新线程下载,用UI线程控制控件了。


  可利用AsyncTask解决异步操作的问题。

To use it, you must subclass AsyncTask and implement the doInBackground() callback method, which runs in a pool of background threads. To update your UI, you should implement onPostExecute(), which delivers the result from doInBackground() and runs in the UI thread, so you can safely update your UI. You can then run the task by calling execute() from the UI thread.

  doInBackground()的代码将在后台的线程池执行,onPostExecute()获得结果并对控件进行控制。

  

public void onClick(View v) {
    new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    /** The system calls this to perform work in a worker thread and
      * delivers it the parameters given to AsyncTask.execute() */
    protected Bitmap doInBackground(String... urls) {
        return loadImageFromNetwork(urls[0]);
    }
    
    /** The system calls this to perform work in the UI thread and delivers
      * the result from doInBackground() */
    protected void onPostExecute(Bitmap result) {
        mImageView.setImageBitmap(result);
    }
}

You should read the AsyncTask reference for a full understanding on how to use this class, but here is a quick overview of how it works:

  1、可以修改第一,三参数,分别是线程的参数以及结果的类型;

  2、doInBackground()在工作线程里工作,onPreExecute(), onPostExecute(), and onProgressUpdate()在UI线程里。

  3、doInBackground()的结果将作为onPostExecute的参数。

  4、可从任何 一个线程、任何时候取消该异步工作。

 

 

 

 

 

 

 

posted @ 2013-10-24 21:30  yutoulck  阅读(171)  评论(0编辑  收藏  举报