当前位置:操作系统 > 安卓/Android >>

android - 为响应度而设计 - 开发文档翻译

Designing for Responsiveness
为响应度而设计
It's possible to write code that wins every performance test in the world, but still sends users in a fiery rage when they try to use the application.
These are the applications that aren't responsive enough — the ones that feel sluggish, hang or freeze for significant periods, or take too long to process input.
有可能写出的代码赢得了每一次性能测试,但是却仍然使得当用户尝试使用应用时,使他们处于怒火之中。
这是因为应用的响应不够迅速 - 这些应用感觉缓慢,挂起或者冻结很长时间,或者处理输入时间过长。


In Android, the system guards against applications that are insufficiently responsive for a period of time by displaying a dialog to the user, called the Application Not Responding (ANR) dialog, shown at right in Figure 1.
The user can choose to let the application continue, but the user won't appreciate having to act on this dialog every time he or she uses your application.
It's critical to design responsiveness into your application, so that the system never has cause to display an ANR dialog to the user.
在Android中,系统监视那些一段时间内反应不够迅速的应用,显示一个对话框给用户,叫做Application Not Responding (ANR)对话框,向下图所示那样。
用户可以选择是让应用继续,但是每一次使用你的应用,用户不会喜欢不得不依照系统弹出的对话框做相应操作
设计较好响应性的应用是很重要的,这样系统才不会给用户显示一个ANR对话框。

Generally, the system displays an ANR if an application cannot respond to user input.
For example, if an application blocks on some I/O operation (frequently a network access), then the main application thread won't be able to process incoming user input events.
After a time, the system concludes that the application is frozen, and displays the ANR to give the user the option to kill it.
一般来说,如果一个应用不能响应用户输入,则系统显示一个ANR。
例如:如果一个应用在一些I/O操作中阻塞了(经常是一个网络访问),那么主应用线程不会有能力处理用户的输入事件。
一段时间后,系统推断出这个应用冻结了,然后显示一个ANR给用户一个选择来杀死此应用。


Similarly, if your application spends too much time building an elaborate in-memory structure, or perhaps computing the next move in a game, the system will conclude that your application has hung.
It's always important to make sure these computations are efficient using the techniques above, but even the most efficient code still takes time to run.
相似的,如果你的应用消耗太多时间来建立一个复杂的内存中的结构,或者也许计算游戏中的下一步,系统会断定你的应用已经挂起。
总是保证使用上面的技巧这些计算是有效率的是很重要的,但是即使是最有效的代码也需要时间来运行。


In both of these cases, the recommended approach is to create a child thread and do most of your work there.
This keeps the main thread (which drives the user interface event loop) running and prevents the system from concluding that your code has frozen.
Since such threading usually is accomplished at the class level, you can think of responsiveness as a class problem. (Compare this with basic performance, which was described above as a method-level concern.)
这两种情况中,推荐的方法是建立一个子线程来做你在那里的大部分工作。
这样保持主线程运行并且阻止系统认定你的代码已经冻结。
因为这样的线程经常在类级别中完成,你可以把响应性作为一个类的问题考虑。


This document describes how the Android system determines whether an application is not responding and provides guidelines for ensuring that your application stays responsive.
这个文档描述了Android系统如何决定是否一个应用是无响应并且提供直到方针来保证你的应用保持响应。


What Triggers ANR?
什么触发ANR

In Android, application responsiveness is monitored by the Activity Manager and Window Manager system services.
Android will display the ANR dialog for a particular application when it detects one of the following conditions:
在Android中,应用响应度是由Activity Manager和Window Manager系统服务监视的。
Android当发现到下面其中一个条件发生的时候,会特定的应用显示ANR对话框。

No response to an input event (e.g. key press, screen touch) within 5 seconds
A BroadcastReceiver hasn't finished executing within 10 seconds
一个输入事件5秒内没有反馈
一个BroadcastReceiver在10秒内没有执行完毕。


How to Avoid ANR
如何避免ANR

Given the above definition for ANR, let's examine why this can occur in Android applications and how best to structure your application to avoid ANR.
已知上面ANR的定义,让我们检查为什么这些能在Android应用中发生并且如何最好的架构你的应用来避免ANR。


Android applications normally run entirely on a single (i.e. main) thread.
This means that anything your application is doing in the main thread that takes a long time to complete can trigger the ANR dialog because your application is not giving itself a chance to handle the input event or Intent broadcast.
Android应用通常整个都运行在一个线程中(主线程)。
这意味着,你应用中做的任何事情都在主线程,花费长时间来完成可能触发ANR对话框,因为你的应用没有给它自己机会来处理用户输出或者Intent广播。


Therefore any method that runs in the main thread should do as little work as possible.
In particular, Activities should do as little as possible to set up in key life-cycle methods such as onCreate() and onResume().
Potentially long running operations such as network or database operations, or computationally expensive calculations such as resizing bitmaps should be done in a child thread (or in the case of databases operations, via an asynchronous request).
However, this does not mean that your main thread should block while waiting for the child thread to complete — nor should you call Thread.wait() or Thread.sleep().
Instead of blocking while waiting for a child thread to complete, your main thread should provide a Handler for child threads to post back to upon completion.
Designing your application in this way will allow your main thread to remain responsive to input and thus avoid ANR dialogs caused by the 5 second input event timeout.
These same practices should be followed for any other threads that display UI, as they are also subject to the same timeouts.
因此主线程运行的任何方法都应该尽量少的工作。
尤其是,Activity应该尽量少的工作来准备关键的生命周期方法,比如onCreate()和onResume().
潜在的长时间运行的操作,如网络或者数据库操作,或者高代价的计算,比如调整bitmap大小,应该在一个子线程中完成。
然而,这不意味着你的主线程应该在等待子线程完成时而阻塞,你的主线程应该为子线程提供一个Handler,当完成时把结果返回给主线程 - 而不该调用Thread.wait()或Thread.sleep()。


You can use StrictMode to help find potentially long running operations such as network or database operations that you might accidentally be doing your main thread.
你可以使用StrictMode来帮助你找到潜在的长时间运行的操作,比如你也许意外的在你的主线程进行的网络或数据库操作。


The specific constraint on IntentReceiver execution time emphasizes what they were meant to do: small, discrete amounts of work in the background such as saving a setting or registering a Notification.
So as with other methods called in the main thread, applications should avoid potentially long-running operations or calculations in BroadcastReceivers.
But instead of doing intensive tasks via child threads (as the life of a BroadcastReceiver is short), your application should start a Service if a potentially long running action needs to be taken in response to an Intent broadcast.
As a side note, you should also avoid starting an Activity from an Intent Receiver, as it will spawn a new screen that will steal focus from whatever application the user is currently

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,