很多时候所以为的原因,实际上只是表层现象
Context类型不同导致的 Dialog 崩溃
背景:Dialog 中弹出 Dialog,传递的 context 为 activity 的 context。
问题:在部分 MIUI 机型上提示“Permission Denied Activity”,现象上与小米的「后台弹出界面权限」有关。但实际上是在前台弹出。
解决思路:我只看到了后台权限的这个现象,搞了挺久,但是不尽人意,因为理论上不需要申请权限,毕竟都在前台。后来老大过来,debug 发现那台手机在 dialog 初始化时的 context 变成了 contextWrapper。
解决办法:判断 dialog 初始化时的 context 是否为 contextWrapper,如果是则使用 context.baseContext 来获取 activity 的 context。否则直接使用 activity 的 context 即可。
问题机型:Redmi 6 MIUI11 安卓9
各种 dir 配置问题
移步:各种 Android 常用 dir 在 gradle 中的配置方式
SDK 接入耗时问题 :文档阅读不仔细
在接入某个 SDK 的时候遇到了一些麻烦,搞了挺久,被自己坑了
- 一些运行时的错误,是自己将 support 条件写反了导致没有初始化(自己居然没发现,一个劲儿的思维定势去看报错信息,傻了)
- 另外无法正常运行的授权失败的原因是“包名不匹配”,而这在文档的最底部写得清清楚楚,但是我却因为心急而漏看了(捡芝麻丢西瓜)。
!!!要细心啊!!!
异常的加载缓慢问题
原因:
项目里有一个公司自己封装的异步框架,项目越来越大,内部的异步处理的 runnable 也越来越多,以至于未知原因阻塞导致数据一直无法加载。比较奇怪的是只在部分手机上会这样,大概是与线程池的分配有关,没去细纠,用协程替代了。
解题思路:
将项目流程的主要位置使用 log 记录,找出耗时最长的位置再进行判断
一个 ktx 库引用错误问题
移步:More than one file was found with OS independent path ‘META-INF/proguard/coroutines.pro’
一次广告调用时序导致份长耗时问题
背景:
正常逻辑,ActivityA -> pickImage -> return ActivityA -> show image temp and crop(覆盖在 activity 上,但属于 activity 的上层布局)-> done 按钮 -> ActivityA
加了广告后:
ActivityA -> pickImage -> return ActivityA -> show image temp and crop(覆盖在 activity 上,但属于 activity 的上层布局)-> done 按钮 -> Ad activity -> ActivityA
问题复现:不加广告不会有问题、加广告就出现了问题,说明逻辑上本身没有问题。
一番拼命 debug 也没解决,只知道原因是因为需要拿一个crop 的 view 范围,但 view 拿到的 各种 left、right、top 等都是0,大概猜到是没有绘制,但逻辑很是复杂。
最后,老大给了个方案,让 ad 观看完后的事件使用 post 去发送,结果没想到成了,后面分析,是因为 ad 将 ActivityA 覆盖了,导致返回时设置的 view 的相关参数并没有完成绘制,因为 activity 本身也并没绘制完,加上这中间还有一些数据计算操作。
反思:确实是迷,但这过程中我也是有发现并没调用相关 addOnGlobalLayoutListener 回调,但我没能想到activity 本身可能都没初始化完成。经验差距?
Windows 文件被占用
先按标准的快捷键,按出任务管理器,切换到 cpu Tab,底下有个资源监视器。
打开后,会看到一个大大的输入框:“关联的句柄”,输入被占用的文件名的一部分就可以过滤出来了,然后右键结束那个进程即可。Windows 真是糟心。
分析 Activity 的一些启动流程
接手别人项目的时候,遇到奇怪的跳转问题,除了分析其调用逻辑,还得多看看堆栈,才能和逻辑对上。直接打印 activity 堆栈看看吧,或许很有帮助。
adb shell dumpsys activity
怎么分析呢,找包名,找 stack,一个 stack 中有相关的一个或者多个 activity,很好辨别。
Android 包瘦身?
公司的 apk 包很大,大得离谱,去找了下相关瘦身操作才知道,公司实际上已经把这些操作做到极致了,最后怎么解?还是得从不用的库开始,注释代码,少依赖。
美团的这篇文章可以看看:
资源方面一般都是配合 AndResGuard + 7zip 的重新压缩。
这里可以使用 gradle 分析依赖:
./gradlew :app:dependencies
可以输出到某个文件,mac 路径上略有不同,但更方便,但都是用>
./gradlew :app:dependencies > d:out.txt
You must not call setTag() on a view Glide is targeting
在解一个 rv 的图片加载错乱时候,用了 setTag,本来 Glide 会自己去用这种方式解决错位问题,但我们这里只是用来获取 bitmap,so,需要自己设置 tag,但没想到,有个惊喜: You must not call setTag() on a view Glide is targeting
解决办法也很简单,在项目中也找到了,就是在 res/values/ids.xml中自己定义一个 ids,然后使用
setTag(R.id.your_id,"some content")
val some_content = getTag(R.id.your_id)
即可。
Android 设置壁纸
无论动态静态,对于三方应用其实都没有什么尽善尽美的办法,还是官方的主题中心靠谱,代码别处找找即可。
kotlin 协程混淆问题
网上很多:但这种问题,谷歌自己干嘛不解决?
-keep class kotlin.** { *; } -keep class kotlin.Metadata { *; } -dontwarn kotlin.** -keepclassmembers class **$WhenMappings { <fields>; } -keepclassmembers class kotlin.Metadata { public <methods>; } -assumenosideeffects class kotlin.jvm.internal.Intrinsics { static void checkParameterIsNotNull(java.lang.Object, java.lang.String); } -keep class kotlinx.coroutines.android.** {*;} # ServiceLoader support -keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {} -keepnames class kotlinx.coroutines.CoroutineExceptionHandler {} -keepnames class kotlinx.coroutines.android.AndroidExceptionPreHandler {} -keepnames class kotlinx.coroutines.android.AndroidDispatcherFactory {} # Most of volatile fields are updated with AFU and should not be mangled -keepclassmembernames class kotlinx.** { volatile <fields>; }
TabLayout 与 ViewPage联动
可以使用TabLayoutMediator
官方文档:使用 TabLayout 添加标签页
本站由以下主机服务商提供服务支持:
0条评论