Android開發中,有哪些讓你覺得相見恨晚的方法、類或介面?

Android(Java)開發中,有哪些方法、類或介面很實用,但是你卻沒能在第一時間知道它?有一天你發現它時,只想說一句:「What the f**k,還有這個!」

相關問題:Android開發時你遇到過什麼相見恨晚的工具或網站? - Android 開發


拋磚引玉一下,怎麼都沒什麼人?

1、Throwable介面中的getStackTrace()方法(或者Thread類的getStackTrace()方法),根據這個方法可以得到函數的逐層調用地址,其返回值為StackTraceElement[];

2、StackTraceElement類,其中四個方法getClassName(),getFileName(),getLineNumber(),getMethodName()在調試程序列印Log時非常有用;

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

使用參見:Android使用UncaughtExceptionHandler捕獲全局異常

4、Resources類中的getIdentifier(name, defType, defPackage)方法,根據資源名稱獲取其ID,做UI時經常用到;

5、View中的isShown()方法,以前都是用view.getVisibility() == View.VISIBLE來判斷的(╯□╰);(謝評論提醒,這裡面其實有一個坑:【android】view.isShown ()的用法)

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

Collections類中的一系列關於集合操作的工具方法:sort(),reverse()等;

7、android.text.format.Formatter類中formatFileSize(Context, long)方法,用來格式化文件Size(B → KB → MB → GB);

8、android.media.ThumbnailUtils類,用來獲取媒體(圖片、視頻)縮略圖;

9、String類中的format(String, Object...)方法,用來格式化strings.xml中的字元串(多謝 @droider An 提示:Context類中getString(int, Object... )方法用起來更加方便);

10、View類中的三個方法:callOnClick()performClick()performLongClick(),用於觸發View的點擊事件;

11、TextUtils類中的isEmpty(CharSequence)方法,判斷字元串是否為null或"";

12、TextView類中的append(CharSequence)方法,添加文本。一些特殊文本直接用+連接會變成String;

13、View類中的getDrawingCache()等一系列方法,目前只知道可以用來截圖;

14、DecimalFormat類,用於字串格式化包括指定位數、百分數、科學計數法等;

15、System類中的arraycopy(src, srcPos, dest, destPos, length)方法,用來copy數組;

16、Fragment類中的onHiddenChanged(boolean)方法,使用FragmentTransaction中的hide(),show()時貌似Fragment的其它生命周期方法都不會被調用,太坑爹!

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

18、View類中的getLocationInWindow(int[])方法和getLocationOnScreen(int[])方法,獲取View在窗口/屏幕中的位置;

19、TextView類中的setTransformationMethod(TransformationMethod)方法,可用來實現「顯示密碼」功能;

20、TextWatcher介面,用來監聽文本輸入框內容的改變,可用來實現一系列具有特殊功能的文本輸入框;

21、View類中的setSelected(boolean)方法結合android:state_selected=""用來實現圖片選中效果;

22、Surface設置透明:SurfaceView.setZOrderOnTop(true);

SurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);但是會擋住其它控制項;

23、ListView或GridView類中的setFastScrollEnabled(boolean)方法,用來設置快速滾動滑塊是否可見,當然前提是item夠多;

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

25、apache提供的一系列jar包:commons-lang.jarcommons-collections.jarcommons-beanutils.jar等,裡面很多方法可能是你曾經用幾十幾百行代碼實現過的,但是執行效率或許要差很多,比如:ArrayUtils,StringUtils……;

26、AndroidTestCase類,Android單元測試,在AndroidStudio中使用非常方便;

27、TextView類的setKeyListener(KeyListener)方法;

其中DigitsKeyListener類,使用getInstance(String accepted)方法即可指定EditText可輸入字符集;

28、ActivityLifecycleCallbacks介面,用於在Application類中監聽各Activity的狀態變化;

29、Context類中的createPackageContext(packageName, flags)方法,可用來獲取指定包名應用程序的Context對象。


首先呼應題目,Log.wtf()

Part 1:

Activity.startActivities() 常用於在應用程序中間啟動其他的Activity。

TextUtils.isEmpty() 簡單的工具類,用於檢測是否為空。

Html.fromHtml() 用於生成一個Html,參數可以是一個字元串.個人認為它不是很快,所以我不怎麼經常去用.(我說不經常用它是為了重點突出這句話:請多手動構建 Spannable 來替換 Html.fromHtml),但是它對渲染從 web 上獲取的文字還是很不錯的。

TextView.setError() 在驗證用戶輸入的時候很棒。

Build.VERSION_CODES 這個標明了當前的版本號,在處理兼容性問題的時候經常會用到.點進去可以看到各個版本的不同特性。

