- 獲取Fragment的context:
getActivity().getApplicationContext()或者getActivity()You can use getActivity(), which returns the activity associated with a fragment.The activity is a context (since Activity extends Context).
- 設置TextView的顏色setTextColor()的用法:
setTextColor(0xff999faa);setTextColor(Color.parseColor("#999faa"))
- Android textView 動態設置字體大小,帶單位:
setTextSize(TypedValue.COMPLEX_UNIT_PX,22);
setTextSize(TypedValue.COMPLEX_UNIT_SP,22);
setTextSize(TypedValue.COMPLEX_UNIT_DIP,22);
- 初始化一個ArrayList<>并賦值:
ArrayList<String> list = new ArrayList<String>() {{add("string1"); add("string2"); add("string3");}}
- setBackgroundDrawable和setBackgroundResource的區別:
setBackgroundXXX的用處,設置View背景。
setBackgroundDrawable的參數為Drawable對象。
setBackgroundColor的參數為Color對象,比如說Color.Red為紅色或 Color.rgb(255,0,0)來指定一個紅色
setBackgroundResource的參數為資源ID,比如說R.drawable.icon對于ImageView類有類似 setImageXXX
道理同上,setImageBitmap的參數為Bitmap對象,同時ImageView還支持矩陣對象,比如setImageMatrix的參數為Matrix對象。
- Android延時執行接口:
new Handler().postDelayed(new Runnable(){@Overridepublic void run() {func();}
}, 250);
- 查看Android系統服務命令:
adb shell service list
- Activity有三種基本狀態:
- Active:處于屏幕前景(當前task的棧頂Activity處于Active狀態),同一時刻只能有一個Activity處于Active狀態。
- Paused狀態:處于背景畫面畫面狀態,失去了焦點,但依然是活動狀態。
- Stopped:不可見,但依然保持所有的狀態和內存信息。
- 同一個Service的類在android中可以有多個實例嗎?
不可以。Service的啟動模式決定它不會在系統中存在多個實例,當有新的Intent傳遞過來的時候,android系統會直接使用已經存在的Service實例而不會重新創建,所以在android系統中的Service都是單例的。
但為什么在錘子手機上有好幾個xstate service???
-
android繼承activity和application有什么不同:
初學安卓,看到有些代碼繼承activity,有些繼承application,不知有什么?
Activty是UI界面的抽象,Application是應用程序的抽象。一個Application有若干個Activity組成。一般繼承Application主要是做一些初始化以及獲取全局Context的引用,每個用戶界面都要繼承自Acitivity。 -
Fragment中調用startActivityForResult:
注意要采用fragment的startActivityForResult,而不要通過activity調用,否則activity的onActivityResult回被回調,fragment不會被調用,這樣start和onResult就分離了。
目前還沒有遇到這個問題,先收藏著
徹底搞懂startActivityForResult在FragmentActivity和Fragment中的異同
淺談Android Fragment嵌套使用存在的一些BUG以及解決方法 -
去除字符串中的標點符號
public static String removePunct(String s) {String str = s.replaceAll("[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……& amp;*()——+|{}【】‘;:”“’。,、?|-]", "");str = str.replace("\"", "");return str;
}
- 判斷字符串中是否都是中文字符
public static boolean isChinese(String string) {String regex = "^[\u4E00-\u9FA5]+$";Pattern pattern = Pattern.compile(regex);Matcher match = pattern.matcher(string);return match.matches();}
- 令人厭惡的Bundles
摘錄自Android 中 EventBus 的使用(2):緩存事件
“我在上一篇文章中曾說過,我并不喜歡Android中的Bundle,而且盡量避免使用它們。我不喜歡被象Serializable或者是Parcelable這類對象所約束,尤其是它們還缺少對類型安全的檢查。我的意思是必竟這是Java,而不是Python或者Javascript什么的。我希望我的IDE能夠發現并告訴我這樣的錯誤,如一個組件向另外一個組件發送了一個不是它期望的對象類型。
不要誤會,Intent在進程間通信時還是很有用的,在這種情況下將攜帶的數據序列化成通用格式是合情合理的。但如果僅僅是為了在用戶旋轉了一下屏幕后,讓程序保持原來的狀態,以科學的名義說,有必要非得用這種方法么?沒錯,我說的就是Android提供的處理配置改變的標準模式——在onSaveInstanceState(Bundle bundle)和onRestoreInstanceState(Bundle bundle)中保存和恢復狀態數據。且不提那些荒唐復雜的Fragment生命周期問題,單單是保持運行狀態的這種處理方式就是我最不喜歡的Android開發特點之一。”
剛剛遇到了類似問題:Parcel android.os.Parcel@dbaf03f: Unmarshalling unknown type code 2131625126 at offset 1308 導致了crash
XXXX info = mXXXXList.get(position);
if (info == null) {return;
}
Intent intent = new Intent(XXXXActivity.this, XXXXActivity.class);
intent.putExtra(XXX.KEY_SOUND_INFO, info);if (intent != null) {mXXXX = (XXXX) intent.getSerializableExtra(XXX.KEY_SOUND_INFO);
}
由于Serializable導致的問題,出現幾率比較小,目前還沒找到原因。
- AsyncTask, Loader和Executor…… 拜托!
摘錄自Android 中 EventBus 的使用(3):多線程事件處理
Android中有很多種執行異步操作的方法(指平行于UI線程的)。AsyncTask對于用戶來說是最簡單的一種機制,并且只需要少量的設置代碼即可。然而,它的使用是有局限的,正如Android官方文檔中所描述的:
AsyncTask被設計成為一個工具類,在它內部包含了Thread和Handler,但它本身并不是通用線程框架的一部分。AsyncTask應該盡可能地被用在執行一些較短的操作中(最多幾秒)。如果你需要在線程中執行較長時間的任務,那么建議你直接使用java.util.concurrent包中提供的各種API,如Executor、 ThreadPoolExecutor以及FutureTask。
不過即便是執行短時間的操作也會帶來一些問題,特別是在與Activity/Fragment生命周期有關的地方。由于AsyncTask會持續地運行下去(即使啟動它們的Activity/Fragment已經被銷毀了)。這樣,一旦你在onPostExecute方法中試圖對UI進行更新,那么最終將導致拋出一個IllegalStateException異常。
Android 3.0中引入了Loader API用來解決Activity/Fragment生命周期的問題(它們的確很有效)。Loader API被設計成向Activity/Fragment中以異步方式加載數據。盡管加載數據是一種非常常見的異步操作,但并非唯一一種需要從UI線程中分開的操作。Loader還需要在Activity/Fragment中實現另外一個監聽接口。盡管這么做沒有錯,但我個人并不喜歡這種模式(我的意思是最終你的代碼中會包含許多的回調函數,導致代碼的可讀性變得很差)。最后,Activity和Fragment也并非唯一需要對異步操作分線程的地方。例如如果在Service里,你就不能訪問LoaderManager,所以最終你還是得使用AsyncTask或者java.util.concurrent。
java.util.concurrent包很不錯,我在Android和非Android項目中都可以使用。不過使用時需要對其進行多一點兒配置和管理,不象AsyncTask那么簡單。你需要對ExecutorService進行初始化,管理和監視它的生命周期,并且可能需要跟一些Future對象打交道。
只要使用恰當,AsyncTask、 Loader和Executor都是非常有效的。但在復雜應用中,需要為每個任務選擇合適的工具,最終你可能三種都會用到。這樣你就得維護三種不同的處理并發的框架代碼。
- RelativeLayout布局內組件設置居中
備忘
android:layout_centerVertical="true"
- 設置漸變色的背景
設置背景色可以通過在res/drawable里定義一個xml,如下:
xxx.xml<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><item><shape><gradientandroid:angle="0"android:endColor="#28d5fa"android:startColor="#0083fa"android:type="linear" /></shape></item></layer-list>
引用:
<RelativeLayoutandroid:id="@+id/va_voice_print_step_ll"android:layout_width="match_parent"android:layout_height="149dp"android:background="@drawable/xxx">
</RelativeLayout>
shape:定義形狀(主要包括方形、圓形等);gradient:定義該形狀里面為漸變色填充;startColor:起始顏色;endColor:結束顏色;angle:表示方向角度。(當angle=0時,漸變色是從左向右。 然后逆時針方向轉,當angle=90時為從下往上)。
gradient主要配置起點顏色、終點顏色、中間點的坐標、中間點的顏色、漸變角度(90度為上下漸變,0為左右漸變);
padding主要配置上下左右邊距;
corners節點配置四周園角的半徑;
參考鏈接:Android (shape,gradient)使用總結,android 背景漸變色(shape,gradient)
- 如果在Android中判斷某個線程是否是主線程?
public static boolean isInMainThread() {return Looper.myLooper() == Looper.getMainLooper();
}
- EditText中灰色文字提示
android:hint="請輸入xx"
- 如何查看Activity Task棧的情況
adb shell dumpsys activity activities
adb shell dumpsys activity top
- 打開app對應設置通知中心
public void openNotificationSettings() {try {Intent intent = new Intent();intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName());} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {intent.putExtra("app_package", context.getPackageName());intent.putExtra("app_uid", context.getApplicationInfo().uid);}intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);} catch (Exception e) {e.printStackTrace();}
}
- gradle里面的cached module文件位置
~/.gradle/caches/modules-2/files-2.1/com.ali*
- 判斷app是否在前臺運行
public boolean isAppOnForeground() {// Returns a list of application processes that are running on the// deviceActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);String packageName = getApplicationContext().getPackageName();List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();if (appProcesses == null)return false;for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {// The name of the process that this object is associated with.if (appProcess.processName.equals(packageName)&& appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {return true;}}return false;
}
- Activity內使用Broadcast接收消息
大部分的Broadcast示例都是新建一個class繼承BroadcastReceiver來說明Broadcast的使用,但是這個class中接收到的消息,如何進行后續處理呢?其實大部分情況下是希望在activity中通過Broadcast接收消息,做一些后續的處理工作,而如果在一個新建的繼承自BroadcastReceiver的class中,如何和某個Activity通訊,這是一個悖論,消息發生源傳遞給Broadcast,Broadcast再傳遞給Activity,后一步要采用什么通訊方式呢?為什么不消息發生源不直接發生消息給Activity呢?
由于大部分示例都是在一個新的class中進行,導致我一度認為Broadcast只能寫在class里。后來發現可以通過動態注冊的方式直接new一個BroadcastReceiver的方式,寫在Activity內部,由于BroadcastReceiver在Activity內部,BroadcastReceiver中onReceive()即可操作Activity內數據和控件,實現Activity接受消息的目的。
private BroadcastReceiver mSearchRequestReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {//do somethings}}};@Overridepublic void onResume() {super.onResume();LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);lbm.registerReceiver(mSearchRequestReceiver, new IntentFilter(SEARCH_REQUEST_BROADCAST_ACTION));}@Overrideprotected void onPause() {super.onPause();LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);lbm.unregisterReceiver(mSearchRequestReceiver);}
- 判斷當前線程是否是Ui線程:
public static boolean isMainThread() {return Thread.currentThread() == Looper.getMainLooper().getThread();
}
- Glide.with()使用
with(Context context):使用Application上下文,Glide請求將不受Activity/Fragment生命周期控制。
with(Activity activity):使用Activity作為上下文,Glide的請求會受到Activity生命周期控制。
with(FragmentActivity activity):Glide的請求會受到FragmentActivity生命周期控制。
with(android.app.Fragment fragment):Glide的請求會受到Fragment 生命周期控制。
with(android.support.v4.app.Fragment fragment):Glide的請求會受到Fragment生命周期控制。
- HashMap的遍歷
從上面的分析來看:
a. HashMap的循環,如果既需要key也需要value,直接用
Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {entry.getKey();entry.getValue();
}
即可,foreach簡潔易懂。
b. 如果只是遍歷key而無需value的話,可以直接用
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {// key process
}
- 自定義view常見問題:
Caused by: java.lang.NoSuchMethodException: [class android.content.Context, interface android.util.AttributeSet]
自定義View時,要同時覆寫
public XXXX(Context context) {super(context);
}/*** 自定義View時,如果自定義View有屬性,這個方法一定要覆寫!!** @param context* @param attrs*/
public XXXX(Context context, AttributeSet attrs) {super(context, attrs);
}
- Android 文件鎖 FileLock
Android 中 FileLock 只支持進程間死鎖,同一進程不同線程是無效的。
- 判斷當前應用是否是debug狀態
/*** 判斷當前應用是否是debug狀態*/
public static boolean isApkInDebug(Context context) {try {ApplicationInfo info = context.getApplicationInfo();return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;} catch (Exception e) {return false;}
}
- 查詢10秒鐘前應用使用統計數據并根據最后使用時間進行排序,得到的最后使用的應用
public static String getTopActivityPackageName(@NonNull Context context) {final UsageStatsManager usageStatsManager = (UsageStatsManager)context.getSystemService(Context.USAGE_STATS_SERVICE);if(usageStatsManager == null) {return PACKAGE_NAME_UNKNOWN;}String topActivityPackageName = PACKAGE_NAME_UNKNOWN;long time = System.currentTimeMillis();// 查詢最后十秒鐘使用應用統計數據List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*10, time);// 以最后使用時間為標準進行排序if(usageStatsList != null) {SortedMap<Long,UsageStats> sortedMap = new TreeMap<Long,UsageStats>();for (UsageStats usageStats : usageStatsList) {sortedMap.put(usageStats.getLastTimeUsed(),usageStats);}if(sortedMap.size() != 0) {topActivityPackageName = sortedMap.get(sortedMap.lastKey()).getPackageName();Log.d(TAG,"Top activity package name = " + topActivityPackageName);}}return topActivityPackageName;}```