View 异步加载
View 异步加载
AndroidX AsyncLayoutInflater
见 [[AsyncLayoutInflater]]
异步加载,协程
View 的异步 Inflate+ 全局缓存 View:加速你的页面
- 方案:布局异步加载,全局缓存
- 存在的问题
- 异步 Inflater,View 使用了 Handler,通过了反射的方式,强制把后台的线程的 Looper 设置为 mainLooper,这样后台线程 new Handler() 方式也能把消息抛到主线程消息队列
- 异步 Inflater,在 View 中使用了 LiveData observe,注意子线程问题
全局缓存 View,View context 的问题,在全局缓存时,为了解决创建 view 的 context 不一定是 activity 导致的问题,或者是 activity 导致的内存泄露问题,对 Context 做封装:新建了 ViewContext 代理类:
- 异步 Inflater,View 使用了 Handler,通过了反射的方式,强制把后台的线程的 Looper 设置为 mainLooper,这样后台线程 new Handler() 方式也能把消息抛到主线程消息队列
- 思路
- View 缓存大小控制,动态更改,LRU?
- View 的状态标记,方便管理 View
- 异步创建 View,提前缓存,减少 View inflate 的耗时
- 内存管理,监听 APP 内存状态,及时释放缓存
- RecyclerView 中的 ViewHolder
- 注意全局创建 View 的 LayoutParams 丢失问题
View的异步Inflate+全局缓存:加速你的页面_文化 & 方法_阿里巴巴文娱技术_InfoQ精选文章
异步加载问题
LiveData observe{} 主线程问题
异步加载的 view 中如果使用的 LiveData,注意线程 observe 问题,需要在主线程 observe。
AssertManager 锁问题
 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
main (blocked)
tid=1 systid=20274 | waiting to lock <0x0052b884> (android.content.res.AssetManager) held by thread 125
Triggered ANR
main (blocked):tid=1 systid=20274 | waiting to lock <0x0052b884> (android.content.res.AssetManager) held by thread 125
at android.content.res.AssetManager.applyStyle(AssetManager.java:1180)
at android.content.res.ResourcesImpl$ThemeImpl.obtainStyledAttributes(ResourcesImpl.java:1355)
at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java:1690)
at android.content.Context.obtainStyledAttributes(Context.java:887)
at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:8556)
at androidx.constraintlayout.widget.ConstraintLayout$LayoutParams.<init>(ConstraintLayout.java:2910)
at androidx.constraintlayout.widget.ConstraintLayout.generateLayoutParams(ConstraintLayout.java:1934)
at androidx.constraintlayout.widget.ConstraintLayout.generateLayoutParams(ConstraintLayout.java:486)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1129)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1130)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088)
at android.view.LayoutInflater.inflate(LayoutInflater.java:686)
at android.view.LayoutInflater.inflate(LayoutInflater.java:538)
at com.zzz.si_category.CategoryFragment.onCreateView(CategoryFragment.kt:119)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3104)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:524)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1817)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1729)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:323)
at com.zzz.si_main.MainTabsActivity.safeAddFragment(MainTabsActivity.kt:1736)
at com.zzz.si_main.MainTabsActivity.initFragments(MainTabsActivity.kt:1775)
at com.zzz.si_main.MainTabsActivity.init$lambda-23(MainTabsActivity.kt:1936)
at com.zzz.si_main.MainTabsActivity.$r8$lambda$qCxjN0u8Pnm_kU3fyYIR-u4a2xQ(MainTabsActivity.kt)
at com.zzz.si_main.MainTabsActivity$$InternalSyntheticLambda$0$41221826ff81153d89c8359c62d585def63fbe1a877da80880266ae3e21e8eef$2.queueIdle$bridge(MainTabsActivity.kt:8)
at android.os.MessageQueue.next(MessageQueue.java:404)
at android.os.Looper.loopOnce(Looper.java:161)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:8115)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:703)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)
本文由作者按照 CC BY 4.0 进行授权