Log.getStackTraceString() 方便的日誌類工具,方法Log.v()、Log.d()、Log.i()、Log.w()和Log.e()都是將信息列印到LogCat中,有時候需要將出錯的信息插入到資料庫或一個自定義的日誌文件中,那麼這種情況就需要將出錯的信息以字元串的形式返回來,也就是使用static String getStackTraceString(Throwable tr)方法的時候。

LayoutInflater.from() 顧名思義,用於Inflate一個layout,參數是layout的id.這個經常寫Adapter的人會用的比較多。

ViewConfiguration.getScaledTouchSlop() 使用 ViewConfiguration 中提供的值以保證所有觸摸的交互都是統一的。這個方法獲取的值表示:用戶的手滑動這個距離後,才判定為正在進行滑動.當然這個值也可以自己來決定.但是為了一致性,還是使用標準的值較好。

PhoneNumberUtils.convertKeypadLettersToDigits 顧名思義.將字母轉換為數字,類似於T9輸入法,

Context.getCacheDir() 獲取緩存數據文件夾的路徑,很簡單但是知道的人不多,這個路徑通常在SD卡上(這裡的SD卡指的是廣義上的SD卡,包括外部存儲和內部存儲)Adnroid/data/您的應用程序包名/cache/ 下面.測試的時候,可以去這裡面看是否緩存成功.緩存在這裡的好處是:不用自己再去手動創建文件夾,不用擔心用戶把自己創建的文件夾刪掉,在應用程序卸載的時候,這裡會被清空,使用第三方的清理工具的時候,這裡也會被清空。

ArgbEvaluator 用於處理顏色的漸變。就像 Chris Banes 說的一樣,這個類會進行很多自動裝箱的操作,所以最好還是去掉它的邏輯自己去實現它。這個沒用過,不明其所以然,回頭再補充.

ContextThemeWrapper 方便在運行的時候修改主題。

Space space是Android 4.0中新增的一個控制項,它實際上可以用來分隔不同的控制項,其中形成一個空白的區域.這是一個輕量級的視圖組件,它可以跳過Draw,對於需要佔位符的任何場景來說都是很棒的。

ValueAnimator.reverse() 這個方法可以很順利地取消正在運行的動畫。

---------------------------------------------------------------------------------------------------------------------------------

Part 2:

DateUtils.formatDateTime() 用來進行區域格式化工作,輸出格式化和本地化的時間或者日期。

