Gson 数据解析
0x01 Kotlin Gson 解析 data class 两条黄金法则:
1、 String 必须是可空类型 String?
2、 需要使用默认值,则全部字段都必须给予默认值,以满足kotlin对象有空的构造函数
0x02 手动解析Gson基础字段
1、msg 可空String解析 jsonReader.peek() == JsonToken.NULL
1 | import com.google.gson.Gson |
1、msg 可空String解析 jsonReader.peek() == JsonToken.NULL
1 | import com.google.gson.Gson |
埋点需求,Android App 需要在onResume 和 onPause 方法中计算浏览的时长,同时上报浏览的进度。
浏览进度Rate具体的计算方式的具体过程:
1、在滚动屏幕过程中,通过 textContent?.viewTreeObserver?.addOnScrollChangedListener
来记录屏幕滚动的位置
2、在滚动监听里通过textContent?.getLocationOnScreen(location)
获取在屏幕的具体位置,同时,
计算出visibleHeight = screenHeight - location[1]
当前文本的可见高度
3、当可见高度超过目标的高度,则认为已经全部浏览,rate = 100%
,同时移除滚动监听textContent?.viewTreeObserver?.removeOnScrollChangedListener(mScrollChangeListener)
核心代码如下:
1 | private var totalHeight: Int = 0 |
提供了注册加载更多,和判断是否不足一屏等工具方法
1 | import androidx.recyclerview.widget.GridLayoutManager |
java.lang.AssertionError: Could not delete caches dir
CreateProcess error=206, El nombre del archivo o la extensión es demasiado largo
Caused by: java.lang.AssertionError: Could not delete caches dir YourProjectPath\build\kotlin\compileDebugTestingKotlin
临时解决
打开任务管理器,结束 java.exe 或者 OpenJDK Platform Binary
降级 Android Studio
Notice: This happens with the newer AndroidStudio 4.2.x.
Google hasn’t provide us a fix, so you’ll need to downgrade to an older version which works for you. 4.1.3 seems to be working fine.
Please close other application using ADB:Monitor, DDMS, Eclip
Warning:debug info can be unavailable. Please close other application using ADB:Monitor, DDMS, Eclipse.
方案一:
1 | adb usb |
方案二:
打开任务管理器,结束adb.exe进程。
方案三:
重启 adb 服务
1 | adb kill-server |
能安装apk却无法在Logcat查看log,即使重启Android studio,重启adb服务都无法解决。最后通过重启手机搞定
platform-tools/api/api-versions.xml java.io.IOException: Stream closed
在 android studio 更新到 v2020.3.1 后遇到
1 | cannot load api descriptions from ../Android/android-sdk/platform-tools/api/api-versions.xml java.io.IOException: Stream closed |
问题的原因与类SdkUtils (请参阅the source file)相关。SdkUtils类具有对文件platform-tools/api/api-versions.xml的硬引用,但是在最新的平台工具(31.0.3)中,该文件不再存在。
从platforms/android-31/data/api-versions.xml复制文件到platform-tools/api/api-versions.xml。
如果是CI编译,可以尝试以下脚本:
1 | steps: |
Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager.
升级android sdk api 版本到31,适配android 12 ,遇到这个问题。当前开发环境:
android studio 版本: 2020.3.1
AGP 版本: 4.1.2 (classpath "com.android.tools.build:gradle:4.1.2"
)
SDK 版本
1 | android { |
SDK Manager更新对应版本都正常下载,编译过程出现异常
1 | Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager. |
是 Build Tools 升级之后,DX 变成了 D8。而 AGP 4.x 的版本使用的还是DX。
解决的方案:
1 | change below to your Android SDK path |
将 C:\Users\user\AppData\Local\Android\Sdk\build-tools\31.0.0\d8.bat
改为 dx.bat
将 C:\Users\user\AppData\Local\Android\Sdk\build-tools\31.0.0\lib\d8.jar
改为 dx.jar
PS:也可以尝试升级 AGP 到 7.x
1 | java.lang.IllegalStateException: FragmentManager is already executing transactions |
解决方案
如果在 Fragment 中使用 ViewPager2,那么 FragmentStateAdapter 应该使用 childFragmentManager。将
1 | FragmentStateAdapter viewPagerAdapter = new FragmentStateAdapter(getActivity().getSupportFragmentManager(), titles); |
改为
1 | FragmentStateAdapter viewPagerAdapter = new FragmentStateAdapter(getChildFragmentManager(), titles); |
原因分析:
因为 FragmentStateAdapter 会保存所有 Fragment 实例,当调用 Adapter.notifyDataSetChanged()
方法时,Fragment 并没有走 onCreate
方法。
解决方案:
方案一(这个方法会导致内存泄漏,不推荐)
在调用 notifyDataSetChanged
之前,清空 FragmentStateAdapter 的 Fragment 列表。
方案二
重写 getItemId()
containsItem()
这两个方法,并确保 getItemId()
的值是唯一的。
1 | override fun createViewPagerAdapter(): RecyclerView.Adapter<*> { |
1 | java.lang.IllegalStateException: Design assumption violated. |
解决方案:
如果重写了 getItemId()
containsItem()
这两个方法,确保 getItemId()
的值是唯一的。代码同 0x02
原因分析:
同方向滚动事件被 ViewPager2 拦截了。
解决方案:
采用官方提供的自定义 NestedScrollableHost
来包一层 RecyclerView
1 | import android.content.Context |
对应的 layout 代码:
1 |
|
自定义 NestedRecyclerView
的分发事件通过 requestDisallowInterceptTouchEvent()
方法来限制父布类的拦截事件
1 | public class NestedRecyclerView extends RecyclerView { |
降级,使用 ViewPager 来嵌套 RecyclerView ,可以避免事件冲突,亲测有效。
1 | import android.os.Bundle |
在 Fragment 中使用 ViewPager 的时候,切换 Fragment 导致 ViewPager 无法正确恢复异常
1 | java.lang.IllegalStateException: Fragment no longer exists for key f1: unique id 55efaee5-a65c-4e57-9281-7c8f8f6e4156 |
在这个页面中,内容列表使用 ViewPager 嵌套 Fragment 实现,并和时间选择 Tab 绑定。切换【即将上线】和【播出时间表】Tab,实际是使用 FragmentManager 的 replace 方法,动态切换两个 Fragment,然后就报了上面的异常。
网上流行的解决方案是使用 FragmentPagerAdapter 或者添加
1 |
|
但是这样处理会导致 ViewPager 中的 fragments 全部无法恢复,导致 ViewPager 白屏。
本例中的解决方案是:
在切换【即将上线】和【播出时间表】Tab 时,不使用 FragmentManager 的 replace 方法,而采用动态的 Hide 和 show 方法暂时规避 Fragment 被回收的问题。
1 | java.lang.IllegalArgumentException: Called attach on a child which is not detached: BaseViewHolder{2b241e1 position=12 id=-1, oldPos=-1, pLpos:-1} androidx.recyclerview.widget.RecyclerView{afecb06 VFED..... ......ID 0,0-1080,2055 #7f09236e app:id/recycler_view_xxx}, adapter:com.xxxx.adapter.XxxAdapter@cfc75c7, layout:androidx.recyclerview.widget.LinearLayoutManager@24af7f4, context:com.xxxx.XxxActivity@1ed75e2 |
问题分析
对同一个 position 位置同时进行notifyItemRemoved(position)
和 notifyItemInserted(position)
操作导致。
解决方案
避免同时对同一个位置先 notifyItemRemoved 再 notifyItemInserted,使用 notifyItemChanged。
1 | adapter?.notifyItemChanged(position) |
当RecyclerView属性设置为wrap_content
+maxHeight
时,maxHeight没有效果。
问题分析
当RecyclerView的LayoutManager#isAutoMeasureEnabled()
返回true时,RecyclerView高度取决于children view的布局高度,并非取决于RecyclerView自身的测量高度。
解决方案
因此,我们只需要重写LayoutManager的public void setMeasuredDimension(Rect childrenBounds, int wSpec, int hSpec)
方法即可为RecyclerView设置最大宽高。
1 | recyclerView.layoutManager = object : LinearLayoutManager(context, RecyclerView.VERTICAL, false) { |
作者:猫爸iYao
链接:https://www.jianshu.com/p/0dec79ff70df
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Update your browser to view this website correctly.&npsb;Update my browser now