1、自定义View ,wrap_content 不处理时和父布局大小一样(占满父布局)。可以查看View的getDefaultSize方法。
2、NestedScrollView 嵌套 竖向的RecyclerView 时,item会被全部创建出来。具体可看 measureChildWithMargins方法,传给RecyclerView的是UNSPECIFIED。
3、RxJava : repeatWhen() 和 retryWhen() 区别就在于什么样的终止事件会触发重订阅:当.repeat()接收到.onCompleted()事件后触发重订阅 ; 当.retry()接收到.onError()事件后触发重订阅;
被返回的Observable>所要发送的事件决定了重订阅是否会发生。
如果发送的是onCompleted或者onError事件,将不会触发重订阅。
相对的,如果它发送onNext事件,则触发重订阅(不管onNext实际上是什么事件)。
这就是为什么使用了通配符作为泛型类型:这仅仅是个通知(next, error或者completed),一个很重要的通知而已。
4、PopUpWindow 中有EditText 时,且 EditText 没有设置inputType , 使用原生输入法输入错误单词,按空格键,提示单词错误时,移动光标到错误的单词中,会导致闪退:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@503232 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:769)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1429)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1203)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1170)
at android.widget.Editor$PinnedPopupWindow.updatePosition(Editor.java:3186)
at android.widget.Editor$PinnedPopupWindow.show(Editor.java:3142)
at android.widget.Editor$SuggestionsPopupWindow.show(Editor.java:3587)
at android.widget.Editor.replace(Editor.java:381)
at android.widget.Editor$3.run(Editor.java:2223)
解决办法是给EditText设置inputType为 textNoSuggestions 。该问题在Android 8上出现。Android 10/11没有出现。
5、如果NestedScrollView里面没有RecyclerView, setOnTouchListener会被调用,setOnScrollChangeListener(NestedScrollView的OnScrollChangeListener)不会被调用;
如果NestedScrollView里面有RecyclerView, setOnScrollChangeListener(NestedScrollView的OnScrollChangeListener)会被调用,setOnTouchListener却不会被调用; 不管NestedScrollView里面有没有RecyclerView,setOnScrollChangeListener(View.OnScrollChangeListener)都会被调用。
6、Android8.0上:
设置了android:windowIsTranslucent 为 true 后,不能设置android:screenOrientation ,否则会报错
java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation。
Activity使用共享元素启动:
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, "sharedName")
ActivityCompat.startActivity(activity, intent, options.toBundle())
启动后如果 setRequestedOrientation 改变Activity的方向,会报错:
java.lang.IllegalStateException: Only fullscreen activities can request orientation
解决方法是给这个Activity设置android:windowIsTranslucent 为 true。这样setRequestedOrientation就不会报错了。
7、ViewPager中使用PhotoView,多只手指左右滑动和缩放图片一起操作时,可出现下面异常:
Fatal Exception: java.lang.IllegalArgumentException:pointerIndex out of range
解决办法是使用 ViewPager2 代替 ViewPager 即可。
8、BottomNavigationView或Viewpager 有些情况选中不了对应item,比如页面刚打开时或者页面不在栈顶(后台),延时执行选中方法方可。
9、静态内部类,在被调用时才会被加载(静态内部类实现单例是懒加载)。
10、fastjson解析Kotlin Data类可能会出现问题:
data类要有默认构造方法,不然报错;
如果data类包含list,这个list的元素会被解析为JsonObject,而不是指定的类型;
11、继承Dialog自定义弹框,要设置弹框没有黑边,通过style样式指定windowBackground为透明和windowIsTranslucent为true是没有效果的,必须通过下面方法实现:
attributes.format = PixelFormat.TRANSPARENT
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
12、Kotlin中的data class不能被继承。若data class类继承一个类,使用Gson解析json为该data class,父类的属性不会被解析。
13、Fragment中观察LiveData:
页面操作相关的在onCreate中观察,owner参数使用this,与Fragment的生命周期对应。如果在onCreateView或onViewCreated里面观察,导致每次页面创建时都会回调一次。
在ViewPager中,切换页面时Fragment会重新创建View。页面显示的数据要在onViewCreated中观察,并且owner参数使用getViewLifecycleOwner,与view的生命周期对应。
14、webView,处理h5调用 window.go(-1)返回上一页,当页面为跟页面时,这时需要关闭 Actiivty。
一种解决方法是让h5调用app提供的接口关闭页面;
另一种方法是打开h5时,先打开一个本地页面,本地页面加载完成后(onPageFinished),在加载h5。然后同样也在onPageFinished判断加载地址是否为本地页面,再根据是否加载过h5,判断是否需要关闭activity。这种方式时无侵入的,对h5友好。注意:要在onPageFinished处理,不能在onPageStarted里面处理,因为在android7.0上不生效。
15、使用liveData保存接口返回的数据时,第一次接口请求成功,liveData有数据,如果第二次接口请求失败,liveData数据变没了,但是界面还会显示旧的数据。所以最好保存一个数据的副本,和界面显示的数据保持一致。
16、使用Html.fromHtml显示文字时,在string.xml中定义字符资源,要使用:包裹,不然没有效果。
%s to your wallet after the order is received]]>
17、kotlin 要让 lambda 能return调用lambda的方法,lambda需要使用inline,不然只能return到lambda(局部返回);
crossinline 的作用是让被标记的lambda表达式不允许非局部返回。
18、js调用APP注入的方法线程不是主线程,在JavaBridge线程。
19、eventBus如果register了,但是没有定义事件接受方法,会报错:
org.greenrobot.eventbus.EventBusException: Subscriber class * and its super classes have no public methods with the @Subscribe annotation
20、sw最小宽度适配是按下匹配的,如果手机是sw为392,资源定义的是sw400,不会匹配到sw400,只会向下找小于sw392的,找不到就使用默认的。
一般以sw360为基础,算出其他尺寸的sw,公式为dp = sw360中的dp * 目标sw / 360
21、android:fontFamily=“sans-serif-medium” 对应Roboto-Medium字体
android:fontFamily="sans-serif" // roboto regular
android:fontFamily="sans-serif-light" // roboto light
android:fontFamily="sans-serif-condensed" // roboto condensed
android:fontFamily="sans-serif-thin" // roboto thin (android 4.2)
android:fontFamily="sans-serif-medium" // roboto medium (android 5.0)
22、观察liveData时,如果liveData里面有值,会立马收到回调。而不是等到有新值时才收到回调。
23、 下载的apk,如果放在getCacheDir里面,在Android7.0以下安装时,因为文件是私有,导致系统安装失败,提示解析包出现问题。放在getExternalCacheDir里面不会出现该问题。
24、beginTransaction.commitNow()是同步提交,commit()是异步提交。使用BottomNavigationView切换Fragment,或者实现类似功能是,最好使用commitNow(),如果使用commit(),在快速切换时可能会出现页面重叠,一个fragment被添加多次。
executePendingTransactions()会将所有pending在队列中还有你新提交的transactions都执行了, 而commitNow()将只会执行你当前要提交的transaction.
所以commitNow()避免你会不小心执行了那些你可能并不想执行的transactions.
不能对要加在back stack中的transaction使用commitNow(), 即addToBackStack()和commitNow()不能同时使用
25、查看签名文件信息:keytool -list -v -keystore .\app.jks
26、点九图不能放着drawable文件下,必须放在drawable-xxhdpi(或者mipmap-xxhpi)等有分辨率的文件下,不然点九图没有效果。
27、RecyclerView里面的itemView使用ConstraintLayout的话,onCreateViewHolder里面inflate布局时,要把parent参数传进去,不然ConstraintLayout的宽度不会撑满。
28、Kotlin foreach中使用return跳出循环需要添加标签才能跳出
29、Application的onCreate方法只在app冷启动的时候才执行。温启动不会执行。
30、popupwindow如果再activity销毁时忘记了关闭,虽不影响app,但会出现windowLeaked异常,在log会打印。
31、如果没有在 manifest 文件中声明 Camera 权限,使用 ACTION_IMAGE_CAPTURE 不需要对 Camera 权限做运行时权限处理,代码正常运行。如果manifest声明了就必须要做权限处理。
32、LiveData的观察回调里面不要使用onBackPressed关闭页面,如果网络很慢,app放到后台后,网络请求完成,再回到前台,在Android8和9的机器上会出现该异常:
Caused by: java.lang.IllegalStateException: FragmentManager is already executing transactions
如果使用onBackPressed(),假如你的Activity有添加管理fragment回退的话,调用该方法是不会退出Activity的.直到Fragment回退栈清空,才会退出Activity。
如果使用finish(),那么就会直接退出Activity。