熊猫儿 发表于 2016-9-21 16:55

启动一个缓存mCacheDispatcher线程,用来读取缓存数据,启动若干个网络请求mDispatchers线程,用来实现网络通信。
mCacheDispatcher线程的 run 方法<code class=" hljs java" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">    <span class="hljs-annotation" style="box-sizing: border-box; color: rgb(136, 136, 136);">@Override</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">void</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">run</span>() {      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">if</span> (DEBUG) VolleyLog.v(<span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"start new dispatcher"</span>);      Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);      <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">// Make a blocking call to initialize the cache.</span>      <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//初始化缓存</span>      mCache.initialize();      <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//循环获取缓存请求</span>      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">while</span> (<span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">true</span>) {            <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">try</span> {                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">// Get a request from the cache triage queue, blocking until</span>                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">// at least one is available.</span>                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//从缓存队列中获取缓存请求,如果没有缓存请求,这个方法会阻塞在这里</span>                <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">final</span> Request request = mCacheQueue.take();                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//打印 log 信息</span>                request.addMarker(<span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"cache-queue-take"</span>);                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">// If the request has been canceled, don't bother dispatching it.</span>                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//如果请求终止了,结束本次循环</span>                <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">if</span> (request.isCanceled()) {                  request.finish(<span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"cache-discard-canceled"</span>);                  <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">continue</span>;                }                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">// Attempt to retrieve this item from cache.</span>               <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//获取缓存数据,如果没有,把请求加入到网络请求的队列中</span>                Cache.Entry entry = mCache.get(request.getCacheKey());                <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">if</span> (entry == <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">null</span>) {                  request.addMarker(<span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"cache-miss"</span>);                  Log.i(<span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"CacheDispatcher"</span>, <span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"没有缓存数据:"</span> + request.getUrl());                  mNetworkQueue.put(request);                  <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">continue</span>;                }                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">// If it is completely expired, just send it to the network.</span>                <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//判断缓存是否已经过期,如果过期,把请求加入到网络请求的队列中,直接请求网络获取数据</span>                <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">if</span> (entry.isExpired()) {                  request.addMarker(<span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"cache-hit-expired"</span>);                  request.setCacheEntry(entry);                  Log.i(<span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"CacheDispatcher"</span>, <span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"缓存数据过期:"</span> + request.getUrl());                  mNetworkQueue.put(request);                  <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">continue</span>;                }

熊猫儿 发表于 2016-9-21 16:55

如果缓存不符合要求,网络线程终止阻塞得到执行;
我们一般习惯用法是在 Application 中全局初始化RequestQueue mRequestQueue,并启动它,让整个应用都能获取到。具体运用将会在下面用到。三、Volley 实战 GET 请求和 POST 请求这里我用酷狗音乐播放器中的一个音乐搜索功能的接口来实现这两种请求
接口:http://mobilecdn.kugou.com/api/v3/search/song?keyword=冰雨
返回数据:
http://img.blog.csdn.net/20150301072810035
根据返回数据我们可以把基本数据类型定义出来

熊猫儿 发表于 2016-9-21 16:56

根据返回数据我们可以把基本数据类型定义出来http://img.blog.csdn.net/20150301121027845SearchResult 就是整个数据的对象,ListSong 对应的是 Data 对象,SongDetail是info 下的每个 item 对象。
1、GET 请求
第一步:在 Application 中初始化RequestQueue,<code class=" hljs cs" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;">    <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//初始化请求队列</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">private</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">void</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">initRequestQueue</span>(){      VollayUtil.initialize(mContext);    }</code><code class=" hljs java" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-javadoc" style="box-sizing: border-box; color: rgb(136, 136, 255);">/** * Created by gyzhong on 15/3/1. */</span><span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">VolleyUtil</span> {</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">private</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">static</span> RequestQueue mRequestQueue ;    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">static</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">void</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">initialize</span>(Context context){      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">if</span> (mRequestQueue == <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">null</span>){            <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">synchronized</span> (VolleyUtil.class){                <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">if</span> (mRequestQueue == <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">null</span>){                  mRequestQueue = Volley.newRequestQueue(context) ;                }            }      }      mRequestQueue.start();    }    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">static</span> RequestQueue <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">getRequestQueue</span>(){      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">if</span> (mRequestQueue == <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">null</span>)            <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">throw</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">new</span> RuntimeException(<span class="hljs-string" style="box-sizing: border-box; color: rgb(136, 0, 0);">"请先初始化mRequestQueue"</span>) ;      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">return</span> mRequestQueue ;    }}</code>

熊猫儿 发表于 2016-9-21 16:59

第二步:定制 Request
先来分析接口所返回的数据,我们看到是一条 json 数据,虽然 Volley 中已经为我们定制好了JsonObjectRequest请求,但我们知道,在数据具体显示的时候,是需要把 json 数据转化为对象进行处理,所以这里我们可以定制通用的对象请求。如何定制呢?
先看StringRequest的实现代码<code class=" hljs axapta" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//继承Request<String>,String 为请求解析之后的数据</span><span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">StringRequest</span> <span class="hljs-inheritance" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">extends</span></span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">Request</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">String</span>> {</span>    <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//正确数据回调接口</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">private</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">final</span> Listener<String> mListener;    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">public</span> StringRequest(<span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">int</span> method, String url, Listener<String> listener,            ErrorListener errorListener) {      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">super</span>(method, url, errorListener);      mListener = listener;    }    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">public</span> StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">this</span>(Method.GET, url, listener, errorListener);    }    <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//回调解析之后的数据</span>    @Override    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">protected</span> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">void</span> deliverResponse(String response) {      mListener.onResponse(response);    }    <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">//解析数据,把网络请求,或者中缓存中获取的数据,解析成 String</span>    @Override    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">protected</span> Response<String> parseNetworkResponse(NetworkResponse response) {      String parsed;      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">try</span> {            parsed = <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">new</span> String(response.data, HttpHeaderParser.parseCharset(response.headers));      } <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">catch</span> (UnsupportedEncodingException e) {            parsed = <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">new</span> String(response.data);      }      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">return</span> Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));    }}</code>

熊猫儿 发表于 2016-9-21 16:59

通过上面代码可知,StringRequest继承了 Request 并实现了两个抽象方法parseNetworkResponse()和 deliverResponse(),这两个方法很好理解,parseNetworkResponse()把获取到的数据解析成我们所定义的数据类型;deliverResponse()把所解析的数据通过回调接口回调给展示处。
为了简化回调接口,这里把错误回调Response.ErrorListener 和正确的数据回调Response.Listener合并成一个ResponseListener<code class=" hljs php" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/** * Created by gyzhong on 15/3/1. * 简化回调接口 */</span><span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">ResponseListener</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">T</span>> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">Response</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">ErrorListener</span>,<span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">Response</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">Listener</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">T</span>> {</span>}</code>根据 StringRequest,如法炮制<code class=" hljs scala" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-javadoc" style="box-sizing: border-box; color: rgb(136, 136, 255);">/** * Created by gyzhong on 15/3/1. */</span>public <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">GetObjectRequest</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">T</span>> <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">Request</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(136, 0, 0); font-weight: bold;">T</span>> {</span>    <span class="hljs-javadoc" style="box-sizing: border-box; color: rgb(136, 136, 255);">/**   * 正确数据的时候回掉用   */</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">private</span> ResponseListener mListener ;    <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*用来解析 json 用的*/</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">private</span> Gson mGson ;    <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*在用 gson 解析 json 数据的时候,需要用到这个参数*/</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">private</span> Type mClazz ;

熊猫儿 发表于 2016-9-21 16:59

public GetObjectRequest(String url,Type <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">type</span>, ResponseListener listener) {      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">super</span>(Method.GET, url, listener);      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">this</span>.mListener = listener ;      mGson = <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">new</span> GsonBuilder().excludeFieldsWithoutExposeAnnotation().create() ;      mClazz = <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">type</span> ;    }    <span class="hljs-javadoc" style="box-sizing: border-box; color: rgb(136, 136, 255);">/**   * 这里开始解析数据   * <span class="hljs-javadoctag" style="box-sizing: border-box; font-weight: bold;">@param</span> response Response from the network   * <span class="hljs-javadoctag" style="box-sizing: border-box; font-weight: bold;">@return</span>   */</span>    <span class="hljs-annotation" style="box-sizing: border-box; color: rgb(136, 136, 136);">@Override</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">protected</span> Response<T> parseNetworkResponse(NetworkResponse response) {      <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">try</span> {            T result ;            String jsonString =                  <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">new</span> String(response.data, HttpHeaderParser.parseCharset(response.headers));            result = mGson.fromJson(jsonString,mClazz) ;            <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">return</span> Response.success(result,                  HttpHeaderParser.parseCacheHeaders(response));      } <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">catch</span> (UnsupportedEncodingException e) {            <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">return</span> Response.error(<span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">new</span> ParseError(e));      }    }    <span class="hljs-javadoc" style="box-sizing: border-box; color: rgb(136, 136, 255);">/**   * 回调正确的数据   * <span class="hljs-javadoctag" style="box-sizing: border-box; font-weight: bold;">@param</span> response The parsed response returned by   */</span>    <span class="hljs-annotation" style="box-sizing: border-box; color: rgb(136, 136, 136);">@Override</span>    <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">protected</span> void deliverResponse(T response) {      mListener.onResponse(response);    }}</code>以上代码中在实例化 Gson 的时候用到的是mGson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation(),主要是用于过滤字段用的.如果有疑问的同学可以参考我前面写的一篇文章Gson 过滤字段的几种方法
第三步:获取 request<code class=" hljs vbscript" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-image: initial; background-attachment: initial; background-color: transparent !important; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-built_in" style="box-sizing: border-box; font-weight: bold;">Request</span> <span class="hljs-built_in" style="box-sizing: border-box; font-weight: bold;">request</span> = <span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">new</span> GetObjectRequest(url,<span class="hljs-keyword" style="box-sizing: border-box; font-weight: bold;">new</span> TypeToken<SearchResult>(){}.getType(),listener) ;</code>1、url -> http://mobilecdn.kugou.com/api/v3/search/song?keyword=冰雨
2、new TypeToken(){}.getType() ->为 gson 解析 json 数据所要的 type
3、listener -> 为我们定义的ResponseListener回调接口

熊猫儿 发表于 2016-9-21 17:03

Android官方开发文档Training系列课程中文版:电池续航时间优化之监测电池电量及充电状态
标签: android优化电池使用优化电池状态监测
2016-09-21 08:40 170人阅读 评论(0) 收藏 举报

http://static.blog.csdn.net/images/category_icon.jpg 分类:
翻译(102) http://static.blog.csdn.net/images/arrow_triangle%20_down.jpg


目录(?)[+]

原文地址:http://android.xsoftlab.net/training/monitoring-device-state/index.html引言作为一款优秀的APP应用,应该总是想方设法的降低电量的消耗。通过这节课的学习,你将有能力使APP可以基于设备的状态来调整APP的功能及行为。我们可以通过比如在断开连接时关闭后台服务,或者在电量低的时候降低更新的频率等等手段来降低电量的消耗。监测电池电量及充电状态在更改后台的更新频次时,检查当前的电池电量及充电状态是我们先要做的。应用程序的更新频率取决于电池的电量以及充电状态。由于设备处于充电状态时应用的耗电量几乎可以忽略,所以,在设备连接到充电器时,你可以将应用的刷新频率开到最大,如果设备没有在充电,那么降低更新频率可以延长电池的使命时间。检查当前的充电状态首先我们需要检查当前的充电状态。BatteryManager会将电池信息以及充电信息通过粘性Intent将其广播。因为是粘性Intent,所以不需要注册BroadcastReceiver,只需要在调用registerReceiver()时传一个null就可以,当前的电池状态由该方法直接返回。你也可以在这里传递一个BroadcastReceiver对象,但是我们接下来的处理方式并不是在其中做的,所以这并不是必须的。IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);Intent batteryStatus = context.registerReceiver(null, ifilter);
[*]1
[*]2

[*]1
[*]2
如果设备当前处于充电状态,那么可以获得当前的充电状态,无论它是通过USB还是通过AC适配器充电的。// Are we charging / charged?int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||                     status == BatteryManager.BATTERY_STATUS_FULL;// How are we charging?int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
[*]7
[*]8

[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
[*]7
[*]8
通常的做法是:应当是在连接到AC电源适配器时,将后台的更新频率加到最大,如果当前处于USB状态,这个频率应当适当降低,如果断开充电,则应当进一步降低。


熊猫儿 发表于 2016-9-22 15:48

监测充电状态的变化设备的充电状态很容易随着充电器的插入、拔出而发生变化。所以随着充电状态的变化应当相应的调整应用的刷新频率。当设备插上充电器或是拔出充电器时,BatteryManager都会广播一个Action,所以应当注册一个BroadcastReceiver用来监听这些事件。在清单文件中需要定义ACTION_POWER_CONNECTED及ACTION_POWER_DISCONNECTED的意图过滤器。<receiver android:name=".PowerConnectionReceiver"><intent-filter>    <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/></intent-filter></receiver>
[*]1
[*]2
[*]3
[*]4
[*]5
[*]6

[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
在该BroadcastReceiver内,你可以获取当前的充电状态:public class PowerConnectionReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {         int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);      boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||                            status == BatteryManager.BATTERY_STATUS_FULL;      int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);      boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;      boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;    }}
[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
[*]7
[*]8
[*]9
[*]10
[*]11
[*]12

[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
[*]7
[*]8
[*]9
[*]10
[*]11
[*]12
检查电池的剩余电量在一些情况下还需要检查设备的剩余电量。当电量较低时可能需要降低应用的后台服务频率。你可以通过以下方式获得设备的剩余电量:int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);float batteryPct = level / (float)scale;
[*]1
[*]2
[*]3

[*]1
[*]2
[*]3
监测电量的重要变化应用不能一直连续不断的监听电池的状态。通常来说,一直不断的监听电池电量会使监听电池的任务大于应用的实际任务,所以最好是只监听一些比较重要的变更事件。下面的清单文件摘自一段广播接收器内。该广播接收器会在电池的电量很低时或者是在电量恢复到安全水平时被触发。它监听了两个事件:ACTION_BATTERY_LOW及ACTION_BATTERY_OKAY.<receiver android:name=".BatteryLevelReceiver"><intent-filter><action android:name="android.intent.action.ACTION_BATTERY_LOW"/><action android:name="android.intent.action.ACTION_BATTERY_OKAY"/></intent-filter></receiver>
[*]1
[*]2
[*]3
[*]4
[*]5
[*]6

[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
通常情况下,在电量很低时要关闭所有的后台更新。加载在使用APP之前,手机关机了,那么应用的数据是否是最新的就没那么重要了。在很多情况下,手机充电时是被放在一个固定的位置上的。下节课我们将会学习如何检查设备的放置环境以及如何监测设备的放置状态。

熊猫儿 发表于 2016-9-22 15:48

Android官方开发文档Training系列课程中文版:电池续航时间优化之检查与监测坞的状态与类型
标签: android优化坞状态监听
2016-09-22 08:55 180人阅读 评论(0) 收藏 举报

http://static.blog.csdn.net/images/category_icon.jpg 分类:
翻译(103) http://static.blog.csdn.net/images/arrow_triangle%20_down.jpg


目录(?)[+]

原文地址:http://android.xsoftlab.net/training/monitoring-device-state/docking-monitoring.htmlAndroid设备可以被放置在若干种不同的扩展坞中。这些扩展坞包括汽车坞与家庭坞以及数字与模拟坞。其中坞的状态与充电状态非常相近,因为这些坞也提供了充电功能。译者提示:这里说的坞是一种扩展设备,Android中比较少见,而苹果设备比较常见。我们常见的苹果设备的扩展坞就是苹果体验店所见的各种小型音响设备。APP在何种坞中的运行频率取决于APP自身。你可以在设备处于APP坞时提高运动类APP的更新频率,或者设备处于汽车坞时完全关闭更新,或者也可以在APP在更新交通信息时将更新频率提高至最大。这些坞的状态也同样通过粘性Intent广播获取,它可以用来查询是否被放置在了某个坞中,如果被放置了,那么可以查询是何种类型的坞。检查当前坞的状态当前坞的状态被放置在粘性Intent中。因为它是粘性的,所以不需要注册广播接收器。你可以直接通过registerReceiver()方法直接获得这个Intent。IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);Intent dockStatus = context.registerReceiver(null, ifilter);
[*]1
[*]2

[*]1
[*]2
接下来则通过该Intent获取当前坞的状态:int dockState = battery.getIntExtra(EXTRA_DOCK_STATE, -1);boolean isDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
[*]1
[*]2

[*]1
[*]2
检查当前坞的类型如果设备被放置在坞中,那么它可能处于以下类型中:
- Car
- Desk
- 低端桌面坞(模拟)
- 高端桌面坞(数字)注意后面这两种类型只在Android 11中介绍到,所以只需要统一检查后面这三种类型就可以:boolean isCar = dockState == EXTRA_DOCK_STATE_CAR;boolean isDesk = dockState == EXTRA_DOCK_STATE_DESK ||                  dockState == EXTRA_DOCK_STATE_LE_DESK ||               dockState == EXTRA_DOCK_STATE_HE_DESK;
[*]1
[*]2
[*]3
[*]4

[*]1
[*]2
[*]3
[*]4
监测坞的状态以及类型的变化当设备被放置或移除坞时,系统会广播一个ACTION_DOCK_EVENT。为了可以监测坞状态的变化,只需要在清单文件中注册一个广播接收器就可以:<action android:name="android.intent.action.ACTION_DOCK_EVENT"/>
[*]1
http://static.blog.csdn.net/images/save_snippets_01.png

[*]1
你可以在对应的广播接收器内获取坞的类型以及状态。


熊猫儿 发表于 2016-9-22 15:51

Android官方开发文档Training系列课程中文版:布局性能优化之ListView的优化
标签: androidui性能优化布局优化ListView优化
2016-09-20 08:59 268人阅读 评论(0) 收藏 举报

http://static.blog.csdn.net/images/category_icon.jpg 分类:
翻译(103) http://static.blog.csdn.net/images/arrow_triangle%20_down.jpg


目录(?)[+]

原文地址:http://android.xsoftlab.net/training/improving-layouts/smooth-scrolling.html想要让ListView滑动流畅的关键所在是减轻主线程的负担。要确保任何的磁盘访问、网络访问、或者SQL访问都是在单独的线程中执行的。如果要测试APP的状态,可以开启StrictMode。使用后台线程使用工作线程可以使UI线程将所有的注意力都集中在UI的绘制上。在很多情况下,使用AsyncTask所提供的功能就可以在工作线程中处理耗时任务。AsyncTask会自动的将execute()发起的请求排队,并依次执行。这意味着你不要自己创建线程池。在下面的示例代码中,AsyncTask被用来加载一张图像,并在加载结束后自动的将其渲染到UI上。它还在图像加载时展示了一个旋转的进度条。// Using an AsyncTask to load the slow images in a background threadnew AsyncTask<ViewHolder, Void, Bitmap>() {    private ViewHolder v;    @Override    protected Bitmap doInBackground(ViewHolder... params) {      v = params[0];      return mFakeImageLoader.getImage();    }    @Override    protected void onPostExecute(Bitmap result) {      super.onPostExecute(result);      if (v.position == position) {            // If this item hasn't been recycled already, hide the            // progress and set and show the image            v.progress.setVisibility(View.GONE);            v.icon.setVisibility(View.VISIBLE);            v.icon.setImageBitmap(result);      }    }}.execute(holder);
[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
[*]7
[*]8
[*]9
[*]10
[*]11
[*]12
[*]13
[*]14
[*]15
[*]16
[*]17
[*]18
[*]19
[*]20

[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
[*]7
[*]8
[*]9
[*]10
[*]11
[*]12
[*]13
[*]14
[*]15
[*]16
[*]17
[*]18
[*]19
[*]20
从Android 3.0开始,AsyncTask提供了一项新特性:可以将任务运行在多核处理器上。你可以使用executeOnExecutor()方法发起执行请求,这样多个请求就可以同时进行,同时进行的任务数量取决于CPU的核心数量。使用View Holder持有View对象在滑动ListView时,代码可能会频繁的调用findViewById(),这会降低性能。就算是Adapter将已经加载过的View返回,但是在复用时还是需要去查询这些View来更新它们。杜绝重复使用findViewById()的方法就是使用”View Holder”设计模式。ViewHolder对象将每个View组件存储于布局容器的tag属性内,所以你可以快速访问它们而不需要每次都去查询。首先,你需要创建一个类来持有已加载的View:static class ViewHolder {TextView text;TextView timestamp;ImageView icon;ProgressBar progress;int position;}然后对ViewHolder的成员属性赋值,然后将其存放在布局容器内:ViewHolder holder = new ViewHolder();holder.icon = (ImageView) convertView.findViewById(R.id.listitem_image);holder.text = (TextView) convertView.findViewById(R.id.listitem_text);holder.timestamp = (TextView) convertView.findViewById(R.id.listitem_timestamp);holder.progress = (ProgressBar) convertView.findViewById(R.id.progress_spinner);convertView.setTag(holder);
[*]1
[*]2
[*]3
[*]4
[*]5
[*]6

[*]1
[*]2
[*]3
[*]4
[*]5
[*]6
那么现在就可以很方便的对这些View组件进行访问,而不再需要对它们单独进行查询,如此便可以节省出宝贵的CPU资源。


页: 24 25 26 27 28 29 30 31 32 33 [34] 35 36 37 38 39 40 41 42 43
查看完整版本: 【Android的一些重要知识6。。。。】