Android DOC翻译—Processes and Threads

Processes and Threads

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.

 

当一个APP的组件启动,并且这个应用没有任何一个组件已经运行在系统中的时候,那么Android 就会为这个APP启动一个新的linux线程来运算。默认的,所有组件运行在同一个线程里(叫做:主线程)。如果APP的组件启动或者已经启动了一个进程,那么这个组件就会在这个线程中执行。不过,你可以安排APP中不同的组件运行在分散的线程中,并且,也可以在一个进程中创建多个线程。

 

Processes

By default, all components of the same application run in the same process and most applications should not change this. However, if you find that you need to control which process a certain component belongs to, you can do so in the manifest file.

 

       默认情况下,一个APP的所有组件都要运行在相同的进程中,并且大多数程序都不能改变这个情况。不过,如果你发现,你需要控制一个进程的某些部分,那么你可以修改manifest 文件。

 

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 setandroid: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中的每一种component ,<activity>, <service>, <receiver>, and <provider>都有一个android:process 的属性,指定组件可以在哪个进程中运行,你也可以设置成,“每个组件运行在自己的线程中”或者“当别人不分享时,分享一些进程给别人”或者“让不同程序的组件运行在同一个进程中”—这需要应用程序提供相同的linux user ID 并且标示着相同的证书。

 

The <application> element also supports an android:process attribute, to set a default value that applies to all components.

 

    <application> 这个元素同样提供了android:process 这个属性,去对于所有components 的默认值。

 

Android might decide to shut down a process at some point, when memory is low and required by other processes that are more immediately serving the user. Application components running in the process that's killed are consequently destroyed.  A process is started again for those components when there's again work for them to do.
     

        Android会在内存较低时,或者在那些更直接服务用户的进程(理解为优先级较高的进程)需要内存时,会杀死一些进程。运行在进程中得组件也因此被杀死。一个进程只有当组件再次被启动时才能开始工作。

 

When deciding which processes to kill, the Android system weighs their relative importance to the user.  For example, it more readily shuts down a process hosting activities that are no longer visible on screen, compared to a process hosting visible activities. The decision whether to terminate a process, therefore, depends on the state of the components running in that process. The rules used to decide which processes to terminate is discussed below.

 

       当进程被杀死的时候,Android将权衡哪些进程对于系统相对重要。举例,相比于那些可见的线程,系统更容易删除那些保存着Activity的而不再显示在屏幕上的进程。因此,依靠这些进程中components的状态。这些规则将决定谁会被终止。

Process lifecycle

The Android system tries to maintain an application process for as long as possible, but eventually needs to remove old processes to reclaim memory for new or more important processes.  To determine which processes to keep and which to kill, the system places each process into an "importance hierarchy" based on the components running in the process and the state of those components.  Processes with the lowest importance are eliminated first, then those with the next lowest importance, and so on, as necessary to recover system resources.

 

        Android系统尽可能唱得去保持一个应用程序,但最终,当需要移除旧进程去为新的更重要的进程去回收内存的时候,应该觉得,哪个进程被杀死,哪个被保存,系统这些组件的state很重。优先级最低的将优先被淘汰,然后是次低级的。。。等等。

 