AlarmManager.setInexactRepeating 通過鬧鈴分組的方式省電,即使你只調用了一個鬧鐘,這也是一個好的選擇,(可以確保在使用完畢時自動調用 AlarmManager.cancel ()。原文說的比較抽象,這裡詳細說一下:setInexactRepeating指的是設置非準確鬧鐘,使用方法:alarmManager.setInexactRepeating(AlarmManager.RTC, startTime,intervalL, pendingIntent),非準確鬧鐘只能保證大致的時間間隔,但是不一定準確,可能出現設置間隔為30分鐘,但是實際上一次間隔20分鐘,另一次間隔40分鐘。它的最大的好處是可以合併鬧鐘事件,比如間隔設置每30分鐘一次,不喚醒休眠,在休眠8小時後已經積累了16個鬧鐘事件,而在手機被喚醒的時候,非準時鬧鐘可以把16個事件合併為一個, 所以這麼看來,非準時鬧鐘一般來說比較節約能源。

Formatter.formatFileSize() 一個區域化的文件大小格式化工具。通俗來說就是把大小轉換為MB,G,KB之類的字元串。

ActionBar.hide()/.show() 顧名思義,隱藏和顯示ActionBar,可以優雅地在全屏和帶Actionbar之間轉換。

Linkify.addLinks() 在Text上添加鏈接。很實用。

StaticLayout 在自定義 View 中渲染文字的時候很實用。

Activity.onBackPressed() 很方便的管理back鍵的方法,有時候需要自己控制返回鍵的事件的時候,可以重寫一下。比如加入 「點兩下back鍵退出」 功能。

GestureDetector 用來監聽和相應對應的手勢事件,比如點擊,長按,慢滑動,快滑動,用起來很簡單,比你自己實現要方便許多。

DrawFilter 可以讓你在不調用onDrew方法的情況下,操作canvas,比了個如,你可以在創建自定義 View 的時候設置一個 DrawFilter,給父 View 裡面的所有 View 設置反別名。

ActivityManager.getMemoryClass() 告訴你你的機器還有多少內存,在計算緩存大小的時候會比較有用。

ViewStub 它是一個初始化不做任何事情的 View,但是之後可以載入一個布局文件。在慢載入 View 中很適合做佔位符。唯一的缺點就是不支持標籤,所以如果你不太小心的話,可能會在視圖結構中加入不需要的嵌套。

SystemClock.sleep() 這個方法在保證一定時間的 sleep 時很方便,通常我用來進行 debug 和模擬網路延時。

DisplayMetrics.density 這個方法你可以獲取設備像素密度,大部分時候最好讓系統來自動進行縮放資源之類的操作,但是有時候控制的效果會更好一些.(尤其是在自定義View的時候)。

Pair.create() 方便構建類和構造器的方法。

---------------------------------------------------------------------------------------------------------------------------------

Part 3:

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

Fragment.setArguments——因為在構建 Fragment 的時候不能加參數,所以這是個很好的東西,可以在創建 Fragment 之前設置參數(即使在 configuration 改變的時候仍然會導致銷毀/重建)。

DialogFragment.setShowsDialog ()—— 這是一個很巧妙的方式,DialogFragment 可以作為正常的 Fragment 顯示!這裡可以讓 Fragment 承擔雙重任務。我通常在創建 Fragment 的時候把 onCreateView ()和 onCreateDialog ()都加上,就可以創建一個具有雙重目的的 Fragment。

FragmentManager.enableDebugLogging ()——在需要觀察 Fragment 狀態的時候會有幫助。

LocalBroadcastManager——這個會比全局的 broadcast 更加安全,簡單,快速。像 otto 這樣的 Event buses 機制對你的應用場景更加有用。

PhoneNumberUtils.formatNumber ()——顧名思義,這是對數字進行格式化操作的時候用的。

Region.op()——我發現在對比兩個渲染之前的區域的時候很實用,如果你有兩條路徑,那麼怎麼知道它們是不是會重疊呢?使用這個方法就可以做到。

Application.registerActivityLifecycleCallbacks——雖然缺少官方文檔解釋,不過我想它就是註冊 Activity 的生命周期的一些回調方法(顧名思義),就是一個方便的工具。

versionNameSuffix——這個 gradle 設置可以讓你在基於不同構建類型的 manifest 中修改版本名這個屬性,例如,如果需要在在 debug 版本中以」-SNAPSHOT」結尾,那麼就可以輕鬆的看出當前是 debug 版還是 release 版。

CursorJoiner——如果你是只使用一個資料庫的話,使用 SQL 中的 join 就可以了,但是如果收到的數據是來自兩個獨立的 ContentProvider,那麼 CursorJoiner 就很實用了。

Genymotion——一個非常快的 Android 模擬器,本人一直在用。

-nodpi——在沒有特別定義的情況下,很多修飾符(-mdpi,-hdpi,-xdpi等等)都會默認自動縮放 assets/dimensions,有時候我們需要保持顯示一致,這種情況下就可以使用 -nodpi。

BroadcastRecevier.setDebugUnregister ()——又一個方便的調試工具。

Activity.recreate ()——強制讓 Activity 重建。

PackageManager.checkSignatures ()——如果同時安裝了兩個 app 的話,可以用這個方法檢查。如果不進行簽名檢查的話,其他人可以輕易通過使用一樣的包名來模仿你的 app。

---------------------------------------------------------------------------------------------------------------------------------

Part 4:

Activity.isChangingConfigurations ()——如果在 Activity 中 configuration 會經常改變的話,使用這個方法就可以不用手動做保存狀態的工作了。

SearchRecentSuggestionsProvider——可以創建最近提示效果的 provider,是一個簡單快速的方法。

ViewTreeObserver——這是一個很棒的工具。可以進入到 VIew 裡面,並監控 View 結構的各種狀態,通常我都用來做 View 的測量操作(自定義視圖中經常用到)。

org.gradle.daemon=true——這句話可以幫助減少 Gradle 構建的時間,僅在命令行編譯的時候用到,因為 Android Studio 已經這樣使用了。

DatabaseUtils——一個包含各種資料庫操作的使用工具。

android:weightSum (LinearLayout)——如果想使用 layout weights,但是卻不想填充整個 LinearLayout 的話,就可以用 weightSum 來定義總的 weight 大小。

android:duplicateParentState (View)——此方法可以使得子 View 可以複製父 View 的狀態。比如如果一個 ViewGroup 是可點擊的,那麼可以用這個方法在它被點擊的時候讓它的子 View 都改變狀態。

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

android:fillViewport (ScrollView)——在這片文章中有詳細介紹文章鏈接,可以解決在 ScrollView 中當內容不足的時候填不滿屏幕的問題。

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

android:enterFadeDuration/android:exitFadeDuration (Drawables)——此屬性在 Drawable 具有多種狀態的時候,可以定義它展示前的淡入淡出效果。

android:scaleType (ImageView)——定義在 ImageView 中怎麼縮放/剪裁圖片,一般用的比較多的是「centerCrop」和「centerInside」。

Merge——此標籤可以在另一個布局文件中包含別的布局文件,而不用再新建一個 ViewGroup,對於自定義 ViewGroup 的時候也需要用到;可以通過載入一個帶有標籤的布局文件來自動定義它的子部件。

AtomicFile——通過使用備份文件進行文件的原子化操作。這個知識點之前我也寫過,不過最好還是有出一個官方的版本比較好。

---------------------------------------------------------------------------------------------------------------------------------

Part 5:

ViewDragHelper ——視圖拖動是一個比較複雜的問題。這個類可以幫助解決不少問題。如果你需要一個例子,DrawerLayout就是利用它實現掃滑。Flavient Laurent 還寫了一些關於這方面的優秀文章。

PopupWindow——Android到處都在使用PopupWindow ,甚至你都沒有意識到(標題導航條ActionBar,自動補全AutoComplete,編輯框錯誤提醒Edittext Errors)。這個類是創建浮層內容的主要方法。

Actionbar.getThemrContext()——導航欄的主題化是很複雜的(不同於Activity其他部分的主題化)。你可以得到一個上下文(Context),用這個上下文創建的自定義組件可以得到正確的主題。

ThumbnailUtils——幫助創建縮略圖。通常我都是用現有的圖片載入庫(比如,Picasso 或者 Volley),不過這個ThumbnaiUtils可以創建視頻縮略圖。譯者註:該API從V8才開始支持。

Context.getExternalFilesDir()———— 申請了SD卡寫許可權後,你可以在SD的任何地方寫數據,把你的數據寫在設計好的合適位置會更加有禮貌。這樣數據可以及時被清理,也會有更好的用戶體驗。此外,Android 4.0 Kitkat中在這個文件夾下寫數據是不需要許可權的,每個用戶有自己的獨立的數據存儲路徑。譯者註:該API從V8才開始支持。

SparseArray——Map的高效優化版本。推薦了解姐妹類SparseBooleanArray、SparseIntArray和SparseLongArray。

PackageManager.setComponentEnabledSetting()——可以用來啟動或者禁用程序清單中的組件。對於關閉不需要的功能組件是非常贊的,比如關掉一個當前不用的廣播接收器。

SQLiteDatabase.yieldIfContendedSafely()——讓你暫時停止一個資料庫事務, 這樣你可以就不會佔用太多的系統資源。

Environment.getExternalStoragePublicDirectory()——還是那句話,用戶期望在SD卡上得到統一的用戶體驗。用這個方法可以獲得在用戶設備上放置指定類型文件(音樂、圖片等)的正確目錄。

View.generateViewId()——每次我都想要推薦動態生成控制項的ID。需要注意的是,不要和已經存在的控制項ID或者其他已經生成的控制項ID重複。

ActivityManager.clearApplicationUserData()—— 一鍵清理你的app產生的用戶數據,可能是做用戶退出登錄功能,有史以來最簡單的方式了。

Context.createConfigurationContext() ——自定義你的配置環境信息。我通常會遇到這樣的問題:強制讓一部分顯示在某個特定的環境下(倒不是我一直這樣瞎整,說來話長,你很難理解)。用這個實現起來可以稍微簡單一點。

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

AdapterViewFlipper.fyiWillBeAdvancedByHostKThx()——僅僅因為很好玩,沒有其他原因。在整個安卓開源項目中(AOSP the Android ——pen Source Project Android開放源代碼項目)中還有其他很有意思的東西(比如

GRAVITY_DEATH_STAR_I)。不過,都不像這個這樣,這個確實有用

ViewParent.requestDisallowInterceptTouchEvent() ——Android系統觸摸事件機制大多時候能夠默認處理,不過有時候你需要使用這個方法來剝奪父級控制項的控制權。

==============================&>&> 以上 &<&<===============================

譯文出自 @Gracker 的博客,Android Performance:

Part1: [譯]Android小技巧(1)

Part2: [譯]Android小技巧(2)

Part3:[譯]Android小技巧(3)

Part4: [譯]Android小技巧(4)

Part5: [譯]Android小技巧(5)

原文出自 Dan Lew 的博客,有 5 篇,強烈推薦。

Android Tips Round-Up, Part 1

Android Tips Round-Up, Part 2

Android Tips Round-Up, Part 3

Android Tips Round-Up, Part 4

Android Tips Round-Up, Part 5

最後做個福利廣告 zhengxiaopeng/android-dev-bookmarks · GitHub

=============================&>&> 以下個人補充 &<&<=============================

1、android:clipChildren 和 android:clipToPadding:clipToPadding就是說控制項的繪製區域是否在padding裡面的,true的情況下如果你設置了padding那麼繪製的區域就往裡 縮,clipChildren是指子控制項是否超過padding區域,這兩個屬性默認是true的,所以在設置了padding情況下,默認滾動是在 padding內部的,要達到上面的效果主要把這兩個屬性設置了false那麼這樣子控制項就能畫到padding的區域了。使用場景如:ActionBar(透明)下顯示Listview而第一項要在actionbar下。參見 android:clipToPadding和android:clipChildren。

2、Fragment 的 setUserVisibleHint 方法,可實現 fragment 對用戶可見時才載入資源(延遲載入)。

3、自定義 View 時重寫 hasOverlappingRendering 方法指定 View 是否有 Overlapping 的情況,提高渲染性能。

4、AutoScrollHelper,在可滾動視圖中長按邊緣實現滾動,Android View.OnTouchListener 的子類。

5、TouchSlop,系統所能識別出的被認為是最小的滑動距。離,ViewConfiguration.get(context).getScaledTouchSlop()。

6、VelocityTracker,可用於 View 滑動事件速度跟蹤。

7、AlphabetIndexer,字母索引輔助類。

8、Messenger,AIDL 實現的封裝,比手寫 AIDL 更方便。

9、ArrayMap,比 HashMap 更高的內存效率,但比 HashMap 慢,不適合有大量數據的場景。

10、Property,抽象類,封裝出對象中的一個易變的屬性值,使用場景如在使用屬性動畫時對動畫屬性的操作。

11、SortedList,v7 包中,見名知意。

...


  • 清除畫布上的內容:canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

  • 在自定義View的onDetachedFromWindow方法中清理與View相關的資源;

  • Fragment在onAttach方法中接收回調:

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mPageSelectedListener = (PageSelectedListener) activity;
mMenuBtnOnclickListener = (MenuBtnOnClickListener) activity;
mCommitBtnOnClickListener = (CommitBtnOnClickListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + "must implements listener");
}
}

  • 使用ClipDrawable實現進度條功能;
  • 自定義view中的getContext(),再也不需要專門創建一個mContext全局對象了;
  • 自定義手寫view的時候,在手指移動的過程中通過MotionEvent | Android Developers對象的getHistorySize()獲得緩存的歷史點,繪製出來的曲線要平滑很多。
  • 複寫Activity的onUserLeaveHint方法,確保用戶離開界面時能夠立即暫停界面中的一些任務,關於onUserLeaveHint的更多作用可以谷歌:android - Google 搜索
  • 在AndroidManifest.xml中給Activity標籤設置了android:excludeFromRecents="true"屬性後,退出程序後,長按Home鍵,該Activity不會在最近任務列表中顯示。
  • 值得借鑒的點擊兩次退出應用的實現:Android關於雙擊退出應用的問題

