您的位置:首页 > 其它

Processes and Threads 进程与线程

2015-09-21 17:17 543 查看

Processes and Threads 进程与线程

简述

俗话说的好“纸上得来终觉浅 绝知此事要宫刑”,多线程编程可以最大限度地利用多核心和操作系统的系统,是提高程序运行性能常用的方法!

进程(Process)进程(Thread)也是计算机利于最基本的概念,虽然如此,当我们真正的想开发高效率的并发应用,却发现对于他们的理解还是不够深刻!

在Android中,当app启动时,系统会为这个application启动一个新的Linux进程(单线程执行)。默认情况下,一个应用程序的所有组件都运行相同进程和线程中(我们称之为主线程)。当然,你可以分配应用程序不同的组件到不同的进程中,你可以为任何进程创造额外的的线程。

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.

进程-Process

默认情况下,同一个应用程序的所有组件运行在同一个进程下,并且大多数程序不需要改变!

当然你想要控制应用程序组件运行的进程,你可以在清单文件中进行设置。

清单文件不同的组件元素,如activity , service, receiver, and provider 支持
android:process attribute
属性,可以指定组件运行在那个进程中!

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.

进程的生命周期

Andorid系统尽量维持一个应用程序进程,但最后还是需要移除旧进程来回收内存开辟新的进程或者维持重要的进程。为了决定那个进程被保存 那个被移除,Android系统基于进程中运行的组件和组建的状态,为每个进程设置一个重要性层级。重要层级最低的先被移出 回收内存,然后是次重要的,按照重要层级如此往来。

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:

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 the user is interacting with.

It hosts a Service that’s running “in the foreground”—the service has called startForeground().

It hosts a Service that’s executing(实行) one of its lifecycle(生活周期) callbacks(回收) (onCreate(), onStart(), or onDestroy()).

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

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.

Android ranks a process at the highest level it can, based upon the importance of the components currently active in the process. For example, if a process hosts a service and a visible activity, the process is ranked as a visible process, not a service process.

In addition, a process’s ranking might be increased because other processes are dependent(依靠的) on it—a process that is serving another process can never be ranked lower than the process it is serving. For example, if a content provider in process A is serving a client in process B, or if a service in process A is bound to a component(成分) in process B, process A is always considered at least as important as process B.

Because a process running a service is ranked higher than a process with background activities, an activity that initiates(开始) a long-running operation might do well to start a service for that operation, rather than simply create a worker thread—particularly if the operation will likely outlast the activity. For example, an activity that’s uploading a picture to a web site should start a service to perform the upload so that the upload can continue in the background even if the user leaves the activity. Using a service guarantees(保证) that the operation will have at least “service process” priority(优先), regardless(不管) of what happens to the activity. This is the same reason that broadcast receivers should employ services rather than simply put time-consuming(耗时的) operations in a thread.

线程-Thread

当应用程序被启动,Android为这个应用程序创造一个执行线程,我们称之为 主线程。这个线程很重要,因为它负责调度和适当的用户界面view和widgets的事件,包括画图时间。她也是我们应用程序和android UI 包交互的线程。所以主线程也被成为UI线程

必须保证不再主线程进程消耗时间和资源的操作,因为当5s内无响应,Android系统就爆出声名狼藉的ANR(application not responding)错误。

同时Android UI toolkit 不是线程安全的,所以你不能工作线程中进行UI操作,你必须在主线程中进行所有对于UI的操作

Thus, there are simply two rules to Android’s single thread model:



Do not block the UI thread

Do not access the Android UI toolkit(工具包) from outside the UI thread



1.不要阻塞主线程;

2.不要在主线程之外操作UI元素

To fix this problem, Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help:


Activity.runOnUiThread(Runnable) View.post(Runnable)

View.postDelayed(Runnable, long) For example, you can fix the above

code by using the View.post(Runnable) method:



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();
}


Now this implementation is thread-safe: the network operation is done from a separate thread while the ImageView is manipulated from the UI thread.

Thread-safe methods

In some situations, the methods you implement(工具) might be called from more than one thread, and therefore must be written to be thread-safe.


This is primarily true for methods that can be called remotely(遥远地)—such as methods in a bound service. When a call on a method implemented(实施) in an IBinder originates(引起) in the same process in which the IBinder is running, the method is executed(实行) in the caller’s thread. However, when the call originates in another process, the method is executed in a thread chosen from a pool of threads that the system maintains(维持) in the same process as the IBinder (it’s not executed in the UI thread of the process). For example, whereas(然而) a service’s onBind() method would be called from the UI thread of the service’s process, methods implemented in the object that onBind() returns (for example, a subclass(亚纲) that implements RPC methods) would be called from threads in the pool. Because a service can have more than one client, more than one pool thread can engage(吸引) the same IBinder method at the same time. IBinder methods must, therefore, be implemented to be thread-safe.


Similarly, a content provider can receive data requests that originate in other processes. Although the ContentResolver and ContentProvider classes hide the details of how the interprocess(进程间) communication is managed, ContentProvider methods that respond(回答) to those requests—the methods query(), insert(), delete(), update(), and getType()—are called from a pool of threads in the content provider’s process, not the UI thread for the process. Because these methods might be called from any number of threads at the same time, they too must be implemented(实施) to be thread-safe.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: