這些年我踩過的坑——Android

  • PD假設經常要求改入口,使用Adapter + ViewHolder來實現解耦:
    • 這兩個配合模擬FragmentManager + Fragment的邏輯
    • Adapter只負責管理View、對ViewHolder中的生命週期函數進行回調
    • ViewHolder不只保存View的引用。還完整包含與該View有關的所有邏輯,對外暴露一樣的生命週期回調函數,好比onViewCreated、onBindView等
    • 調整入口只需要在Activity中調整Adapter的Data
    • 切記要將ViewHolder與View綁定,假設不綁定就不要複用以前的View,不然空指針
  • Json是弱類型。子類Json串填充父類對象將會出現Member丟失的狀況
  • getSystemService得到Inflater的時候,必定要用Activity的Context。不能用Application Context
  • ListView跳轉到item的某個位置。需要用setSelectoinFromTop,不能setSelection再scroll。ListView直接scroll會致使跳動和空白item
  • ListView中傳遞的所有關於Position的數據都是包含Header、Footer的,算數要當心
  • 在Inflate時,必定要傳入parent參數。不然一些依賴父節點的layout參數是不能解析的。詳見:這裏
  • merge節點在inflate時,必須attachToRoot傳true。不然crash
  • LaunchMode以及ApplicationContext+ActivityContext引起的Task棧混亂問題
  • Android/Linux系統是不保存文件建立時間的,假設想拿到文件建立時間,需要用比較tricky的辦法。

    文件名稱由兩部分組成:原始文件名稱+分隔符+建立時間(1970毫秒).擴展名。html

    原始文件名稱開頭比較easy寫Filterjava

  • 反射在Android上真的很是慢。ormlite比直接使用sql要慢一倍!

  • Activity.runOnUiThread()使用的Handler儘管是Activity的成員變量。其相應的Looper倒是Looper.myLooper()。所有runOnUiThread的Runnable即便Activity已經被finish仍然會被運行
  • SqliteDatabase.beginTransaction必定要setTransactionSuccessful。不然所有的操做都會取消!!

    android

  • 基本所有使用回調的地方都可以經過KVO來實現,而且直接使用LocalBroadcast可以避免很是多內存泄露啊、監聽器管理之類的麻煩。
  • 應對軟鍵盤遮擋的問題,可以處理四個不一樣的事件,事件和調用順序例如如下:
    1. onSizeChanged(Activity需要是AdjustResize的)
    2. onLayout(不用監聽onMeasure,回調的位置太多了)
    3. addOnLayoutChangeListener監聽layout的回調事件
    4. getViewTreeObserver().addOnGlobalLayoutListener監聽全局的layout事件
  • 聽說在App被卸載/中止的時候。jni裏fork出來的子線程是不會被中止的。這樣就可以幹很是多流氓的事情了,比方保活之類的
  • 有一個很是讚的hook,LayoutInflater.Factory提供在原生View的xml裏添加新的attribute。

    樣例git

  • 關於軟鍵盤的問題:github

    • 調起來說,((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).
      showSoftInput(view, 0);
      tag爲0是默認。SHOW_FORCED在某些rom上會要求用戶主動點back才幹收起鍵盤。使用不論什麼一種代碼上的hide都不生效,壓後臺也不生效。理論上是tag越大。show的動做越強sql

    • 收起來說,((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).
      hideSoftInputFromWindow(editText.getWindowToken(), 0);
      tag爲0是默認的,最強的是HIDE_NOT_ALWAYS,卻仍然不能hide用SHOW_FORCED調起的鍵盤markdown

  • Activity上的Theme之類的都是給Window的DecorView設置的。生效的面積大於Activity的面積(在鍵盤動畫的狀況下)網絡

  • 設計的時候,各類碼、狀態類型要統一,儘可能使用int,打印也別非轉換一下。session

    碼類型轉換、字符串拼接這樣的很是耗內存也會添加apk大小ide

  • 使用ValueAnimator作顏色動畫時,必定要用ValueAnimator.ofObject(new ArgbEvaluator(), colors),不能用ValueAnimator.ofInt(colors);。後者會閃,各類閃

  • Fragment因爲在切換過程當中會有各類post,會有不可解的crash。可以本身實現簡單的fragment
  • View的Animation和setXXX是不同的,Animation都是做用在Transform上的。因此所有的結果不能經過setXXX恢復
  • View在add到Window以前post的runnable可能會在add以後不被運行(因爲相應的消息隊列變了)
  • 獲取當前進程名,反射調用android.ddm.DdmHandleAppName.getAppName()。或者使用pid反查
  • 進程的啓動緣由會在MainLooper中Message的obj中存儲,對象不一樣區分緣由
  • SP每次get的時候都會讀文件,假設SP數據不大的話,仍是在內存中保存一份效率高
  • 一個設計合理的埋點應該包含這幾方面。當中的大部分信息都是固定的。可以參考Android中xml壓縮的方法,在多個埋點中重用一樣內容:
    • 固定上下文:用戶信息、設備信息、時間、App信息
    • 交互上下文:Session、網絡
    • 當前用戶操做的信息:類型。所在的模塊、頁面、View,referer(http_referer),url
    • 其它:數據分析串連埋點用的埋點session、埋點起止標識位
  • 可以經過WindowFocus推斷Activity是否在前臺(isResumed)。包含了是否有彈框、是否被其它view遮擋了。toast這樣的不能獲取焦點的window不會影響。很是敞亮的方法
  • 聽說.9作selector的時候,padding會失效。源代碼上看,padding的計算會受背景的大小影響
相關文章
相關標籤/搜索