沒那麼麻煩,直接用toast的getView().getParent() 判斷是不是空就ok了。API 16 測試通過

public class MainActivity extends Activity {

private Toast toast;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toast = Toast.makeText(getApplicationContext(), "確定退出?", 0);

}
public void onBackPressed() {
quitToast();
}
/*
public boolean onKeyDown(int keyCode, KeyEvent event) {
System.out.println(keyCode + "...." + event.getKeyCode());
if(keyCode == KeyEvent.KEYCODE_BACK){
quitToast();
}
return super.onKeyDown(keyCode, event);
}
*/
private void quitToast() {
if(null == toast.getView().getParent()){
toast.show();
}else{
System.exit(0);
}
}
}


  • HandlerThread 單一線程 + 任務隊列 處理輕量的非同步任務 詳見 詳解 Android 中的 HandlerThread

  • Proguard assumenosideeffects 編譯器屏蔽日誌 詳見 關於Android Log的一些思考

  • Android性能調優利器StrictMode

  • Android中線程優先順序控制 android.os.Process.setThreadPriority 詳見 剖析Android中進程與線程調度之nice

  • Android Lint 一個靜態分析工具 詳見 使用Android lint發現並解決高版本API問題
  • (更新) 使用UncaughtExceptionHandler 處理應用崩潰,收集信息甚至可以不顯示崩潰對話框 詳細:Android處理崩潰的一些實踐
  • Application.registerActivityLifecycleCallbacks 用來監聽一些Activity的回調。使用參考:http://droidyue.com/blog/2016/02/21/thinking-of-getting-the-current-activity-in-android/


