android 线程进程机制

来源:互联网 发布:手机上防蓝光软件 编辑:程序博客网 时间:2024/06/06 16:58

1.Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上,service和调用者之间的通讯都是同步的(不论是远程service还是本地service),它跟线程一点关系都没有!

2.Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用,也就是你下次启动的时候,无法控制之前创建的线程,而service则可以。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。

3.你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,这些是 Thread 做不到的。


之前转载了上面这样一篇路边社的解析片段,感觉不是很全面,翻译一下官网。


源地址: http://developer.android.com/guide/components/processes-and-threads.html

 

本文主要讨论进程和线程在Android中的运行机制。

Processes


默认状态下,一个application,占用一个进程。Android系统允许开发者在manifest.xml里定义多个进程。

<activity><service><receiver>, <provider>里面利用android:process属性设置组件所属的进程。 <application>也支持android:process用来定义默认的组件进程。

 

下面详细讨论Android系统对进程的管理:

进程“重要”等级


1.Foreground process  

A process that is required for what the user is currentlydoing. A process is considered to be in the foreground if any of the followingconditions are true:

·        It hosts an Activity that the user is interacting with (the Activity's onResume() method has been called).

·        It hosts a Service that's bound to the activity that theuser is interacting with.

·        It hosts a Service that's running "in theforeground"—the service has called startForeground().

·        It hosts a Service that's executing one of its lifecyclecallbacks (onCreate()onStart(),or onDestroy()).

·        It hosts a BroadcastReceiver that's executing its onReceive() method.

Generally, only a few foreground processes exist at anygiven time. They are killed only as a last resort—if memory is so low that theycannot all continue to run. Generally, at that point, the device has reached amemory paging state, so killing some foreground processes is required to keepthe 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 tobe visible if either of the following conditions are true:

·        It hosts an Activity that is not in the foreground, but isstill visible to the user (its onPause() method has been called). This mightoccur, for example, if the foreground activity started a dialog, which allowsthe previous activity to be seen behind it.

·        It hosts a Service that's bound to a visible (orforeground) activity.

A visible process is considered extremely important andwill not be killed unless doing so is required to keep all foreground processesrunning.

3 Service process

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

4 Background process

A process holding an activity that's not currentlyvisible to the user (the activity's onStop() method has been called). Theseprocesses have no direct impact on the user experience, and the system can killthem at any time to reclaim memory for a foreground, visible, or serviceprocess. Usually there are many background processes running, so they are keptin an LRU (least recently used) list to ensure that the process with theactivity that was most recently seen by the user is the last to be killed. Ifan activity implements its lifecycle methods correctly, and saves its currentstate, killing its process will not have a visible effect on the userexperience, because when the user navigates back to the activity, the activityrestores all of its visible state. See the Activities documentfor information about saving and restoring state.

5 Empty process

A process that doesn't hold any active applicationcomponents. The only reason to keep this kind of process alive is for cachingpurposes, 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 systemresources between process caches and the underlying kernel caches.

 

PS:若一个进程服务于另一个进程,则它的重要等级不低于另一个进程。比如A进程有一个服务作用于B进程,则A进程的等级大于等于B。

Threads


the main thread is also sometimes called the UI thread.  it is in charge of dispatching eventsto the appropriate user interface widgets, including drawing events. It is alsothe thread in which your application interacts with components from the AndroidUI toolkit (components from the android.widget and android.view packages). Main线程(UI线程)分发事件和处理交互。

 

AndroidUI处理两条规则:

1.   Do not block the UI thread

2.   Do not access the Android UI toolkit from outside the UIthread

原因:UI Thread 不是线程安全的

 

基于以上第二点原因:To fix this problem, Android offers several ways to accessthe UI thread from other threads. Here is a list of methods that can help:

·        Activity.runOnUiThread(Runnable)

·        View.post(Runnable)

·        View.postDelayed(Runnable,long)

 

通过以上三个方法把UI操作放在UI线程来处理。比如:

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

Now this implementation is thread-safe: the networkoperation is done from a separate thread while theImageView is manipulated from the UI thread.

 

However, as the complexity of the operation grows, thiskind of code can get complicated and difficult to maintain. To handle morecomplex interactions with a worker thread, you might consider using a Handler in your worker thread, to process messages delivered fromthe UI thread. Perhaps the best solution, though, is to extend the AsyncTask class, which simplifies the execution of worker threadtasks that need to interact with the UI.

但是若是需要对UI和处理线程进行复杂的消息传递,则要用到handler或者AsyncTaskAsyctask比较简单。

 

关于Asynctask;

To use it, you must subclass AsyncTask and implement the doInBackground() callbackmethod, which runs in a pool of background threads. To update your UI, youshould implementonPostExecute(), which delivers the result fromdoInBackground()and runs in the UI thread, so you can safely update your UI. You can then runthe task by callingexecute() from the UI thread.

 

For example, you can implement the previous example using AsyncTask this way:

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 referencefor a full understanding on how to use this class, but here is a quick overviewof how it works:

·        You can specify the type of theparameters, the progress values, and the final value of the task, usinggenerics

·        The method doInBackground() executes automatically on a worker thread

·        onPreExecute()onPostExecute(), and onProgressUpdate() are all invoked on the UI thread

·        The value returned by doInBackground() is sent to onPostExecute()

·        You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the UI thread

·        You can cancel the task at anytime, from any thread

 

PS:其中

onPreExecute()Runs on the UI thread before doInBackground(Params...).

 onPostExecute()Runson the UI thread after doInBackground(Params...).The specified result is the value returned by doInBackground(Params...).

Thismethod won't be invoked if the task was cancelled.

 

 

关于线程安全问题

 

This is primarily truefor methods that can be called remotely—such as methods in a boundservice. When a call on a method implemented in an IBinder originatesin the same process in which the IBinder isrunning, the method is executed in the caller's thread. However, when the calloriginates in another process, the method is executed in a thread chosen from apool of threads that the system maintains in the same process as theIBinder (it'snot executed in the UI thread of the process). For example, whereas a service's onBind() methodwould be called from the UI thread of the service's process, methodsimplemented in the object that onBind()returns(for example, a subclass that implements RPC methods) would be called fromthreads in the pool. Because a service can have more than one client, more thanone pool thread can engage the same IBindermethodat the same time. IBinder methodsmust, therefore, be implemented to be thread-safe.

Similarly, a contentprovider can receive data requests that originate in other processes. AlthoughtheContentResolver and ContentProvider classeshide the details of how the interprocess communication is managed, ContentProvider methodsthat respond to those requests—the methods query()insert()delete(),update(),and getType()—arecalled from a pool of threads in the content provider's process, not the UIthread for the process. Because these methods might be called from any numberof threads at the same time, they too must be implemented to be thread-safe.

关于RPC的问题,When a call on a method implemented in an IBinder originates in the same process in which the IBinder is running如果调用IBinder方法的源和Ibinder在同一个进程里面,则Ibinder的回调方法在源的线程里面运行(可能是main线程) However,when the call originates in another process, the method is executed in a threadchosen from a pool of threads that the system maintains in the same process astheIBinder (it's not executed in the UI thread of the process).否则在系统维护进程(与ibinder同一进程)的线程池里面选择一个线程运行。



0 0
原创粉丝点击