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()