android sdk Process and Threads 翻译

当一个应用程序刚开始运行,同时这个应用程没有其他的正在运行的组件,android系统将会以一个单独运行的线程方式为这个应用程序开启一个新的linux进程。默认的,一个应用程序上的所有的组件运行在相同的进程和线程(被叫做“main”的线程上)上。如果一个应用程序组件开始运行时,同时为这个应用程序也存在一个进程(因为这个应用程序存在的其他的组件),那么这个组件在这个进程中运行并且使用正在执行的那个线程。然而,您可以安排不同的组件在你的应用程序去运行在单独的进程中,你还可以为任何进程创建额外的线程
这篇文章讨论的是进程和线程是如何工作在一个android程序上的
进程
默认的情况是同一个应用程序上的所有的组件运行在相同的进程上,多数的应用程序不应改变这个默认的情况。当然,你也可以在清单列表中设置,那个组件运行在哪一个进程上。
这个清单文件为每一类型的组件设置一个清单条目-<activity>,<service>,<receiver>,<provider>-它们都支持android:process这种属性,这种属性能够控制摸一个进程供哪一个组件运行。你能够设置这个属性让每一个组件运行在它们自己的进程中或者一些组件共享一个进程。你还能够设置这个属性android:process,让不同的应用程序的组件运行在相同的进程上-实现方式是提供给这些应用程序相同的Linux用户ID和赋予同样的证书。
在<application>标签中也支持android:process属性,它设置一个值后,所有的组件都适用这个值。
当内存不够,同时又有其他的进程请求使用内存的时候,android就会关闭一个进程供使用者使用,当一个进程被关闭后,运行在这个进程上的应用程序组件都会被摧毁。直到这个应用程序上的组件重新运行工作的时候,这个进程也会重新运行。
对于决定关闭哪一个进程,android系统会衡量哪一个对使用者比较重要。例如,相比一个正在可见的活动的窗口它可能会比较容易关闭一个长时间没有活动的后台的活动窗口,因此,决定是否终止一个进程取决于组件中在这个进程中运行的状态,下面将讨论关闭哪个进程的判定的规则
进程的周期
Android系统试图尽可能保持应用程序进程,但终究还是需要删除旧的进程来回收内存给那些新的或更重要的是过程。为了确定哪个进程保留或终止,系统把每个进程都划入一个基于组件运行在这些组件的过程和状态的“重要性层次结构”表。重要性最低的进程是第一个被消除,然后是次重要性,等等,以方便必要时恢复系统资源。
有五个级别在重要性层次结构表。下面的列表给出了不同类型的进程的重要性(第一个过程是最重要的,也是最后被终止的)。
1、前台进程
用户去做一些事情所产生的一个进程。判定一个进程是不是前台进程,看是否符合下面描述的任何的一种情况
2、可见进程
3、服务进程
4、后台进程
后台进程又由一个叫做LRU(最近使用列表)的列表控制,最长时间没有使用的最先被终止
5、空进程
为什么会产生一个空进程呢,是因为系统会为某个程序预先产生一个进程,以便能够快速的加载

线程

当应用程序启动时,系统为应用程序创建一个线程的执行,称为"main",这个线程非常重要,因为它负责把事件分发给相应的用户界面部件,包括屏幕绘图事件。也是你的应用程序与组件交互的线程,这些组件来源于Android UI 工具包(组件从Android.widget和android.view)。因此,主线程有时也称为UI线程。
系统不为每个组件的实例创建一个单独的线程。所有组件运行在相同的进程并在UI线程被实例化,并且系统调用每一个组件都是通过这个线程派发的。通常,响应系统回调的方法(例如:onKeyDown)也是在这个进程的UI线程中运行的。