android:animateLayoutChanges

一直以為 Lollipop Dialer 接通畫面裡面那些酷炫的動畫(文字部分)是很複雜的做出來的,後來發現其實只有一行。

視頻 演示:https://dl.pushbulletusercontent.com/N75Bx03taJzFVjjLkMpzzyqGKT8m5PpH/cm_trltexxLMY48Gyilun07312015153119.mp4

只需要加好 android:animateLayoutChanges="true" 然後 setVisibility 就可以了


樓上很多已經提過的我就不重複了。

1、getParent().requestDisallowInterceptTouchEvent(true);剝奪父view對touch事件的處理權,誰用誰知道。

2、ArgbEvaluator.evaluate(float fraction, Object startValue, Object endValue);用於根據一個起始顏色值和一個結束顏色值以及一個偏移量生成一個新的顏色,分分鐘實現類似於微信底部欄滑動顏色漸變。

3、Canvas中clipRect、clipPath和clipRegion剪切區域的API。

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

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

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

7、Palette,5.0加入的可以提取一個Bitmap中突出顏色的類,結合上面的Bitmap.extractAlpha,你懂的。

8、Executors. newSingleThreadExecutor();這個是java的,之前不知道它,自己花很大功夫去研究了單線程順序執行的任務隊列。。

9、android:animateLayoutChanges="true",LinearLayout中添加View的動畫的辦法,支持通過setLayoutTransition()自定義動畫。

