編輯:關於Android編程
看這本書的時候,總感覺怪怪的。
因為在地鐵上看完的,作者書中基本都是他自己工作中遇到的問題和坑,雖說這樣會讓人感覺找到了解決方案,可以再進行深入的研究,可是某些地方介紹的有點片面,僅僅是引用部分博客就以偏概全了。還有可能是涉及的內容大部分都是我自己已經踩過的坑,所以覺得學到的東西不太多。
再說說值得一看的地方吧,首先也如前面提到的,書中內容基本都是作者工作之談,所以有很實用的內容,推薦閱讀章節:
個人認為這是本書的精華,很少看到有人願意這樣詳盡的介紹自己的“機密”經驗,感謝作者的無私分享。
介紹很詳細,網上都是非常瑣碎的介紹,推薦新人看看這部分,尤其是ProGuard,雖然現在第三方已經給出了完善的解決方案,幫我們做了這部分事情,不過了解最基本的原理才能學得更透徹。
這部分是時間的積累才能收獲的,提前學習了解以後我們必須經歷的路沒什麼不好的。測試部分相關的部分是很少有書籍能夠提及,值得看看。
將混亂類文件按照自己的職責劃分並存放在相關目錄下,如:
com.xxx.xxx. | -- activity | -- utils | -- adapter | -- entity | -- ui | -- interface | -- listener
有了清晰的目錄結構,尋找各功能的類文件方便得多,而且便於團隊間多人協作開發。誰也不願意找個相關類全路徑的到處搜,干這種事的人不被同事罵死才怪。
該部分主要說明對Activity一個簡單的封裝,Activity都繼承一個基類BaseActivity,其中BaseActivity將常用的操作封裝起來當作一種規范,如onCreate() —> initViews() —> loadData() 。事實上現在很多項目都是使用的各種框架庫,如ButterKnife、EventBus,Otto等,所以這種較老的方式或許慢慢少了起來,可主要的抽象思想都應該有嘛。
這個地方個人不是太贊同作者推薦的View.setOnClickListener(new OnClickListener() { Override onclick() { … } }這種方式來進行事件注冊。確實switch … case … 有點“擾亂”面向對象的風格,可想想一個代碼較多的Activity中,你要迅速定位某個onClick事件使用後者有多麼方便,並且onClick的事件都能統一管理,無需再擔心某個地方漏了一個onClIck。
通過固定的類庫達到我們想要的目的,常用類庫Gson、FastJson等,不用過多贅述。其中有一點值得一看,就是關於後面提到的Crash事件處理,其實在傳遞Intent的時候也可進行避免某些Crash的操作,如長時間的閒置導致內存回收時將關鍵的變量給回收了,當前跳轉頁面的時候是需要那個變量的,而傳遞變量的同時可以進行檢查判斷是否為null來減少跳轉後的NPE(NullPointerException) Crash。這些都是我個人的經驗。
這裡書中提到的工具都過時了吧(絕對沒有嘲諷的意思,能分享的人都是偉大的)。因為拿來主義的我一般用的都是Android Studio中的插件GsonFormat ,不支持Eclipse!
第二章主講網絡框架的經驗,涉及到的有對網絡底層框架的封裝,作者遇到的坑和某些網絡類庫的使用優化建議等。對於網絡請求這類操作,當前衍生的各種相關類庫功能十分強大,而且基本都封裝好了,在使用方便的同時可不要忽略底層的概念,一門技術要做到:知其然,知其所以然。這樣無論遇到什麼問題都能有一顆冷靜沉著的心去面對和挑戰。
家家使用的工具都不同,但常用的也就那麼幾個:
目前公司項目用的就是這一個,還是我當時建項以來綜合對比後挑的一個,那時候的OkHttp還沒有現在這樣火好不好。所以我們也當然對Volley進行了簡單的封裝,這裡不說文章,先談談我對Volley封裝的看法吧。
打開Volley的目錄結構,在toolbox中可以看到網絡請求類常用的有這麼幾個
接口類RequestCallbackable.java,用於進行請求結果的回調。
public interface RequestCallbackable{ void onSuccess(T model); void onFailure(T msg); }
封裝方法中,由於請求分為Get和Post兩種,並且很可能Post會含有Body,因此需要二次封裝,下面是基於StringRequest的一個完整封裝類
public class HttpUtils { private static final int VOLLEY_REQUEST_TIMEOUT_MS = 20 * 1000; private static final int VOLLEY_REQUEST_RETRY_TIMES = 0; /** * Get請求 * * @param strKVs 這裡的strKVs代表Get的參數字段, * 如果沒有參數或者body則不填, * 格式為: * "user[name]", username, * "user[password]", userPassword, * "user[id]", userId */ public static void doVolleyGet(String getUrl, final RequestCallbackable requestResult, final String... strKVs) { doVolleyRequest(Request.Method.GET, getUrl, requestResult, strKVs); } /** * Post請求 * * @param strKVs 這裡的strKVs代表Post的參數、body字段, * 如果沒有參數或者body則不填, * 格式為: * "user[name]", username, * "user[password]", userPassword, * "user[id]", userId */ public static void doVolleyPost(String getUrl, final RequestCallbackable requestResult, final String... strKVs) { doVolleyRequest(Request.Method.POST, getUrl, requestResult, strKVs); } /** * RequestManager需要在Application初始化 * 關於RequestManager的使用詳情請自行谷歌 */ private static void doVolleyRequest(int requestMethod, String requestUrl, final RequestCallbackable requestCallbackable, final String... paramsStrKVs) { if (TextUtils.isEmpty(requestUrl)) return; // 使用的是StringRequest StringRequest requestPost = new StringRequest(requestMethod, requestUrl, new Response.Listener() { @Override public void onResponse(String resultStr) { if (requestCallbackable != null) { requestCallbackable.onSuccess(resultStr); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { if (requestCallbackable != null) { requestCallbackable.onFailure(volleyError); } } }) { @Override public Map getHeaders() throws AuthFailureError { Map params = new HashMap (); params.put("Authentication", "here put your Token"); return params; } @Override protected Map getParams() throws AuthFailureError { HashMap map = new HashMap (); if (paramsStrKVs != null && (paramsStrKVs.length % 2 == 0)) { for (int i = 0; i < paramsStrKVs.length; i += 2) { map.put(paramsStrKVs[i], paramsStrKVs[i + 1]); } } return map; } @Override public byte[] getBody() throws AuthFailureError { String httpPostBody = ""; if (paramsStrKVs != null && (paramsStrKVs.length % 2 == 0)) { for (int i = 0; i < paramsStrKVs.length; i += 2) { httpPostBody += (i == 0 ? "" : "&") + paramsStrKVs[i] + "=" + paramsStrKVs[i + 1]; } } return httpPostBody.getBytes(); } }; // 設置volley的請求超時時間,重試次數 requestPost.setRetryPolicy(new DefaultRetryPolicy(VOLLEY_REQUEST_TIMEOUT_MS, VOLLEY_REQUEST_RETRY_TIMES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); // queueTag 用於調用cancelAll(queueTag)取消加入隊列的請求 requestPost.setTag(RequestManager.getRequestQueue.getQueueTag()); RequestManager.getRequestQueue().add(requestPost); } }
HttpUtils.doVolleyGet("your request url", new RequestCallbackable() { @Override public void onSuccess(Object model) { // request onSuccess callback // this callback on UI main thread } @Override public void onFailure(Object msg) { // request onFailure callback // this callback on UI main thread } }, "user[name]", username, "user[password]", userPassword, "user[id]", userId); }
比起上面的StringRequest要簡單,封裝方式差不多,也就不多說了。ImageRequest的簡單使用方式:
ImageRequest imagerequest = new ImageRequest("your image url", new Response.Listener() { @Override public void onResponse(Bitmap bitmap) { // callback on UI main thread } }, maxWidth, maxHeight, ImageView.ScaleType.CENTER, Bitmap.Config.ARGB_8888, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { // error callback on UI main thread } });
這可是個重頭戲,通過NetworkImageView.setImageUrl()來進行ImageView的圖片下載,結合LRU進行圖片的二級緩存(內存、磁盤),需要注意的是,Volley的請求方式都是通過RequestQueue這個隊列進行網絡訪問的,也就是說通常全局只需要使用同一個Queue,那麼RequestManager的目的就是為了實例化Queue以保證方法對其正常的調用。
NetworkImageView的使用方式:
NetworkImageView imageview = null; imageview = (ImageView) findViewById(R.id.your_image_view_id); imageview.setImageUrl("your image url", ImageCacheManager.getInstance().getImageLoader());
說到這裡,慢慢引申出了ImageCacheManager這個神奇的Manager類,實際上ImageCacheManager也是一個封裝類,將Volley的ImageLoader包裝起來,實現了二級緩存策略。
Json請求方式和StringRequest大同小異,只不過回調的對象是JSONObject罷了,不介紹了。相關請求類如下:
最近由於項目太大了,導致編譯通不過(Android對一個應用中的方法個數貌似有限制),所以一直琢磨著能否將某些模塊的APK不用安裝,動態加載,通過在網上查找
1.簡介 最近做一個項目,主要通過usb完成pc與Android端的數據傳輸。但是根據api提供的無法監聽usb的插拔,有解釋為不同版本會存在BUG。本
最近做一個效果:在手機設置裡面“關於手機”裡面添加一項來顯示當前手機cpu使用率的曲線!其實現效果如下圖所示: 上圖關於手機的第一項就是我要實現的效果!今天來講講這個曲
1、在res文件夾下新建drawable文件夾。 2、新建一個xml文件。 3、采用drawable來定義資源。 st