如需转载,请标明原文出处: https://juejin.cn/post/6844903789485375496 ,谢谢。
背景
针对平时开发过程中遇到的问题、bug、难点或知识点做一个归纳总结。
不定时更新。
学习地址
1. 网站
2. 博客
张鸿洋
郭霖
南尘
JessYan - MVPArms、AndroidAutoSize
埋坑
1. Android 5.0 以下
- View.getContext()强转Activity崩溃
直接继承 Activity 的 Activity 构造出来的 View.getContext() 返回的是当前 Activity。
但是:当 View 的 Activity 是继承自 AppCompatActivity,并且在 5.0 以下版本的手机上,View.getContext() 得到的并非是 Activity,而是 TintContextWrapper。
参考链接:
View.getContext() 一定返回 Activity 对象么?
每日一问:View.getContext() 一定会返回 Activity 对象么?
View.getContext() 里的小秘密
2. Android 6.0
- 运行时权限
敏感权限崩溃,例如拍照、文件读取等。
3. Android 7.0
- 文件访问权限 FileProvider
调用应用外文件崩溃,需要处理FileProvider。
4. Android 8.0
- java.lang.IllegalStateException: Only fullscreen activities can request orientation
透明Activity在8.0设置了方向会崩溃,解决办法:
A. 不设置;
B. 清单文件android:screenOrientation="behind"。
5. Android 9.0
- 前台服务权限,无权限调用
startForeground(int id, Notification notification)会崩溃
清单文件增加<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
6. 获取View截图没有文字
TextView不能设置singleLine,否则getDrawingCache和view.draw(canvas)无法获取文字。具体原因未知。
7. 根Activity不能设置singleTask
因为MainActivity是根Activity,所以不能在清单文件中设置singleTask,否则按Home键后点击icon启动应用时,不能返回原页面,只显示根Activity。
因为点击icon启动应用本质是Intent打开根Activity,如果设置singleTask会直接清除根Activity上面所有的页面。
如果部分情况需要清除根Activity以上所有页面,可以按以下实现:
/**
* startActivity
*
* @param context context
* @param pageID pageID
*/
public static void startActivity(Context context, int pageID) {
Intent intent = new Intent(context, MainActivity.class);
Bundle bundle = new Bundle();
bundle.putInt(KEY_TYPE, pageID);
intent.putExtra(KEY_BUNDLE, bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
8. Android端RSA加密密文服务端无法解密,服务端密文Android端解密有乱码
Cipher标准问题
服务端使用Cipher cipher = Cipher.getInstance("RSA");
Android端使用Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
参考链接:
解决Android客户端RSA解密出来的明文含有一堆乱码的问题
Android RSA加密 在服务端进行RSA解密不成功的问题
9. 点击通知栏无法打开Activity
步骤:
- 如果从快捷方式启动APP,那么,无论点多少次,都可以正常弹出activity;
- 如果通过返回键退出了APP,那么第一次通知到来可以正常弹出,第二次就没法弹出了。
解决:
启动Activity添加以下代码
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
10. Inten分享文件Intent.ACTION_SEND微信发送没反应
Intent需要设置具体的Type,例如intent.setDataAndType(uri, "video/mp4");
11. Inten分享文件Intent.ACTION_SEND对话框点击没反应
目前发现在小米Redmi 4A / Andrid 6.0.1 / MIUI 8.5.6.0 ,发现是“后台弹出界面”权限问题,允许这个权限可以跳转了,但是在别的小米手机没有复现,而且微信也会出现这个问题,初步怀疑是MIUI系统Bug。
12. 导入aar包报错
报错信息:
ERROR: Unable to resolve dependency for ':app@developDebug/compileClasspath': Failed to transform file 'Unity-release.aar' to match attributes {artifactType=jar}
解决:
最后发现aar包中有文件名含有特殊字符,比如中文。
未完待续
小技巧
1. UiAutomator 查看手机当前页面UI层次Id等信息。可用于AccessibilityService
启动方法:
- Android Studio - Terminal - uiautomatorviewer.bat 回车即可打开;
- SDK路径\tools\bin\uiautomatorviewer.bat 双击即可打开。
2. Android根据路径获取文件信息
例如:根据路径获取音频、视频时长
可使用ContentResolver或MediaMetadataRetriever获取文件信息
/**
* 获取时长
*
* @param path path
* @return duration
*/
public static long getDuration(String path) {
MediaMetadataRetriever mmr = null;
try {
mmr = new MediaMetadataRetriever();
mmr.setDataSource(path);
return Long.parseLong(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
} catch (Exception e) {
// e.printStackTrace();
} finally {
if (mmr != null) {
mmr.release();
}
}
return 0;
}
参考链接:
安卓获取视频语音文件时间长度
ContentResolver 快速查询文件
未完待续
知识点
0. 总结
参考链接:
Android 学习笔记核心篇
1. 模块化开发
参考链接:
Android组件化/模块化开发(一)
Android简单的模块化开发
2. ANR原理、定位及解决
参考链接:
Android ANR traces文件解析
Android ANR ANRWatchDog子线程循环检测
Android ANR DDMS检测
Android ANR:原理分析及解决办法 01
Android ANR:原理分析及解决办法 02
3. App优化
参考链接:
Android App优化, 要怎么做?
Android性能优化来龙去脉总结
4. App安全
参考链接:
Android App安全防范措施的小结
Android App 安全策略
5. 对称加密/非对称加密算法
参考链接:
对称加密和非对称加密介绍和区别
对称加密与非对称加密
6. Android内存
参考链接:
Android App优化之内存优化(序)
Android 内存优化总结&实践
JVM的内存区域划分
Android 内存分哪些区
Java内存的一点理解, 静态方法和实例方法的区别及使用场景
程序计数器(关于java虚拟机内存的那些事)
每日一问:你了解 Java 虚拟机结构么?
每日一问:讲讲 Java 虚拟机的垃圾回收
7. static关键字
参考链接:
Java中的static关键字解析
[Java]static关键字的四种用法
8. 四大组件
参考链接:
Android四大组件(整理相关知识点)
Android面试四大组件基础知识点
四大组件安全
Android组件安全详解
9. 多态
参考链接:
什么是多态?为什么用多态?有什么好处?多态在什么地方用?
多态的好处和弊端
10. 多线程
参考链接:
Android 多线程 — 线程的面试题和答案
Java -- Thread中start和run方法的区别
sleep()和wait()的区别
sleep和wait的区别,以及源码解读
Java多线程学习之wait、notify/notifyAll 详解
线程同步 synchronized 同步代码块 同步方法 同步锁
Java同步锁——lock与synchronized 的区别
volatile关键字小总结
Java线程的6种状态及切换(透彻讲解)
android 线程池使用就是这么简单
11. 屏幕适配
参考链接:
JessYan - 今日头条屏幕适配方案终极版正式发布!
12. Java创建对象的几种方式
参考链接:
Java中创建对象的5种方式
通过Class.newInstance()和Constructor.newInstance()两种反射方法创建对象的异同
13. 引用类型
参考链接:
Android 强、软、弱、虚引用 区别和使用场景
14. 排序算法
参考链接:
十大经典排序算法(动图演示)
15. 外部启动App、H5链接、系统分享列表增加自己的App等
参考链接:
酷炫的外部开启Activity新姿势
16. MVC、MVP、MVVM
参考链接:
Android App的三种架构模式MVC,MVP和MVVM
17. 事件分发
参考链接:
Android中的事件传递和处理机制
重学安卓:学习 View 事件分发,就像外地人上了黑车!
解惑requestDisallowInterceptTouchEvent
TouchEvent事件分发机制全解析
Android事件分发之ACTION_CANCEL机制及作用
面试系列:讲讲 Android的事件分发机制
每日一问:Android 滑动冲突,你们都是怎样处理的
Android事件分发机制详解与实战剖析,一张事件分发流程图,让你彻底搞明白
Android 编程下 Touch 事件的分发和消费机制
Android事件分发机制详解:史上最全面、最易懂
Android手势检测——GestureDetector全面分析
18. Handler
参考链接:
Android Handler机制之总目录
我所理解的Handler
你真的懂Handler吗?Handler问答
Looper.loop为什么不会阻塞掉UI线程?
你知道android的MessageQueue.IdleHandler吗?
19. 多状态管理
参考链接:
十六进制状态管理-就算不去火星种土豆,也请务必掌握的 Android 状态管理最佳实践!
20. RecyclerView
RecyclerView问题汇总
RecyclerView缓存机制(咋复用?)
21. ActivityManagerService(AMS)
AMS在Android起到什么作用,简单的分析下Android的源码
22. View绘制流程
Android View 的绘制流程
Android View绘制流程
自定义View之探索onLayout()、onMeasure()方法及作用
measure之UNSPECIFIED的用途
每日一问:浅谈 onAttachedToWindow 和 onDetachedFromWindow
23. 图片加载
Glide最全解析-郭霖
加载大图片
Android 高清加载巨图方案 拒绝压缩图片
PhotoView 解析
24. 数据结构
数据结构:数组和链表的区别(数组和链表的优缺点 & 数组和链表的适用场景)
数据结构:八大数据结构分类
漫画算法:什么是红黑树?(适合初学红黑树小白简单易懂)
一文读懂HashMap
面试中的HashMap、ConcurrentHashMap和Hashtable,你知道多少?
SparseArray:解析与实现
高级工程师调优秘籍;使用SparseArray代替HashMap
ArrayList的一些常见知识点
源码阅读之ArrayList实现细节
源码阅读之LinkedList实现细节
完全解析Andorid的缓存机制LruCache
java中equals,hashcode和==的区别
Java提高篇——equals()与hashCode()方法详解
Java 深入学习(7) —— Object.hashCode()的返回值与对象内存地址的关系
25. 泛型
<? extends T>和<? super T>
Android:写了这么多代码,你真的理解泛型吗
未完待续
零碎
View.getContext() 一定返回 Activity 对象么? View.getContext() 里的小秘密
全面了解HTTP和HTTPS(开发人员必备)
ButterKnife 原理解析