例如,当用户触摸屏幕上的按钮时,应用程序的UI线程分派触摸事件的小部件,进而设置按下状态,传递一个无效请求事件队列。UI线程出列请求和通知小部件应该改变自己。
当你的应用程序来响应用户交互执行密集的工作,这个单线程模型能产生不佳的表现,除非你正确的处理你的应用程序。具体地说,如果一切都发生在UI线程,执行长期操作如网络访问或数据库查询将阻止整个UI。当线程被阻塞时,所有事件都不能被分发,包括屏幕绘图事件。从用户的角度来看,应用程序挂起。更糟糕的是,如果UI线程被阻塞超过几秒钟目前(大约5秒钟),用户界面就会弹出“应用程序没有响应”(ANR)对话框。用户可能会决定退出你的应用程序和卸载它,通常都是带着嫌弃的情绪。

此外,Andoid UI工具包不是线程安全的。所以,你不能操作UI允许从一个工人操作的用户界面UI线程。因此,有两个简单的规则为Android的单线程模型: 1、不阻塞UI线程2、不从外部UI线程访问Android UI工具包。
工作线程
由于上述单线程模型,这是至关重要的应用程序的UI的响应性以至于你不阻塞UI线程。如果你有不及时操作执行,你应该确保他们在单独的线程(“后台”或“工作”线程)

例如,下面是一些代码点击监听器,下载一个图像从一个单独的线程在ImageView并显示
public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            Bitmap b = loadImageFromNetwork("http://example.com/image.png");
            mImageView.setImageBitmap(b);
        }
    }).start();
}

首先,这段代码似乎运行的很好,因为它创建了一个新线程来处理网络操作。然而,它违反了单线程模型的第二条规则:不要从外部访问Android UI 工具包-这个例子修改了ImageView工作线程而不是UI线程。这可能导致未定义的和意想不到的行为,并且很难非常耗费时间去查出问题。
要修复这个问题,Android提供了几种方法来从其他线程访问UI线程。这里是一个列表的方法,可以得到一些帮助:
    Activity.runOnUiThread(Runnable)
    View.post(Runnable)
    View.postDelayed(Runnable, long)
例如,你可以修改上面的代码通过使用 View.post(Runnable)方法
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();
}

现在这个实现是线程安全的:网络操作从一个单独的线程,一段时间后ImageView通过UI线程被操纵
然而,随着操作的复杂性,这种代码也会变得很复杂,很难维护。为了用一个工作线程去处理复杂的交互,你可能需要考虑使用一个Handler在你的工作线程里,从UI线程处理消息交付。也许最好的解决方案,是继承AsyncTask类,这样将简化工作线程任务和UI交互的执行。

