Android开发笔记

2,553 阅读8分钟

如需转载,请标明原文出处: https://juejin.cn/post/6844903789485375496 ,谢谢。

背景

针对平时开发过程中遇到的问题、bug、难点或知识点做一个归纳总结。
不定时更新。

学习地址

1. 网站

玩Android
极客导航
鸿洋公众号推送文章列表

2. 博客

张鸿洋
郭霖
南尘
JessYan - MVPArms、AndroidAutoSize

埋坑

1. Android 5.0 以下

  1. 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

  1. 运行时权限
    敏感权限崩溃,例如拍照、文件读取等。

3. Android 7.0

  1. 文件访问权限 FileProvider
    调用应用外文件崩溃,需要处理FileProvider。

4. Android 8.0

  1. java.lang.IllegalStateException: Only fullscreen activities can request orientation
    透明Activity在8.0设置了方向会崩溃,解决办法:
    A. 不设置;
    B. 清单文件android:screenOrientation="behind"

5. Android 9.0

  1. 前台服务权限,无权限调用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

步骤:

  1. 如果从快捷方式启动APP,那么,无论点多少次,都可以正常弹出activity;
  2. 如果通过返回键退出了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

启动方法:

  1. Android Studio - Terminal - uiautomatorviewer.bat 回车即可打开;
  2. 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 原理解析