There are five levels in the importance hierarchy. The following list presents the different types of processes in order of importance (the first process is most important and iskilled last):

        下面有五个重要的等级,

       1、前台进程(Foreground process):
  用户当前工作所需要的。一个进程如果满足下列任何条件被认为是前台进程:正运行着一个正在与用户交互的活动(Activity对象的onResume()方法已经被调用)。
  寄宿了一个服务,该服务与一个与用户交互的活动绑定。
  有一个Service对象执行它的生命周期回调(onCreate()、onStart()、onDestroy())。
  有一个BroadcastReceiver对象执行他的onReceive()方法。
  在给定时间内仅有少数的前台进程存在。仅作为最后采取的措施他们才会被杀掉——如果内存太低以至于他们不能继续运行。
 

    

     2、可视进程(Visible process):
  没有任何前台组件,但是仍然能影响用户在屏幕上看到东西。一个进程满足下面任何一个条件都被认为是可视的:  寄宿着一个不是前台的活动,但是它对用户仍可见(它的onPause()方法已经被调用)。举例来说,这可能发生在,如果一个前台活动在一个对话框(其他进程的)运行之后仍然是可视的,比如输入法的弹出时。
  寄宿着一个服务,该服务绑定到一个可视的活动。
  一个可视进程被认为是及其重要的且不会被杀死,除非为了保持前台进程运行。
 

   

    3、服务进程(Service process):

       是一个运行着一个用startService()方法启动的服务,并且该服务并没有落入上面2种分类。虽然服务进程没有直接关系到任何用户可见的,它们通常做用户关心的事(诸如在后台播放mp3或者从网络上下载数据),因此系统保持它们运行,除非没有足够内存来保证所有的前台进程和可视进程。
 

 

    4、后台进程(Background process):

       是一个保持着一个当前对用户不可视的活动(已经调用Activity对象的onStop()方法)(如果还有除了UI线程外其他线程在运行话,不受影响)。这些进程没有直接影响用户体验,并且可以在任何时候被杀以收回内存用于一个前台、可视、服务进程。一般地有很多后台进程运行着,因此它们保持在一个LRU(least recently used,即最近最少使用,如果您学过操作系统的话会觉得它很熟悉,跟内存的页面置换算法LRU一样。)列表以确保最近使用最多的活动的进程最后被杀。


  5、空进程(Empty process): 

      是一个没有保持活跃的应用程序组件的进程。保持这个进程可用的唯一原因是作为一个cache以提高下次启动组件的速度。系统进程杀死这些进程,以在进程cache和潜在的内核cache之间平衡整个系统资源。

  一个进程的排名因为其他进程依赖它而上升。一个进程服务其它进程,它的排名从不会比它服务的进程低。例如,进程A中的一个内容提供者服务进程B中的一个客户,或者进程A中的一个服务绑定到进程B中的一个组件,进程A总是被认为比进程B重要。
  因为一个服务进程排名比后台活动的进程排名高,一个活动启动一个服务来初始化一个长时间运行操作,而不是简单地衍生一个线程——特别是如果操作很可能会拖垮活动(例如出现ANR)。这方面的例子是在后台播放音乐和上传相机拍摄的图片到一个网站。使用服务保证操作至少有“服务进程”的优先级,无论活动发生什么情况。

Threads

When an application is launched, the system creates a thread of execution for the application, called "main." This thread is very important because it is in charge of dispatching events to the appropriate user interface widgets, including drawing events. It is also the thread in which your application interacts with components from the Android UI toolkit (components from the android.widget and android.view packages). As such, the main thread is also sometimes called the UI thread.

        当一个APP被启动,系统会创建一个线程去执行。叫做“主线程”。这个线程非常重要,因为,这个线程,负责event处理和UI交互,这个线程,也是用来于Android UI toolkit 交互的,因此,主线程有时也被称为UI线程。

 

     当线程被阻塞,就会出现ANR,所以对于Android 单线程模型。

    1.不要阻碍UI线程,

    2.不要在UI线程之外调用UI控件。

 

Worker threads

 

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

 

AysncTask

 

AsyncTask  allows you to perform asynchronous work on your user interface. It performs the blocking operations in a worker thread and then publishes the results on the UI thread, without requiring you to handle threads and/or handlers yourself.

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.

      使用AsyncTask ,需要继承AsyncTask 并且实现 doInBackground() ,通过实现onPostExecute()这个方法来更新UI,可以通过调用execute()这个方法来执行任务。

 

 

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

 

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 theIBinder 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'sonBind() 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 ContentProviderclasses 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.

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值