android開發要避免的那些坑

來源:互聯網
上載者:User

標籤:

  • SparseArray 目前有很多地方從效能最佳化方說使用SparseArray來替換hashMap,來節省記憶體,提高效能。

  • Linkify.addLinks() 這個類可以更方便的為文本添加超連結。

  • ThumbnailUtils 這個類主要是用來處理縮圖相關的,有過這方面需求的,應該是用過這個類的。

  • Bitmap.extractAlpha();返回一個新的Bitmap,capture原始圖片的alpha值。有的時候我們需要動態修改一個元素的背景圖片又不希望使用多張圖片的時候,通過這個方法,結合Canvas和Paint可以動態修改一個純色Bitmap的顏色。

  • 靜態變數不要直接或者間接引用Activity、Service等。這會使用Activity以及它所引用的所有對象無法釋放,然後,使用者操作時間一長,記憶體就會狂升。

  • Handler機制有一個特點是不會隨著Activity、Service的生命週期結束而結束。也就是說,如果你Post了一個Delay的Runnable,然後在Runnable執行之前退出了Activity,Runnable到時間之後還是要執行的。如果Runnable裡麵包含更新View的操作,程式崩潰了。

  • 不少人在子線程中更新View時喜歡使用Context.runOnUiThread,這個方法有個缺點,就是一但Context生命週期結束,比如Activity已經銷毀時,一調用就會崩潰。

  • PackageManager.getInstalledPackages這個方法經常使用,你可能不知道,當擷取的結果數量比較多的時候,在某些機型上面調用它花費的時間可能秒級的,所以盡量在子線程中使用。另外,如果結果太多,超過系統設定的Binder資料最大傳輸量的上限,則會發生TransactionException,如果你使用這個方法擷取機器上的己安裝應用列表,最好做一下預防。

  • 如果使用Context.startActivity啟動外部應用,最好做一下異常預防,因為尋找不到對應的應用時,會拋出異常。如果你要開啟的是應用內的Activity,不防使用顯式Intent,這樣能提高系統搜尋目標Activity的效率。

  • 判斷手機是不是飛航模式 boolean isEnabled = Settings.System.getInt(context.getContentResolver(),
    Settings.System.AIRPLANE_MODE_ON, 0) == 1;

  • 如果子類實現Serializable介面而父類未實現時,父類不會被序列化,但此時父類必須有個無參構造方法,否則會拋InvalidClassException異常。

  • transient關鍵字修飾變數可以限制序列化。

  • 類繼承之間的調用順序 父類static成員 -> 子類static成員 -> 父類普通成員初始化和初始化塊 -> 父類構造方法 ->子類普通成員初始化和初始化塊 -> 子類構造方法

  • 華為手機無法顯示log解決方案,.撥號介面輸入(##2846579##) Service menu will appear.Go
    to “ProjectMenu” -> “Background Setting” -> “Log Setting”Open “Log switch” and set it to ON.Open “Log level setting” and set the log level you wish.

  • 後台service經常因為重啟之類的出現onStartCommand()中的Intent傳遞的參數為null,通過在onStartCommand()中的傳回值改成return super.onStartCommand(intent,Service.START_REDELIVER_INTENT, startId); 可以解決問題。下面介紹幾個flag的意思:

flag 解釋
START_STICKY 如果service進程被kill掉,保留service的狀態為開始狀態,但不保留遞送的intent對象。隨後系統會嘗試重新建立service,由於服務狀態為開始狀態,所以建立服務後一定會調用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那麼參數Intent將為null。
START_NOT_STICKY “非粘性的”。使用這個傳回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統不會自動重啟該服務。
START_REDELIVER_INTENT 重傳Intent。使用這個傳回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啟該服務,並將Intent的值傳入。
START_STICKY_COMPATIBILITY START_STICKY的相容版本,但不保證服務被kill後一定能重啟。
  • getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
    ViewGroup.LayoutParams.MATCH_PARENT);設定全屏方法一定要在setContentView之後

  • viewpager 的 setCurrentItem 一定要在 setAdapter 方法之後調用才會有效果.

  • 當前Activity的onPause方法執行結束後才會執行下一個Activity的onCreate方法,所以在onPause方法中不適合做耗時較長的工作,這會影響到頁面之間的跳轉效率;

  • 謹慎使用Android的透明主題,透明主題會導致很多問題,比如:如果新的Activity採用了透明主題,那麼當前Activity的onStop方法不會被調用;在設定為透明主題的Activity介面按Home鍵時,可能會導致刷屏不乾淨的問題;進入主題為透明主題的介面會有明顯的延時感;

  • 不要在非UI線程中初始化ViewStub,否則會返回null;

  • 盡量不要通過Application快取資料,這不穩定:不要在Android的Application對象中快取資料!

  • (AnimationDrawable在Android5.0及以上的版本已有明顯的最佳化)盡量不要使用AnimationDrawable,它在初始化的時候就將所有圖片載入到記憶體中,特別占記憶體,並且還不能釋放,釋放之後下次進入再次載入時會報錯;

  • 謹慎使用Android的多進程,多進程雖然能夠降低主進程的記憶體壓力,但會遇到如下問題:(1)不能實現完全退出所有Activity的功能(如果有同行在應用內採用多進程成功實現過完全退出程式歡迎溝通交流);(2)首次進入新啟動進程的頁面時會有延時的現象(有可能黑屏、白屏幾秒,是白屏還是黑屏和新Activity的主題有關);(3)應用內多進程時,新啟動一個進程都會重新跑一次Application的onCreate方法,不上重新建立一個Application,但會重新跑Application的onCreate,這樣就不能在Application中快取資料作為記憶體共用的途徑了;(4)多進程間通過SharedPreferences共用資料時不穩定,具體可以查閱《Android開發藝術探索》。

  • View的面積越大繪製的時間就越長,透明通道對View的繪製速度影響很大;

  • 做自訂手寫功能時,底層上報的點並不會都在MotionEvent中能夠及時接收到,比如底層一秒鐘200個點,上層收到的可能只有幾十個點,為了提高手寫的流暢度,在onTouchEvent中,通過MotionEvent中的getHistorySize能夠擷取到從底層傳輸到上層過程中所有的點;

  • 在Android4.0以後,在Manifest.xml中靜態註冊的廣播,程式安裝後必須啟動一次才能接收到廣播,比如你的應用監聽開機啟動的廣播,必須要你的程式被運行過才能監聽到;

  • 在2.3之前GC操作是不能並發進行的,也就是系統進行中GC程式就只能阻塞住等待GC結束,在2.3之後GC操作改成了並發的方式進行,GC過程中不會影響程式的正常運行,但在GC操作的開始和結束還是會短暫阻塞一段時間。所以頻繁的GC會導致使用應用的過程中卡頓,所以為了應用在使用過程中更流暢,需要盡量減少觸發GC操作,這涉及到效能最佳化,對於靜態代碼的分析,AS已經很強大了,可以使用Android Studio的Analyze→Inspect Code…進行分析;

  • 在字串處理方面,android.text.TextUtils這個類就能勝任絕任多數的工作public static boolean isEmpty(@Nullable CharSequence str) 這個方法判斷字串非null且非空
    public static CharSequence concat(CharSequence… text) 字串串連
    public static boolean equals(CharSequence a, CharSequence b) 判斷兩個字串對象的內容是否相等,內部進行了非null判斷
    public static String htmlEncode(String s) 將html代碼中的特殊字元進行轉碼處理

  • 當判斷一些常用的URI的時候,可以用android.webkit.URLUtil這個工具類

  • android.text.format.DateUtils 這個類是Android提供的格式化日期的工具類。

    public static String formatDateTime(Context context, long millis, int
    flags); 這個方法可以格式化日期和時間,接收三個參數,其中第三個參數flags決定輸出後的格式,如果只輸出日期的話:
    DateUtils.formatDateTime(context,millis,DateUtils.FORMAT_SHOW_DATE)

    public static boolean isToday(long when) 判斷日期是否是今天

    public static CharSequence getRelativeTimeSpanString(long startTime)
    返回與當前的相對時間的字串比如的聊天列表上顯示的上一條資訊的時間,如果是今天就顯示今天的時間,是昨天的就顯示昨天,再久遠一點的就顯示日期(但是這個方法的最大隻能精確到天,不能像那樣顯示到幾秒前,幾分鐘前)。

  • tools schemas在建立Activity時IDE都會在xml的根節點預設加上tools的命名空間

    <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"   xmlns:app="http://schemas.android.com/apk/res-auto"   xmlns:tools="http://schemas.android.com/tools"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:orientation="vertical"   tools:context=".MainActivity"   tools:showIn="@layout/activity_main_utils">   <Button       android:id="@+id/btn_select_date"       android:layout_width="match_parent"       android:layout_height="wrap_content"</LinearLayout>

    在寫布局的時候經常會寫一些無用的字串用來預覽布局,但是這些資料一般會在完成後刪除,有時候在維護時為了方便預覽再寫上。這時可以使用tools的命名空間,比如tools:text=”點擊選擇日期”tools僅僅可以預覽,在啟動並執行狀態下解析布局檔案時就會忽略過這條屬性。這非常適合用於預覽布局。

  • 如果是在應用範圍內的廣播可以使用LocalBroadcastManager這個API(低版本用v4下的),更加安全高效,不必擔心別的app偽造廣播或收聽你的廣播做一些不好的事情。

  • Html.fromHtml() 如果你對Html熟悉的話,可以很迅速通過這個方法處理一些富文本操作。比如超連結和圖文排版等處理。

  • Build.VERSION_CODES 有些時候我們的app需要根據不同的SDK版本進行執行不同的操作

  • ValueAnimator.reverse() 順暢的取消動畫效果

  • Formatter.formatFileSize() 這個方法會格式化資料的大小,根據輸入的位元組大小,返回 B KB MB GB等等(最大支援到 PB)。當然要注意的是輸入的最大值是 Long.MAX_VALUE.

  • TypedValue.applyDimension() 首先這個方法我們可以用來對sp dp 和 px 之間的單位轉換

  • 有些時候不能使用Application的Context,不然會報錯(比如啟動Activity,顯示Dialog等)

    *備忘:大家注意看到有一些NO上添加了一些數字,其實這些從能力上來說是YES,但是為什麼說是NO呢?下面一個一個解釋: 1. 數字1:啟動Activity在這些類中是可以的,但是需要建立一個新的task,一般情況不推薦; 2. 數字2:在這些類中去layout inflate是合法的,但是會使用系統預設的主題樣式,如果你自訂了某些樣式可能不會被使用; 3. 數字3:在Receiver為null時允許,在4.2或以上的版本中,用於擷取黏性廣播的當前值。(可以無視); 4. ContentProvider、BroadcastReceiver之所以在上述表格中,是因為在其內部方法中都有一個context用於使用

  • UncaughtExceptionHandler介面,再好的代碼異常難免,利用此介面可以對未捕獲的異常善後

  • Arrays類中的一系列關於數組操作的工具方法:binarySearch(),asList(),equals(),sort(),toString(),copyOfRange()等;Collections類中的一系列關於集合操作的工具方法:sort(),reverse()等;

  • Activity類中的onWindowFocusChanged(boolean),onNewIntent(intent)等回調方法;

  • PageTransformer介面,用來自訂ViewPager頁面切換動畫,用setPageTransformer(boolean,PageTransformer)方法來進行設定;

  • UrlQuerySanitizer——使用這個工具可以方便對 URL 進行檢查。

  • ActivityOptions ——方便的定義兩個Activity切換的動畫。 使用ActivityOptionsCompat可以很好解決舊版本的相容問題。

  • getParent().requestDisallowInterceptTouchEvent(true);剝奪父view對touch事件的處理權

  • IntentService,一個可以幹完活後自己去死且不需要我們去管理子線程的Service

  • HandlerThread,代替不停new Thread開子線程的重複體力寫法。

  • android:animateLayoutChanges=”true”,LinearLayout中添加View的動畫的辦法,支援通過setLayoutTransition()自訂動畫。

  • AsyncQueryHandler,如果做系統工具類的開發,比如連絡人簡訊協助工具輔助等,肯定免不了和ContentProvider打交道,如果資料量不是很大的情況下,隨便搞,如果資料量大的情況下,瞭解下這個類是很有必要的,需要注意的是,這玩意兒吃異常。

  • android:descendantFocusability,ListView的item中CheckBox等元素搶焦點導致item點擊事件無法響應時,除了給對應的元素設定
    focusable,更簡單的是在item根布局加上android:descendantFocusability=”blocksDescendants”。

  • includeFontPadding=”false”,TextView預設上下是有一定的padding的,有時候我們可能不需要上下這部分留白,加上它即可。

  • Messenger,面試的時候通常都會被問到處理序間通訊,除了AIDL,還有這個可以裝下~~(Android開發藝術探索中有講)

  • EditTxt.setImeOptions, 使用EditText彈出軟鍵盤時,修改斷行符號鍵的顯示內容。

  • java8中新增的LocalDate和LocalTime介面,Date雖然是個萬能介面,但是它真的不好用,有了這倆,終於可以愉快的處理日期時間了。

  • WeakHashMap,直接使用HashMap有時候會帶來記憶體溢出的風險,使用WaekHashMap執行個體化Map。當使用者不再有對象引用的時候,WeakHashMap將自動被移除對應Key值的對象。

  • 使用SnackBar的時候,不要使用view.getRootView()作為snackbar的view,華為榮耀7 會出問題。

  • 設定TextView單行顯示的時候不要用Lines=1,而要用singleLine=”true”,因為魅族部分手機在設定Lines=1的時候,然後TextView的值全為數位時候, 你就會懵逼了。

  • ArgbEvaluator可用於計算不同顏色值之間的插值,配合ValueAnimator.ofObject或者ViewPager.PageTransformer使用,可以實現不同顏色之間的平滑過渡。

  • Activity.recreate重新建立Activity。有什麼用呢?可以在程式更換主題後,立馬重新整理當前Activity,而不會有明顯的重啟Activity的動畫。(螢幕會變黑一下)

  • View.getContext顧名思義,就不用解釋了吧

  • View.post方便在非UI線程對介面進行修改,與Handler的作用類似。並且由於post的Runnable會保證在該View繪製完成的前提下才調用,所以一般也可以用於擷取View的寬高;還有一種是用getViewTreeObserver擷取寬高。

  • Fragment.setUserVisibleHintFragment可以重寫此方法,然後根據參數的布爾值(true的話表示當前Fragment對使用者可見),來執行一些邏輯。

  • android:clipToPadding
    設定父view是否允許其子view在它的padding(這裡指的是父View的padding)中繪製。是不是有點繞?舉個實際情境吧:假如有個ListView,我們想要在初始位置時,第一項Item離頂部有10dp的距離,就可以在ListView的布局中加入android:clipToPadding=”false” android:paddingTop=”10dp”即可。

  • onTrimMemory,在Activity中重寫此方法,會在記憶體緊張的時候回調(支援多個層級),便於我們主動的進行資源釋放,避免OOM。

  • android:clipChildren (ViewGroup)——如果此屬性設定為不可用,那麼 ViewGroup 的子 View在繪製的時候會超出它的範圍,在做動畫的時候需要用到。

  • android:tileMode (BitmapDrawable)——可以指定圖片使用重複填充的模式。

  • SharedPreference.Editor的apply是非同步作業,不會返回成功的狀態,而commit是同步操作,因此,在多個並發的提交commit的時候,他們會等待正在處理的commit儲存到磁碟後再操作下一個資料,從而降低了效率。

參考: http://www.zhihu.com/question/27818921
https://github.com/jiang111/awesome-android-tips

android開發要避免的那些坑

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.