經過一段時間的學習,閱讀完了《App研發錄》,此書同以前閱讀的其餘書,如 xx入門,xx提升不一樣,不是針對具體知識點、api的講解,而是做者多年的工做經驗及工做之中遇到的問題進行彙總分享,特別是第二部分crash異常收集、分析處理,做者花了大篇幅對項目中遇到的crash問題進行分析、歸類,重現,有這樣一個異常庫,對快速定位緣由解決bug是頗有幫助的。接下來就闡述一下本人的一些學習心得。html
(一)App框架設計與重構java
1.1 此部分主要講述了項目開發中遇到的基礎技術問題及經典場景,項目重構和命名規範兩章,其實主要講述了代碼規範、風格一致,如項目包結構,BaseActivity,adapter模板設計,命名規範及編碼規範,代碼規範,風格規範一致有不少好處,如能夠減小新人的學習成本、加強代碼複用,快速bug定位、項目複製、多項目切換等,在項目中還能夠結合mvc、mvp及設計模式進行設計及重構。android
1.2 網絡設計講述了怎樣封裝一個公共的網絡請求框架,講解了封裝技巧,公共方法的提取,線程池,對比了asyncTask的優缺點,其中有個知識點,我的感受項目中可能會用到,當咱們定義一個公共的 interface 回調,如 interface CallBack{git
void showCollectResult();github
void showSubscribResult();設計模式
}api
A activity須要實現 CallBack, 只須要 showCollectResult,B activity 只須要showSubscribResult,緩存
直接實現 CallBack,就會出現一些空方法,此時咱們可經過以下方式避免服務器
abstract class AdapterCallBack implements CallBack
A implements AdapterCallBack{ void showCollectResult(){ dosomething; } } B implements AdapterCallBack{ void showSubscribResult(){ dosomething; } }
網絡請求框架目前有不少開源框架可供參考網絡
1 volley 使用方法參考http://blog.csdn.net/sinyu890807/article/details/17482095
2 Retrofit 使用方法參考 http://blog.csdn.net/carson_ho/article/details/73732076
3 OkHttp 使用方法參考:https://github.com/hongyangAndroid/okhttp-utils
1.3 app圖片緩存講述了 ImageLoader的原理、使用及改造,爲減小GC次數,在頁面onDestroy 時手動清空ImageLoader緩存。
除ImageLoader外,Android 圖片緩存框架還有 Picasso,Glide,Fresco,各原理及性能對比可參考:http://www.cnblogs.com/linghu-java/p/5741358.html
1.4 網絡流量優化
通訊層面上 :
1 、當api請求或者返回數據比較大時,考慮採用gzip壓縮
二、減小api請求頻率,網絡請求大部分時間都消耗在創建網絡鏈接及數據傳輸上,所以能一次請求接口獲取數據的,就不要兩次, 但這種訴求常常和接口開發人員的設計思想相沖突,他們常常會說一個接口只作一件事,一個功能有時讓客戶端調兩次,甚至三次接口。
三、創建取消網絡請求機制,頁面跳轉前,要將不用的網絡請求中止掉,以避免形成網絡阻塞及資源浪費。
圖片策略優化:
1 根據ImageView大小下載圖片,經過額外在url 上添加width,height參數,如http://www.aaa.com/a.png?width=100&height=50從服務器獲取相應尺寸圖片。
2 根據當前網絡環境選擇不一樣圖片質量
1.5 APP和h5交互一章中,印象最深的是 h5跳轉app頁面分發器一節,以前的實現方式是:
h5端:
<a onclick="baobao.gotoAnyWhere('gotoMovieDetail:movieId=(int)12')"gotoAnyWher </a>
android端代碼
public void gotoAnyWhere(String url){ if(url!=null){ if(url.startsWith("gotoMoviesDetail:")){ String starMoveId=url.substring(24); int movieId=Integer.valueOf(strMovieId); Intent intent=new Intent(MainActivity.this,MovieDetailActivity.class); intent.putExtra("movieId",movieId); startActivity(intent); }else if (url.startsWith("gotoNewsList:")){ //as above }else if (url.startsWith("gotoUrl:")){ String strUrl=url.substring(8); wvads.loadUrl(strUrl); }else if (url.startsWith("gotoPersonCenter:")){ Intent it=new Intent(MainActivity.this,PersonCenterActivity.class); startActivity(it); } } }
h5端每增長一個類型,app就要添加一else if,並且要發版解決,書中在頁面分發器章節介紹瞭解決方案,改造以下:
h5端:
<a onclick="baobao.gotoAnyWhere('com.example.youngheart.MovieDetailActivity: movieId=(int)12')"gotoAnyWher </a>
咱們能夠看到協議內容分兩段:第一段是要跳轉到的Activity名稱及包路徑,第二段是傳遞的參數,以key-value的形式組裝。
app端:
解析出第一段,經過Class.fromName(pageName) 反射出Activity 對象, 解析第二段,用於跳轉到目標頁面傳值,具體實現以下
public void gotoAnyWhere(String url) { if (url != null) { if (url.startsWith("gotoMovieDetail:")) { String strMovieId = url.substring(24); int movieId = Integer.valueOf(strMovieId); Intent intent = new Intent(this, MovieDetailActivity.class); intent.putExtra("movieId", movieId); startActivity(intent); } else if (url.startsWith("gotoNewsList:")) { // as above } else if (url.startsWith("gotoPersonCenter")) { Intent intent = new Intent(this, PersonCenterActivity.class); startActivity(intent); } } } private String getAndroidPageName(String key) { String pageName = null; int pos = key.indexOf(","); if (pos == -1) { pageName = key; } else { pageName = key.substring(0, pos); } return pageName; } public void gotoAnyWhere2(String url) { if (url == null) return; String pageName = getAndroidPageName(url); if (pageName == null || pageName.trim() == "") return; Intent intent = new Intent(); int pos = url.indexOf(":"); if (pos > 0) { String strParams = url.substring(pos); String[] pairs = strParams.split("&"); for (String strKeyAndValue : pairs) { String[] arr = strKeyAndValue.split("="); String key = arr[0]; String value = arr[1]; if (value.startsWith("(int)")) { intent.putExtra(key, Integer.valueOf(value.substring(5))); } else if (value.startsWith("(Double)")) { intent.putExtra(key, Double.valueOf(value.substring(8))); } else { intent.putExtra(key, value); } } } try { intent.setClass(this, Class.forName(pageName)); } catch (ClassNotFoundException e) { e.printStackTrace(); } startActivity(intent); } }
這樣h5只要知道 須要跳轉類的包路徑及跳轉參數便可實現跳轉,不需app端作改動,相應的侷限是隻有當頁面傳遞參數是簡單類型才適應。