使用AsyncTask
AsyncTask允许您执行异步工作在你的用户界面。它执行阻塞操作在一个工作线程,然后在UI线程上公布结果,不需要你自己处理线程和/或处理程序。
使用它,您必须实现AsyncTask子类,实现doInBackground()回调方法,运行在一个后台线程池。更新UI,你应该实现onPostExecute(),交付结果从doInBackground()和在UI线程中运行,所以您可以安全地更新UI。然后您可以运行任务从UI线程通过调用execute()。
例如,您可以使用AsyncTask实现前面的示例:
public void onClick(View v) {
    new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {

protected Bitmap doInBackground(String... urls) {
        return loadImageFromNetwork(urls[0]);
    }

protected void onPostExecute(Bitmap result) {
        mImageView.setImageBitmap(result);
    }
}
现在UI是安全的,代码更简单,因为它分离的部分应该做的工作在一个工作线程的部分应该在UI线程上。

时间: 2024-10-10 15:46:34

android sdk Process and Threads 翻译的相关文章

Ubuntu下android studio 编译报错A problem occurred starting process &#39;command &#39;/Android/Sdk/build-tools/21.1.2/aapt&#39;&#39;

此问题在stack  over flow 上找到答案. 原链接地址:http://stackoverflow.com/questions/27589844/android-studio-1-0-2-not-building-appmergedebugresources-error 解决方法: //在终端分别运行下面两条指令,安装lib32stdc++6 和lib32z1 sudo apt-get install lib32stdc++6 sudo apt-get install lib32z1

「android」Ubuntu下android studio 编译报错A problem occurred starting process &#39;command &#39;/Android/Sdk/build-tools/21.1.2/aapt&#39;&#39;(转)

转自”http://www.cnblogs.com/jonzone/p/5246531.html“ 此问题在stack  over flow 上找到答案. 原链接地址:http://stackoverflow.com/questions/27589844/android-studio-1-0-2-not-building-appmergedebugresources-error 解决方法: //在终端分别运行下面两条指令,安装lib32stdc++6 和lib32z1 sudo apt-get

GoBelieve Android SDK接入备忘

Android SDK版本 目前SDK只支持Android 2.2或以上版本的手机系统. AndroidManifest.xml配置 以下配置可以在IMDemo/AndroidManifest.xml 找到并直接拷贝放置进自己的应用工程中的AndroidManifest.xml文件对应的tag中. manifest 标签下添加: <!-- 必需: 权限配置 --> <uses-permission android:name="android.permission.INTERNE

Qt on Android: Android SDK安装

之前我在 <Windows下Qt 5.2 for Android开发入门>一文中介绍了 Windows 下 Qt on Android 开发环境的搭建,略过了 Android SDK 的安装,实际还是有一些朋友会在这里遇到问题.这里再专门介绍一下 Android SDK 的安装. 版权全部,转载请注明出处:http://blog.csdn.net/foruok Android SDK 能够到这里下载:http://developer.android.com/sdk/index.html . 假

/Android/sdk/build-tools/21.1.2/aapt&#39;&#39; finished with non-zero exit value 42

相信很多朋友都会遇到 Error:Error: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/billy/Library/Android/sdk/build-tools/21.1.2/aapt'' finished with non-zero exit value 42 这个问题,找了很多资料,虽然解决了,但是

Android Interface Definition Language (AIDL)——翻译自developer.android.com

Android 接口定义语言(AIDL) AIDL类似你可能接触过的其他的IDL.它可以让你定义编程接口,使得客户端和服务端可以达成一致,从而使用IPC(interprocess communication)相互通信. 在Android里面,一个进程通常不能访问其他进程的内存.所以说,他们需要将对象分解为操作系统可以理解的基本的部分,从而使得这些对象为你突破界限.然而突破界限的代码太繁杂,所以Android使用AIDL替你打理. 提示:只有当你想要不同app的客户端都可以对你的service I

Gprinter Android SDK V2.1 使用说明

Gprinter Android SDK旨在佳博用户更快速,更高效的在Android平台下开发和使用佳博打印机.如果您在使用SDK中碰到问题,或者发现BUG,请留言 一.下载GprinterSDKV2.1 GprinterSDKV2.1可打电话到0756-3866865,填写客户资料后,即可获得. 二.新建工程,导入gprinter-2.1.jar包 向工程的libs文件中拷贝gprinter-2.1.jar 三.注册服务 在AndroidManifest文件中添加服务,gprinter-2.1

Android 关于百度地图Android SDK几处修正使用说明(非官方)

本篇主要是因为最近在学习使用百度地图,发现了一些问题,跟大伙分享一下. 1.根据android sdk开发指南中"Hello World"的例子,构建一个基础的地图页面,如果大家完全按照示例代码中所写的那样,是不会执行成功的,会有以下问题的错误提示"java.lang.RuntimeException: Unable to instantiate activity ComponentInfo" 这个问题出现的原因是 在第二步,配置Activity部分,android

【Android官方文档】翻译Android官方文档-Activities(一)

Activity是可以给用户提供交互操作的程序组件,例如打电话,拍照,发送邮件,抑或者是显示地图.通常窗口会填满屏幕,但是也可以做到比屏幕小或者是悬浮在窗口顶部. App通常由多个Activities组成,它们之间支持相互跳转.一般情况下,每个Activity在应用中都是特别的,就好像 主Activity一样,主activity是应用第一个Activity,其他Activity可以通过其他操作启动.一个新的Activity的启动,那么旧Activity就会被停止,但是系统会保存这些activit