10、ViewDragHelper,自定義ViewGroup處理各種事件很累吧,嗯? what the fuck!!

11、GradientDrawable,之前接手公司的項目,發現有個陰影效果還不錯,以為是切的圖片,一看代碼,什麼鬼= =!

12、AsyncQueryHandler,如果做系統工具類的開發,比如聯繫人簡訊輔助工具等,肯定免不了和ContentProvider打交道,如果數據量不是很大的情況下,隨便搞,如果數據量大的情況下,了解下這個類是很有必要的,需要注意的是,這玩意兒吃異常..

13、ViewFlipper,實現多個view的切換(循環),可自定義動畫效果,且可針對單個切換指定動畫。

14、有朋友提到了在自定義View時有些方法在開啟硬體加速的時候沒有效果的問題,在API16之後確實有很多方法不支持硬體加速,通常我們關閉硬體加速都是在清單文件中通過&,其實android也提供了針對特定View關閉硬體加速的方法,調用View.setLayerType(View.LAYER_TYPE_SOFTWARE, null);即可。

15、android util包中的Pair類,可以方便的用來存儲一"組"數據。注意不是key value。

16、PointF,graphics包中的一個類,我們經常見到在處理Touch事件的時候分別定義一個downX,一個downY用來存儲一個坐標,如果坐標少還好,如果要記錄的坐標過多那代碼就不好看了。用PointF(float x, float y);來描述一個坐標點會清楚很多。

17、StateListDrawable,定義Selector通常的辦法都是xml文件,但是有的時候我們的圖片資源可能是從伺服器動態獲取的,比如很多app所謂的皮膚,這種時候就只能通StateListDrawable

來完成了,各種addState即可。

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

19android:duplicateParentState="true",讓子View跟隨其Parent的狀態,如pressed等。常見的使用場景是某些時候一個按鈕很小,我們想要擴大其點擊區域的時候通常會再給其包裹一層布局,將點擊事件寫到Parent上,這時候如果希望被包裹按鈕的點擊效果對應的Selector繼續生效的話,這時候duplicateParentState就派上用場了。

20、includeFontPadding="false",TextView默認上下是有一定的padding的,有時候我們可能不需要上下這部分留白,加上它即可。

21、Messenger,面試的時候通常都會被問到進程間通信,一般情況下大家都是開始背書,AIDL巴拉巴拉。。有一天在鴻神的博客看到這個,嗯,如他所說,又可以裝一下了。

22、TextView.setError();用於驗證用戶輸入。

23、ViewConfiguration.getScaledTouchSlop();觸發移動事件的最小距離,自定義View處理touch事件的時候,有的時候需要判斷用戶是否真的存在movie,系統提供了這樣的方法。

24、ValueAnimator.reverse(); 順暢的取消動畫效果。

25、ViewStub,有的時候一塊區域需要根據情況顯示不同的布局,通常我們都會通過setVisibility的方法來顯示和隱藏不同的布局,但是這樣默認是全部載入的,用ViewStub可以更好的提升性能。

26、onTrimMemory,在Activity中重寫此方法,會在內存緊張的時候回調(支持多個級別),便於我們主動的進行資源釋放,避免OOM。

27、EditTxt.setImeOptions, 使用EditText彈出軟鍵盤時,修改回車鍵的顯示內容(一直很討厭用回車鍵來交互,所以之前一直不知道這玩意兒)

28、TextView.setCompoundDrawablePadding,代碼設置TextView的drawable padding。

29、ImageSwitcher,可以用來做圖片切換的一個類,類似於幻燈片。

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

