胡凯

Android Training - 避免程序无响应ANR

| Comments

可能你写的代码在性能测试上表现良好,但是你的应用仍然有时候会反应迟缓(sluggish),停顿(hang)或者长时间卡死(frezze),或者应用处理输入的数据花费时间过长。对于你的应用来说最槽糕的事情是出现”程序无响应(Application Not Responding)” (ANR)的警示框。

在Android中,系统通过显示ANR警示框来保护程序的长时间无响应。对话框如下:

anr

此时,你的应用已经经历过一段时间的无法响应了,因此系统提供用户可以退出应用的选择。为你的程序提供良好的响应性是至关重要的,这样才能够避免系统为用户显示ANR的警示框。

这节课描述了Android系统是如何判断一个应用不可响应的。这节课还会提供程序编写的指导原则,确保你的程序保持响应性。

是什么导致了ANR?(What Triggers ANR?)

通常来说,系统会在程序无法响应用户的输入事件时显示ANR。例如,如果一个程序在UI线程执行I/O操作(通常是网络请求或者是文件读写),这样系统就无法处理用户的输入事件。或者是应用在UI线程花费了太多的时间用来建立一个复杂的在内存中的数据结构,又或者是在一个游戏程序的UI线程中执行了一个复杂耗时的计算移动的操作。确保那些计算操作高效是很重要的,不过即使是最高效的代码也是需要花时间执行的。

Android Training - Volley(Lesson 4 - 实现自定义的请求)

| Comments

这节课会介绍如何实现你自定义的请求类型,这些自定义的类型不属于Volley内置支持包里面。

编写一个自定义的请求Write a Custom Request

大多数的请求类型都已经包含在Volley的工具箱里面。如果你的请求返回数值是一个string,image或者JSON,那么你是不需要自己去实现请求类的。

对于那些你需要自定义的请求类型,下面是你需要做得步骤:

  • 继承Request<T>类,<T>表示了请求返回的数据类型。因此如果你需要解析的响应类型是一个String,可以通过继承Request<String>来创建你自定义的请求。请参考Volley工具类中的StringRequest与 ImageRequest来学习如何继承Request
  • 实现抽象方法parseNetworkResponse()deliverResponse(),下面会详细介绍。

parseNetworkResponse

为了能够提交一种指定类型的数据(例如,string,image,JSON等),需要对解析后的结果进行封装。下面会演示如何实现parseNetworkResponse()

1
2
3
4
5
6
7
8
9
10
11
12
@Override
protected Response<T> parseNetworkResponse(
        NetworkResponse response) {
    try {
        String json = new String(response.data,
        HttpHeaderParser.parseCharset(response.headers));
    return Response.success(gson.fromJson(json, clazz),
    HttpHeaderParser.parseCacheHeaders(response));
    }
    // handle errors
...
}

Android Training - Volley(Lesson 3 - 创建标准的请求)

| Comments

这一课会介绍如何使用Volley支持的常用请求类型:

  • StringRequest。指定一个URL并在相应回调中接受一个原始的raw string数据。请参考前一课的示例。
  • ImageRequest。指定一个URL并在相应回调中接受一个image。
  • JsonObjectRequestJsonArrayRequest (均为JsonRequest的子类)。指定一个URL并在相应回调中获取到一个JSON对象或者JSON数组。

如果你需要的是上面演示的请求类型,那么你应该不需要自己实现一个自定义的请求。这节课会演示如何使用那些标准的请求类型。关于如何实现自定义的请求,请看下一课:实现自定义的请求

1)Request an Image

Volley为请求图片提供了如下的类。这些类依次有着依赖关系,用来支持在不同的层级进行图片处理:

  • ImageRequest - 一个封装好的,用来处理URL请求图片并且返回一张decode好的bitmap的类。它同样提供了一些简便的接口方法,例如指定一个大小进行重新裁剪。它的主要好处是Volley回确保类似decode,resize等耗时的操作执行在工作线程中。

  • ImageLoader - 一个用来处理加载与缓存从网络上获取到的图片的帮助类。ImageLoader是管理协调大量的ImageRequest的类。例如,在ListView中需要显示大量缩略图的时候。ImageLoader为通常的Volley cache提供了更加前瞻的内存缓存,这个缓存对于防止图片抖动非常有用。。这还使得能够在避免阻挡或者延迟主线程的前提下在缓存中能够被Hit到。ImageLoader还能够实现响应联合Coalescing,每一个响应回调里面都可以设置bitmap到view上面。联合Coalescing使得能够同时提交多个响应,这提升了性能。

  • NetworkImageView - 在ImageLoader的基础上建立,替换ImageView进行使用。对于需要对ImageView设置网络图片的情况下使用很有效。NetworkImageView同样可以在view被detached的时候取消pending的请求。

Android Training - Volley(Lesson 2 - 建立请求队列)

| Comments

前一节课演示了如何使用Volley.newRequestQueue这一简便的方法来建立一个RequestQueue,这是利用了Volley默认的优势。这节课会介绍如何显式的建立一个RequestQueue,以便满足你自定义的需求。

这节课同样会介绍一种推荐的实现方式:创建一个单例的RequestQueue,这使得RequestQueue能够持续保持在你的app的生命周期中。

Set Up a Network and Cache

一个RequestQueue需要两部分来支持它的工作:一部分是网络操作用来执行请求的数据传输,另外一个是用来处理缓存操作的Cache。在Volley的工具箱中包含了标准的实现方式:DiskBasedCache提供了每个文件与对应响应数据一一映射的缓存实现。 BasicNetwork提供了一个网络传输的实现,连接方式可以是AndroidHttpClient 或者是 HttpURLConnection.

BasicNetwork是Volley默认的网络操作实现方式。一个BasicNetwork必须使用HTTP Client进行初始化。这个Client通常是AndroidHttpClient 或者 HttpURLConnection: