1. 程式人生 > >《APP研發錄》筆記

《APP研發錄》筆記

最近兩天在專案不忙的時候讀了《APP研發錄》,雖然是看的PDF版,但還是受益匪淺,由於時間關係,還沒有對其中的問題進行demo驗證,

僅對一些重要內容做了筆記,現將筆記貼出來與大家共同學習,如果有問題,大家可以留言或私信。在今後的額閱讀中,再對筆記的內容進行補充說明。

面試考察的幾方面: 1.Activity的生命週期 2.Activity的4種啟動方式及使用場合 3.做過的專案,Activity是否有基類,如果有,封裝了哪些公用的邏輯 4.事件的各種使用方式及優缺點 5.與HTML5頁面的相互呼叫 6、UI執行緒的阻塞與解決方案(Runnable和Handler) 7. 採用什麼姿勢呼叫MobileAPI並解析返回的資料 8。怎樣做列表的分頁和重新整理 9.登入的實現,包括從哪來,到哪去的頁面跳轉機制,記住密碼的邏輯設計。 10.效能調優,包括Layout調優,Activity中如何使用Const常量,時間換空間策略, ViewHolder、圖集的優化策略、資料快取的圖片快取,等等。 11.全域性變數過多怎麼辦 12.寫過UT沒 13.是否做過自動打包,Ant、Maven或Gradle任意一種都可以。 14.如何檢查記憶體洩露、如何優化記憶體、多執行緒、自動打包、框架設計、版本管理等。 Android應用開發所需要的技能點: 1.Activity相關,涉及LaunchMode、onSaveInstanceState、生命週期等。 2.Fragment相關,《Creating Dynamic UI with Android Fragments》 3.序列化技術。Parcelable和Serializable。前者基於Service,後者基於Bundle 4.ImageLoader的原理和使用。 5.fastJson或Gson的使用。 6.多執行緒相關。包括Handler、Looper、ExecutorService 7.Adapter和ListView。 8.使用者Cookie設計。登入機制。 9.網路請求封裝。 10.Android與H5互動。 11.程式碼混淆。 12.Android打包機制。 13.線上Crash分析並修復。 14.記憶體洩露,記憶體優化,記憶體洩露場景,MAT工具。 15.除錯工具。DDMS等 16。Monkey機制 17.單元測試,Junit。 18.Git的高階功能。包括Stage、R額八色、Revert、Stash、Cherry Pick和Sub Module等。svn。 19.外掛化變成。DexClassLoader。 20.設計模式。工廠、生成器、介面卡、代理、策略模式等。
第四章 編碼規範 1.activity中定義新生命週期在onCreate中建立三個方法 initVariables initViews loadData 2.activity中不要巢狀內部類 3.實體不要在不同模組中共享,可以在同一模組的不同頁面中共享 4.為節省記憶體,儘量使用ArrayList<自定義實體>,而不是HashMap 5.圖片的處理統一使用第三方元件載入 6.簡單的配置資訊,設定頁面的各種開關,儲存到SharedPreferences中。複雜的物件,比如User類, 城市基礎資料,需要存在本地檔案中。 7.儘量使用ApplicationContext替代Context,否則會引起記憶體洩露,但也不是任何地方都可以替代。 8.資料型別轉換一定要進行校驗。 第五章 Crash異常收集與統計 第六章 Crash異常分析 CrashHandler類 繼承自UncaughtExceptionHandler, /** * UncaughtException處理類,當程式發生Uncaught異常的時候,由該類來接管程式,並記錄傳送錯誤報告。 * 需要在Application中註冊,為了要再程式啟動器就監控整個程式。 */ public class CrashHandler implements UncaughtExceptionHandler{ public static final String TAG = "CrashHandler"; public static final String APP_CACHE_PATH = Environment.getExternalStorageDirectory()/getPath()+"/YoungHeart/crash"; /** * 當UncaughtException發生時會轉入函式來處理 */ @Override public void uncaughtException(Thread thread,Throwable ex){ if(!handleException(ex) && mDefaultHandler !=null){ //如果使用者沒有處理則讓系統預設的異常處理器來處理 mDefaultHandler. uncaughtException(thread,ex); }else{ try{ Thread.sleep(3000); }catch(){ } //退出程式 android.os.Process.killProcess(android.os.Process.myPid); System.exit(1); } } handlerException 方法主要做三件事情,1發錯誤日誌到伺服器2給使用者友好提示3記錄到sd卡
1.對Crash進行歸納,每類Crash發生的次數、涉及的機型、涉及的Android系統版本 2.對Crash產生的原因分析 a。Android碎片化 b. MobileAPI返回了髒資料。 c。混淆時沒有Keep要使用的類或方法,找不到類或方法了。 3.每天跑Monkey的包存到測試機上即可。有專人去排查Monkey包的問題。 4.Java語法相關的異常 1)空指標 a。方法需要對傳入的引數判空後再使用。 b。呼叫外部介面,確保返回值中不為空,需要確保執行該介面不會丟擲其他異常導致程式退出。 c。APP中過多使用全域性變數。 2)角標越界OutOfBoundsException a。程式不嚴謹 b。在遍歷一個數組/集合時,需要預判陣列/集合是否為空,長度是否大於0. c。在使用陣列/集合中的元素時,要預判陣列/集合長度是否有這麼長。 d。subString(start,end)要判斷字串的長度 e。listview的長度判斷 3)試圖呼叫空物件方法 Attempt to invoke virtual method on a null object reference 物件沒有例項化,或者將例項化的語句寫在了if-else語句中 在activityA中呼叫activityB中的方法,在B中建立了一個static變數,當這個static變數被回收。就會出現這個問題。 推送,跳過首頁直接進入二級或三級,需要使用首頁某個物件時,物件為空 4)型別轉換異常 設定轉換失敗的預設值,防止得到空值。 5)數字轉換錯誤 NumberFormatException 字元型轉換為數字失敗時, String abc = “123xxx45”; int result = Integer.parseInt(abc); 如果轉換失敗,要設定預設值。 6)宣告陣列時長度為-1 NegativeArraySizeException String[] arg1 = new String[args.length - 1]; 當args陣列中沒有元素時,就會出現問題。 7)遍歷集合同事刪除其中元素 ConcurrentModificationException 多個執行緒同時刪除同一個集合中的元素。 8)比較器使用不當 Comparison method violates its general contrat! 9)除數為0 ArithmeticException:divide by zero 多發生在第三方控制元件,如GifView 10)隨便用asList
11)有類找不到 ClassNotFoundException 和 NoClassDefFoundError 5.Activity相關異常 1)找不到activity 2)不能例項化Activity RuntimeException 沒有在AndroidManifest清單中註冊該activity 建立activity後修改了包名或類名但配置清單沒有修改 系統處於異常狀態 3)找不到Service RuntimeException 4)不能啟動BroadcastReceiver 使用Activity以外的content來startActivity。比如BroadcastReceiver,必須用 Intent.FLAG_ACTIVITY_NEW_TASK 5)startActivityForResult不能回傳 6)Fragment Fragment not attached to Activity Fragment在還沒有Attach到Activity時,呼叫了諸如getResource() 的方法 解決方案需要在獲取資源前用isAdded方法進行判斷 isAdded方法是Android系統提供的,只有在Fragment被新增到所屬的Activity中才會返回true。 7.序列化相關異常 實體物件不支援序列化 序列化時未指定ClassLoader 反序列化時找不到類,被ProGuard混淆導致的崩潰 反序列化時找不到類,傳入畸形資料 反序列化時出錯,Could not read…… 8.列表相關異常 adapter資料來源變化沒有通知listview listview滾動時點選重新整理按鈕崩潰(滾動時將重新整理設為不可用) absListview 的obtainView返回空指標 adapter資料來源變化但沒有呼叫notifyDataSetChanged 9.窗體相關異常 視窗控制代碼洩露 View not attached to window manager 窗體在不恰當的時候獲取焦點 token null is not for an application 新增窗體失敗 AlertDialog.resolveDialogTheme The specified child already has a parent 子執行緒不能修改UI 不能在子執行緒操作AlterDialog和Toast 10.資源相關異常 Resources$NotFoundException StackOverflowError 檢視巢狀太深,activity退出不完全,用system.exit(0) UnsatisfiedLinkError so檔案 11.系統碎片化相關異常 NoSuchMethodError 2.3版本的Bundle中getString() RemoteViews (AppWidget和Notification) SecurityException之一Intent中圖片太大,超過1M不用Intent傳遞 SecurityException之二動態載入其他apk的activity SecurityException之三 缺少許可權 不同版本需要預判許可權 view的getDrawingCache()返回null,背景圖太大,超過螢幕大小 DeadObjectException 產生這樣的錯誤以便重啟裝置 Android 2.1不支援SSL ViewFlipper控制元件切換橫豎屏時出現問題,解決方案重寫onDetachedFromWindow( 12.SQLite相關異常 No transaction is active 逐條插入大量資料時發生的,解決辦法一次性插入,通過事物成功進行提交 setTransactionSuccessful() 忘記關閉Cursor 資料庫被鎖定,當不同執行緒中建立多個數據庫連結時發生 想要開啟已經關閉的物件 檔案加密了或無資料庫 磁碟讀寫錯誤 13.不明覺厲的異常 記憶體溢位 TimeoutException GC回收異常,重寫finalize方法不要超時操作 Json解析異常 LayoutInfiater.form().infiate()使用不當 Monkey點選過快導致的崩潰 取決於Monkey點選的間隔時間 圖片縮放很多倍 第七章 ProGuard

ProGuard一共包括4個功能

  • 壓縮:偵測並移除程式碼中無用的類、欄位、方法和特性
  • 優化:對位元組碼進行優化,移除無用的指令
  • 混淆:使用a、b、c、d這樣簡短而無意義的名稱,對類、欄位和方法進行重新命名
  • 預檢:在Java平臺上對處理後的程式碼進行預檢
  • 基本混淆

    • 1.基本指令

      # 程式碼混淆壓縮比,在0-7之間,預設為5,一般不需要改
      -optimizationpasses 5
      
      # 混淆時不使用大小寫混合,混淆後的類名為小寫
      -dontusemixedcaseclassnames
      
      # 指定不去忽略非公共的庫的類
      -dontskipnonpubliclibraryclassmembers
      
      # 不做預校驗,preverify是proguard的4個步驟之一
      # Android不需要preverify,去掉這一步可加快混淆速度
      -dontpreverify
      
      # 有了verbose這句話,混淆後就會生成對映檔案
      # 包含有類名->混淆後類名的對映關係
      # 然後使用printmapping指定對映檔案的名稱
      -verbose
      -printmapping proguardMapping.txt
      
      # 指定混淆時採用的演算法,後面的引數是一個過濾器
      # 這個過濾器是谷歌推薦的演算法,一般不改變
      -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
      
      # 保護程式碼中的Annotation不被混淆
      # 這在JSON實體對映時非常重要,比如fastJson
      -keepattributes *Annotation*
      
      # 避免混淆泛型
      # 這在JSON實體對映中非常重要,比如fastJSON
      -keepattributes Signature
      
      //丟擲異常時保留程式碼行號
      -keepattributes SourceFile,LineNumberTable
      
      -dontskipnonpubliclibraryclasses用於告訴ProGuard,不要跳過對非公開類的處理。預設情況下是跳過的,
      因為程式中不會引用它們,有些情況下人們編寫的程式碼與類庫中的類在同一個包下,並且對包中內容加以引用,此時需要加入此條宣告。
      
      對於-dontusemixedcaseclassnames,Windows使用者必須指定,因為Windows對檔名大小寫不敏感,可能對導致class檔案相互覆蓋
      
    • 2.需要保留的東西

      # 保留所有的本地native方法不被混淆
      -keepclasseswithmembernames class * {
          native <methods>;
      }
      
      # 保留繼承自Activity、Application這些類的子類
      # 因為這些子類都有可能被外部呼叫
      -keep public class * extends android.app.Activity
      -keep public class * extends android.app.Application
      -keep public class * extends android.app.Service
      -keep public class * extends android.content.BroadcastReceiver
      -keep public class * extends android.content.ContentProvider
      -keep public class * extends android.app.backup.BackupAgentHelper
      -keep public class * extends android.preference.Preference
      -keep public class * extends android.view.View
      -keep public class com.android.vending.licensing.ILicensingService
      
      # 如果有引用android-support-v4.jar包,可以新增下面這行
      -keep public class com.tuniu.app.ui.fragment.** {*;}
      
      # 保留在Activity中的方法引數是view的方法
      # 從而我們在layout裡面編寫onClick就不會被影響
      -keepclassmembers class * extends android.app.Activity {
          public void *(android.view.View);
      }
      
      # 列舉類不能被混淆
      -keepclassmembers enum * {
          public static **[] values();
          public static ** valueOf(java.lang.String);
      }
      
      # 保留自定義控制元件(繼承自View)不會混淆
      -keep public class * extends android.view.View{
          *** get*()
          void set*(***)
          public <init>(android.content.Context);
          public <init>(android.content.Context,android.util.AttributeSet);
          public <init>(android.content.Context,android.util.AttributeSet,int);
      }
      
      # 保留Parcelable序列化的類不被混淆
      -keep class * implements android.os.Parcelable {
          public static final android.os.Parcelable$Creator *;
      }
      
      # 保留Serializable序列化的類不被混淆
      -keepclassmembers class * implements java.io.Serializable {
          static final long serialVersionUID;
          private static final java.io.ObjectStreamField[] serialPersistentFields;
          private void writeObject(java.io.ObjectOutputStream);
          private void readObject(java.io.ObjectInputStream);
          java.lang.Object writeReplace();
          java.lang.Object readResolve(); 
      }
      
      # 對於R(資源)下的所有類及其方法,都不能被混淆
      -keep class **.R$* {
          *;
      }
      
      # 對於帶有回撥函式onXXEvent的,不能被混淆
      -keepclassmembers class * {
          void *(**On*Event);
      }
      
  • 針對App的量身定製

    1.保留實體類和成員不被混淆 
    對於實體,要保留它們的set和get方法,以及boolean型的get方法

    -keep public class com.yourpackage.entity.** {
        public void set*(***);
        public *** get*();
        public *** is*();
    }
    

    2.內嵌類 
    內嵌類經常會被混淆,結果在呼叫的時候為空就崩潰了,在混淆時必須要進行保留,如保留MainActivity的所有內嵌類:

    -keep class com.yourpackage.MainActivity$* {*;}
    

    3.對WebView的處理 
    專案中用到了WebView的複雜操作,需新增:

    -keepclassmembers class * extends android.webkit.webViewClient {
        public void *(android.webkit.WebView,java.lang.String,android.graphics.Bitmap);
        public boolean *(android.webkit.WebView,java.lang.String)
    } 
    -keepclassmembers class * extends android.webkit.webViewClient {
        public void *(android.webkit.webView,java.lang.String)
    } 
    

    4.對JavaScript的處理 
    如要保證js呼叫的原生方法不被混淆(JSInterface1是MainActivity的子類)

    -keepclassmembers class com.yourpackage.MainActivity$JSInterface1 {
        <methods>;
    }
    

    5.處理反射 
    對於Class.forName(“SomeClass”)這樣的方法,在混淆過程中,就要保留這個類的名稱不被混淆

  • 針對第三方jar包的解決方案

    1.針對android-support-v4.jar

    -libraryjars libs/android-support-v4.jar
    -dontwarn android.support.v4.**
    -keep class android.support.v4.** {*;}
    -keep interface android.support.v4.app.** {*;}
    -keep public class * extends android.support.v4.**
    -keep public class * extends android.app.Fragment
    

    2.其他的第三方jar包的解決方案 
    將第三方jar包中有關於混淆的說明新增上去

第八章 使用Ant指令碼打包:Ant IIS Antcontrib AndroidSDK JavaSDK SVN CCNET 是否支援自動打包 Daily Build 第九章 競品分析 1.嗅探器 WireShark ,也有fiddler 2、發版前要進行相容性測試,確保穩定性。app升級後,除了使用者資訊保留外,所有遺留資料刪除。 3.h5用zip包存放本地,增量更新 4.使用WebView預載入H5,但耗流量。 5.本地使用png,網上下載使用jpg

相關推薦

APP研發筆記

最近兩天在專案不忙的時候讀了《APP研發錄》,雖然是看的PDF版,但還是受益匪淺,由於時間關係,還沒有對其中的問題進行demo驗證, 僅對一些重要內容做了筆記,現將筆記貼出來與大家共同學習,如果有問題,大家可以留言或私信。在今後的額閱讀中,再對筆記的內容進行補充說明。 面

App研發》讀書筆記

這本書基本上涵蓋了移動開發中常見的關注點,之所以用關注點而不用技術點這個詞是因為這本書並沒有講到具體的技術實現,但提供了行之有效的解決方案。讀這本書的時候非常有感觸,它很多的框架設計和解決方案與我

讀書筆記App研發--資料快取設計

讀書筆記App研發錄–資料快取設計 標籤(空格分隔): 資料快取 android 優化 資料快取策略 在2G和3G網路狀態下,MobileApi訪問速度過慢,會導致不好的使用者體驗。網路端的資料接受的限制主要是傳輸速度的限制。 策略 減少Mo

App 研發、架構設計、Crash分析和競品技術分析------讀書筆記(第二章)

網路底層框架設計 1、不要自己定義網路請求框架,網路層不要使用AsyncTask 2、在網路返回資料Response的應該有一個規範的格式 { "isError":true, "errorType":1, "errorMessa

APP研發》讀書筆記(1、重構)

1、重新規劃Android專案結構 將主專案中的類分門別類的進行劃分,放置在各種包中 詳細介紹如下: activity:所有的activity放在同一個包中,細分的話,將不同模組的activity劃分到不同的包下。 adapter:將所有的介面卡放在一塊

APP研發讀書筆記:網路底層框架設計

一.統一響應實體類Response      我們一般採用JSON作為API返回結果,資料格式一般為: { "errorCode":0, "errorMessage":""; "res

架構設計之APP研發學習筆記

一、APP研發錄總結 1、重構的憂傷 如果版本發行後很短的時間內,就需要對其進行重構,除了小部分其他原因外,最重要的只能說是程式碼寫的爛,架構設計不夠靈活,導致耦合度很高。 要是非得要做重構,必須充分考慮現有資源,在非極端情況下,可

App研發 架構設計 Crash分析和App競品技術分析

第1章原始碼:  1.1 重新規劃Android專案結構  1.1.zip  1.2 為Activity定義新的生命週期 1.2.zip  1.3 統一事件程式設計模型      1.3.zip  1.5 Adapter模板   1.5.zip  1.6 型別安全轉換函式   1.6.zip  第2章原

App研發讀後總結(二)

App開發中高階技巧 2.1  crash 異常收集與統計,作者在書中介紹瞭如何收集crash 到資料庫,如何對大量crash資訊進行去重,如何生成crash報表,如何將crash 自動分配給開發人員提供一整套解決方案。 2.2 作者花了大量時間,列舉出100多個cras

App研發》面世

  古者富貴而名滅,不可勝記,唯倜儻非常之人稱焉。故西伯拘而演《周易》,屈原放逐,乃賦《離騷》。文人雅士一次次的譜寫著千古絕唱,而我亦不能免俗,也要附庸風雅,寫一部前不見古人、後不見來者的經典之作。   於是,歷時一年,嘔心瀝血,結合自身3年來從事App領域的一線實戰經驗,再輔之以從事軟體行業十餘載的奇技淫

App研發》 原始碼

第1章原始碼:  1.1 重新規劃Android專案結構  1.1.zip  1.2 為Activity定義新的生命週期 1.2.zip  1.3 統一事件程式設計模型      1.3.zip  1.5 Adapter模板   1.5.zip  1.6 型別安全轉換函式   1.6.zip 

APP研發》讀記(二)

##第三章:經典場景設計 ###圖片快取設計: 圖片快取的出現是為了避免出現OOM問題,根據需要對圖片的載入進行一些壓縮和優化,它主要完成三個任務: 圖片的快取,可以有效的減少對於流量的消耗,優化使用者體驗 圖片的壓縮載入,降低載入大圖時出現OOM的機率

App狀態維持

情況 同時 ken .com 登錄 ron nsh 認證 一段 轉載地址:http://www.jianshu.com/p/4b6b04244773 目前APP大都支持長登錄,就是用戶登錄一次後,如果用戶沒有主動註銷、清除APP緩存數據或卸載APP,就在一段時間

音樂app各部分筆記(二)

mage 可用 通知 計算屬性 進度 sta 連續 ogre nbsp 7-15播放器progress-circle圓形進度條組件實現 1.首先是引入三步 progress-circle 引入到player.vue中 然後就是 SVG技術 值得註意的事 svg

Tp5框架 關於Apptoken唯一加密算法

function Nid ati gin plog web 加密算 login set web登錄靠的是cookies裏的sessionid來區分唯一性。app登錄靠的是token唯一性。 個人針對token加密的筆錄: public static function se

告別加班 移動APP研發提速利器之EMAS跨平臺解決方案

又到週末了,大家手頭的工作完成的怎麼樣啦?還沒有完成的繼續加油鴨!想要告別加班,給大家推薦一個移動APP研發提速利器。本文根據2018杭州雲棲大會移動研發平臺EMAS專場,阿里巴巴產品專家言沛的主題演講《移動APP研發提速利器之EMAS跨平臺解決方案》整理成文。 在座各位應該都是移動APP研發負責人,大

Vue2.5仿去哪兒app 實戰專案筆記

  移動端適配 專案目錄結構 輪播圖 樣式穿透 px與rem   參考頁面:去哪兒網 效果演示: 專案展示: 仿去哪兒網-Vue.js移動webApp   移動端的適配 引入reset.css 在進行頁面開發的

iOS APP名字國際化 筆記

注意 APP顯示名稱,隨系統語言顯示 新建的,字尾為 .string 的檔案 名字必需是InfoPlist 名字必需是InfoPlist 名字必需是InfoPlist 應用內自由切換語言 對應的.string 的檔案 名字必需是Localizable

移動APP開發工作筆記002---Hbuilder js判斷當前裝置是安卓裝置還是蘋果裝置

   JAVA技術交流QQ群:170933152    js判斷是否為手機系統是安卓還是蘋果,是否為微信瀏覽器                  

移動APP開發工作筆記001---Hbuilder連線蘋果手機

   JAVA技術交流QQ群:170933152      最簡單的連線方法 1     手機電腦連線---usb 2     pc下