31、WeakHashMap,直接使用HashMap有時候會帶來內存溢出的風險,使用WaekHashMap實例化Map。當使用者不再有對象引用的時候,WeakHashMap將自動被移除對應Key值的對象。

---------------------------------------------蒼老師的事業線---------------------------------------------

發現也就我在更新了,結貼,歡迎交流TheFresher的微博,轉載請註明出處。


對於11位手機號,自動添加空格需求,只要添加以下監聽器就可以了,PhoneNumberFormattingTextWatcher 系統本身存在的一個類。

mMobileEt.addTextChangedListener(new PhoneNumberFormattingTextWatcher(Locale.CHINA.getCountry()));


1、android.support.design.widget.TextInputLayout,給EditText帶個套吧⊙▽⊙

2、AndroidMainfest.xml activity的一些標籤,比如android:windowSoftInputMode

& android:label="@string/app_name"

android:windowSoftInputMode="stateHidden" &>

&

&

&

&

&

activity launch後默認隱藏鍵盤,這在activity裡面有EditText等元素又不想一開始就彈出軟鍵盤的情況下有用,在此之前就知道android:name 和android.label這兩個屬性_(:3」∠)_

3、getSystemService函數,獲取各種系統service,而且不用擔心性能問題,都是直接返回各種manager。

4、Parcelable介面

原來受MFC等c++類庫影響,比較習慣繼承serialiabe介面這種方式,但後來知道了Parcelable的實現方式就喜歡上了。

5、android.support.v4.widget.DrawerLayout

原生大方的抽屜控制項。

6、android.support.v7.widget.Toolbar

定製性極強的viewGroup


竟然沒有人說這個:

LocalBroadcastManager

  • You know that the data you are broadcasting won"t leave your app, so don"t need to worry about leaking private data.
  • It is not possible for other applications to send these broadcasts to your app, so you don"t need to worry about having security holes they can exploit.
  • It is more efficient than sending a global broadcast through the system.

簡單來說,就是 LocalBroadcastManager 可以在App的範圍內發廣播和收廣播,不會被global的receiver收到,對數據比較敏感且不用共享的可以用這個。

果然 google support 包裡面藏了太多的好東西。


我也添一些,如有雷同純屬巧合~

1. 通過 WindowManager.addView 在其他app界面添加一個view時,經常會無法顯示,特別在miui,emui固件上,需要指定type為LayoutParams.TYPE_TOAST。

2. View.getLocationOnScreen(new int[]),獲取view在屏幕上的位置

3. Paint.setXfermode(porterDuffXfermode),在ApiDemo裡面有專門的介紹,實現了穿透,疊加,覆蓋等多種繪製效果,非常實用

4. IBinder binder = ServiceManager.getService("wallpaper");

IWallpaperManager wm = IWallpaperManager.Stub.asInterface(binder);

Bundle params = new Bundle();

ParcelFileDescriptor fd = wm.getWallpaper(stub, params);

直接獲取當前系統壁紙的fd,避免壁紙過大造成oom問題。這種方式有適配問題,需注意。

5. 通過View.getDrawingCache()可以獲取截圖,但是需要setDrawingCacheEnabled(true)頻繁使用可能會oom,還有一種方法直接用canvas

Bitmap bm = Bitmap.createBitmap((int) (w * scale), (int) (h*scale), Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas();

canvas.setBitmap(bm);

View.draw(canvas);

return bm;

6. 說到幾個oom,順帶說下有一種偷懶又有效的解決辦法,在manifest上加android:largeHeap="true"

7. 用一個牛逼的來結尾,AccessibilityService。由於強大所以需要手動設置來啟用,各種消息獲取各種狀態攔截,豌豆莢就用ta實現了非root自動安裝。


sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)

可以設置一個最終廣播接收者 resultReceiver。即使有優先順序高的廣播接收者使用了 abortBroadcast() 攔截了廣播,最終的廣播接收著依然可以接收到廣播。

參考:Context | Android Developers(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle)


說幾個簡單但是基礎的吧

selector用這個來做樣式的多態真是沒有太方便了,以前傻傻的自己分析事件來變換

HierarchyViewer這個工具用來了解界面實現方式,找到每個view布局和對應id實在太方便了,還可以配合dumpsys命令用來調試

ListView ViewHolder的使用,雖說現在RecyclerView已經把ViewHolder包含進去了,但是還是要說說這個方法對於復用的意義

