1. DatePickerDialog和TimePickerDialog的onDateSet回調會執行兩次的原因及解決方案。
//從源碼中可以看出,tryNotifyDateSet在onStop中也調用了一次,所以會造成執行兩次。
public void onClick(DialogInterface dialog, int which) {
tryNotifyDateSet();
}
@Override
protected void onStop() {
tryNotifyDateSet();
super.onStop();
}
private void tryNotifyDateSet() {
if (mCallBack != null) {
mDatePicker.clearFocus();
mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
}
}
解決方案:
1. 用標誌位
2. 重寫onStop方法
2. 系統的TimePicker設置最大值,用下面反射的方法只能精確到時分,並且兼容性不好,21以後可能不適用。
try {
//分鐘是mMinuteSpinner
Field hourSpinnerField = timePicker.getClass().getDeclaredField("mHourSpinner");
hourSpinnerField.setAccessible(true);
NumberPicker hourSpinner = (NumberPicker) hourSpinnerField.get(timePicker);
hourSpinner.setMaxValue(maxHour);
} catch (Exception e) {
e.printStackTrace();
}
3. Fragment調用startActivityForResult ()不能收到回調onActivityResult()
- 確保用Fragment.startActivityForResult ()
- v4包版本號確認在23.2.0以後
4. 部分機型中調用系統拍照界面,點擊拍照按鈕無反應
- 確定保存文件的路徑存在,如果不存在,有的手機會自動創建,有的手機啥反應也沒有。
5.EditText文本替換
completeVehicleDataEt.setTransformationMethod(new ReplacementTransformationMethod());
ReplacementTransformationMethod replacementTransformationMethod = new ReplacementTransformationMethod() {
@Override
protected char[] getOriginal() {
char[] lower = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
return lower;
}
@Override
protected char[] getReplacement() {
char[] upper = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
return upper;
}
};
6. FragmentTransaction的幾種方法
- commit() //提交到隊列中,待主線程一起執行。如果activity已經執行了onSavedInstanceStatus()會拋異常。
- commitAllowingStateLoss() //如果activity已經執行了onSavedInstanceStatus()不會拋異常,不保證保留狀態
- commitNow() //立刻提交,同步方法,不等待隊列。
- commitNowAllowingStateLoss() //
- executePendingTransactions() //立刻執行隊列裏所有等待的commit()方法
7. AS中Terminal,直接把目錄拖到Terminal窗口快捷切換目錄。
8. 項目中那麼buildscript中的repositories和allprojects的repositories的作用和區別是什麼呢?
- buildscript中的是gradle腳本本身需要的依賴。
- allprojects中的是工程本身需要的依賴。
9. HashMap的序列化:
newSims = new HashMap<>();
in.readMap(newSims , Sim.class.getClassLoader());
dest.writeMap(newSims);
10. 原生TabLayout設置小紅點
//重點:具體的某個tab是第二層view了。但這裏最好try catch,防止兼容性問題。
val tabView = if (tab_layout?.getChildAt(0) != null) tab_layout?.getChildAt(0) as ViewGroup else return
val view = tabView.getChildAt(position) ?: return
11. 捕獲全局異常
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e) {
}
};
12. onBackPressed()和finish的區別,前者在有Fragment的時候是出棧,後者是直接關閉了。
13. 兩個比較有用的Intent Flag
FLAG_ACTIVITY_NO_HISTORY
新打開的activity不在stack中保留,一旦離開,就從stack中移出。
FLAG_ACTIVITY_FORWARD_RESULT
A啓動B,B啓動C,然後C要把結果返回給A,那麼B在啓動C的時候需要加上這個標誌。
14. onUserInteraction()和onUserLeaveHint()
- onUserLeaveHint()
用戶主動離開的時候會回調
- onUserInteraction()
用戶正在與activity交互的時候會回調,如果你想知道用戶用某種方式和你正在運行的activity交互,可以重寫Activity#onUserInteraction()。
所有調用Activity#onUserLeaveHint()的回調都會首先回調Activity#onUserInteraction(),所以點擊跳轉的時候該方法會執行兩次。
15. 線程同步的輔助類
CountDownLatch ,CycliBarrier,Semaphore
CountDownLatch和CyclicBarrier都能夠實現線程之間的等待,只不過它們側重點不同:
CountDownLatch(countDown())一般用於某個線程A等待若干個其他線程執行完任務之後,它才執行;
而CyclicBarrier(await())一般用於一組線程互相等待至某個狀態,然後這一組線程再同時執行;
另外,CountDownLatch是不能夠重用的,而CyclicBarrier是可以重用的。
Semaphore(aquire() , release())其實和鎖有點類似,它一般用於控制對某組資源的訪問權限。
16. 華爲部分機型DialogFragment多出一條線的問題
標題導致的,解決方法:
//第二個參數 0 代表null
setStyle(DialogFragment.STYLE_NO_TITLE , 0);
17. LaunchMode和StartActivityForResult的坑
5.0以後沒問題,5.0以前如下圖:
18. Button默認寬高問題
- button有一個默認的最小寬高,嫌不好看,xml裏面設置android:minWidth=”0dp”,android:minHeight=”0dp”
- drawablePadding可以設置爲負值
19. transformClassesAndResourcesWithSyncLibJarsForRelease
錯誤詳情:
Error:Execution failed for task ':LogEx:transformClassesAndResourcesWithSyncLibJarsForRelease'.
> java.io.IOException: Could not delete path 'F:\ASworkspace\Klicen-Android\LogEx\build\intermediates\bundles\default\libs\android-logging-log4j-1.0.3.jar'.
解決方案:
根據路徑去文件夾中找到該文件,然後刪除,會發現不能刪除,查看是什麼程序在佔用,強制殺掉再刪除。
20. 啓動白屏
//給啓動activity設置下面style
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@mipmap/home_bg</item>
21. 當容器內view的佈局發生變化的時候播放動畫
LayoutTransition transition = container.getLayoutTransition();
transition.enableTransitionType(LayoutTransition.CHANGING);
//子view顯隱時候的動畫
android:animateLayoutChanges="true"
22. ViewPager切換動畫
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
23. 修改Dialog默認button的顏色
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(Color.parseColor("#1C7FFD"));
24. 部分文字點擊變色
//重要,設置了這一句點擊纔有效
tv.setMovementMethod(LinkMovementMethod.getInstance());
textview.setHighlightColor(getResources().getColor(Android.R.color.transparent));
ClickableSpan span = new ClickableSpan() {
@Override
public void onClick(View widget) {
// do sth.
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(getResources().getColor(R.color.link_color));
ds.setUnderlineText(false);
}
};
25. SwitchCompat修改樣式
<style name="AlarmSetting.Switch">
<item name="colorControlActivated">@color/data_content_mileage</item>
<item name="colorSwitchThumbNormal">@color/main_hint_color</item>
<!--關閉時軌跡的顏色-->
<item name="android:colorForeground">@color/data_line</item>
</style>
26. 水波紋相關
27. OkHttp的https設置:
public static OkHttpClient getUnsafeOkHttpClient() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
//0khttp3.0以前這裏是返回null
return new X509Certificate[]{};
}
}};
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
final HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory);
builder.hostnameVerifier(hostnameVerifier);
OkHttpClient okHttpClient = builder.build();
Log.d(TAG, "");
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
28. RecyclerView的4種滾動方式
- scrollBy() 滾動指定像素
- scrollToPosition() 滾動到指定位置,直接顯示,只要顯示了,不管位置在中間或者其他地方
- smoothScrollToPosition() 同上,平滑滾動
- scrollToPositionWithOffset() 指定項在頂部
- public LinearLayoutManager (Context context, int orientation, boolean reverseLayout)
第三個參數可以控制是否倒序顯示
29. RxJava操作符相關
- flatmap() , concatmap() 保證訂閱順序,switchMap()如果新的數據已發出,舊的數據源還沒有訂閱,就取消舊的。
- merge()是合併請求序列,訂閱多次;zip()合併請求序列的數據,只訂閱一次。
- takeFirst,取第一個,不拋異常;first取第一個,拋異常。
- single()/single(Func1()) 數據項/滿足條件的數據項是否只有一個
- ofType(Integer.class) 過濾數據類型
- distinct 去重
- elementAt 取指定元素
- ignoreElements 忽略所有的數據項
- debounce(5, TimeUnit.SECONDS) 在該時間間隔內,如果只有一個數據項,就發送,如果有多個,就忽略
- window操作符會在時間間隔內緩存結果,類似於buffer緩存一個list集合,區別在於window將這個結果集合封裝成了observable
- throttleFirst() 防抖
30. 隱式啓動Service
5.0以後,如果要隱式啓動Service,要加上包名:
intent.setpackage()