moveTaskToBack 看到很多論壇寫模擬home按鍵的方式是用Intent.setAction(Intent.ACTION_MAIN)來實現所謂模擬home鍵的方式(實際上是調用launcher),其實很多場景裡面要這麼做的主要目的就是為了讓當前的APP隱藏而非退出,但是用Intent方法其實並不是那麼優雅,剛才說了這個方法的實質是調用launcher,會導致所有應用全部轉到後台,最近在做Android多任務相關工作,這麼做對於系統開發者和其他應用造成不小的困擾,其實在activity層面調用moveTaskToBack就可以搞定了

setSystemUiVisibility和setStatusBarColor要實現status bar的透明或者顏色用這兩個介面就可以了,透明只需要設置SystemUiVisibility為View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE,顏色的話調用後面那個介面就可以,看到某某雲音樂用系統id status_bar_height高度各種計算,自己繪製來實現對於status bar的染色也是最了

loader和ContentObserver 實現數據於控制機制分離的非常好的結構,Android原生郵件系統使用了大量的這樣的模式,來處理繁雜的郵件相關的信息內容,載入郵件伺服器內容到資料庫以及UI上的顯示更新完全是兩條路


5、View中的isShown()方法,以前都是用view.getVisibility() == View.VISIBLE來判斷的

這個方法是個坑,並不是像描述的那樣,如果view是個 ViewGroup,如果某個子view是不可見的,其他可見,這個方法照樣會返回fasle


AtomicInteger,一個提供原子操作的Integer的類。在Java語言中,++i和i++操作並不是線程安全的,在使用的時候,不可避免的會用到synchronized關鍵字。而AtomicInteger則通過一種線程安全的加減操作介面。這個類在AsyncTask中用到了。


補充一個,listviev.setEmptyview方法。

更新:

1.android.util.Patterns類,提供一些常用的正則表達式

public static final Pattern EMAIL_ADDRESS
= Pattern.compile(
"[a-zA-Z0-9\+\.\_\%\-\+]{1,256}" +
"\@" +
"[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}" +
"(" +
"\." +
"[a-zA-Z0-9][a-zA-Z0-9\-]{0,25}" +
")+"
);

/**
* This pattern is intended for searching for things that look like they
* might be phone numbers in arbitrary text, not for validating whether
* something is in fact a phone number. It will miss many things that
* are legitimate phone numbers.
*
* &

The pattern matches the following:
* & * &Optionally, a + sign followed immediately by one or more digits. Spaces, dots, or dashes
* may follow.
* &Optionally, sets of digits in parentheses, separated by spaces, dots, or dashes.
* &A string starting and ending with a digit, containing digits, spaces, dots, and/or dashes.
* &
*/
public static final Pattern PHONE
= Pattern.compile( // sdd = space, dot, or dash
"(\+[0-9]+[\- \.]*)?" // +&&*
+ "(\([0-9]+\)[\- \.]*)?" // (&)&*
+ "([0-9][0-9\- \.]+[0-9])"); // &&+&

2.讀取簡訊(added in api 19)

Telephony.Sms.Intents.getMessagesFromIntent(intent)

廣播接收器示例:
@Override
public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(intent.getAction(),INTENT_ACTIVITY_RECEIVE_SMS)) {
SmsMessage[] msgs = null;
if (Version.hasKitKat()) {
msgs = Telephony.Sms.Intents.
getMessagesFromIntent(intent);
} else {
Bundle bundle = intent.getExtras();
Object[] object = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[object.length];

for (int i = 0; i &< object.length; i++) { msgs[i] = SmsMessage.createFromPdu((byte[]) object[i]); } } if (msgs != null msgs[0] != null) { onReceiveSms(SMSCodeProvider.getSMSCode(msgs[0], getSmsCodeLenght()));//讀取驗證碼內容 } } } 3、獲取URL參數 final String value = new UrlQuerySanitizer(url).getValue ("key");


Volley,Xutils,Gson~簡直救星~還在苦苦糾結網路操作後台線程回調么?還在想著法子讓自己的應用不會因為幾張圖片OOM么?還在糾結資料庫什麼DBHelper反人類么?朋友,我相信你需要這個。


CountDownTimer


Fragment.instantiate(Context context, String fname, Bundle args);

Arrays.toString();


Canvas的 ClipPath() 方法;

再補充一個監聽主線程是否空閑,在View丟幀的情況下使用,效果立竿見影,在主線程中

Looper.myQueue().addIdleHandler(mIdleHandler)


setUserVisibleHint getUserVisibleHint 判斷fragment是否可見


推薦閱讀:

Android開發中,如何有效解決ScrollView和ListView衝突?
關於 Android,用多個 activity,還是單 activity 配合 fragment?
怎麼可以快速的學會並掌握Android開發?
有哪些開源的採用 Material Design 的 Android 程序呢?
移動APP切圖標準?

TAG:程序員 | 軟體開發 | Android開發 | Java | Android |