一、已学习:
HashMap:
多线程:
- 简书:Carson_Ho的博客:https://www.jianshu.com/nb/6977014
Android 消息机制:
基础篇:简书:Carson_Ho的博客
深入篇:
Gityuan
final关键字,为什么匿名内部类使用局部引用要用final?
现在我们知道了,是由于一个拷贝的动作,使得内外两个变量无法实时同步,其中一方修改,另外一方都无法同步修改,因此要加上final限制变量不能修改。
那么为什么要拷贝呢,不拷贝不就没那么多事了吗?
这时候就得考虑一下Java虚拟机的运行时数据区域了,dog变量是位于方法内部的,因此dog是在虚拟机栈上,也就意味着这个变量无法进行共享,匿名内部类 也就无法直接访问,因此只能通过值传递的方式,传递到匿名内部类中
从JDK1.8开始,编译器不要求自由变量一定要声明为final,如果这个变量在后面的使用中没有发生变化,就可以通过编译,Java称这种情况为“effectively final”
RxJava:
- 图文详解 背压策略
- compose操作符:Don’t break the chain: use RxJava’s compose() operator
- RxJava 沉思录:RxJava沉思录
JDK8新特性(在笔记文件夹里有文档):
- Lambda 函数式接口:Function/Predicate/Consumer/Supplier
- Stream :forEach/filter/map/count/limit/skip/concat/两种获取Stream流的方式
- 方法引用 : 通过对象名引用成员变量/类名引用静态成员/super引用父类的成员/this引用本类的成员/类的 构造器引用/数组的构造器引用
Android主流三方库源码分析
数据库框架设计(网易移动架构 -> 数据库架构设计):
- 这个课程讲述的是通过反射的方式,但是反射耗费性能,GreeDao通过freeMarker使用模板的方式,通过使用自身的插件配套相应的freemarker模板生成所需的静态代码,避免了反射等消耗性能的操作。
二、待学习:
内存泄漏:
Gradle:
Github 有关学习:
RxJava:
jsonchao :https://juejin.im/post/5caf0f89f265da038145c66e https://github.com/JsonChao/Awesome-Android-Interview
- GC机制、基本的热修复原理、简单的算法题和智力题,比如冒泡、查找
- JAVA并发、JVM等知识,还有数据库、SQL语句、性能优化、海量Top k
三、第三方库:
- 大图加载方案:
- implementation ‘me.panpf:sketch:2.7.1-rc01’(已使用)
- implementation ‘com.koushikdutta.ion:ion:2.+’
- implementation ‘com.shizhefei:LargeImageView:1.1.0’
- implementation ‘com.github.SherlockGougou:BigImageViewPager:v4_4.1.0’
- implementation ‘com.davemorrissey.labs:subsampling-scale-image-view:3.10.0’
- implementation ‘com.github.piasy:BigImageViewer:1.5.7’
四、Android开发艺术探索
第二章 IPC机制
序列化和反序列化
Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写到数据库或文件中,也可用于网络传输,一般当我们使用缓存cache(内存空间不够有可能会本地存储到硬盘)或远程调用rpc(网络传输)的时候,经常需要让我们的实体类实现Serializable接口,目的就是为了让其可序列化。
当然,序列化后的最终目的是为了反序列化,恢复成原先的Java对象,要不然序列化后干嘛呢,所以序列化后的字节序列都是可以恢复成Java对象的,这个过程就是反序列化。
静态成员变量属于类,不属于对象,所以不会参与序列化过程。对象的跨进程传输本质上都是反序列化的过程,这就是为什么AIDL中的自定义对象都要实现Parcelable的原因。
Binder是Android中的一个类,它继承了IBinder接口。从IPC角度来说,Binder是Android中的一种跨进程通信方式,Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder,该通信方式在Linux中没有;从Android Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、WorkManager等)和ManagerService的桥梁;从Android应用层来说,Binder是客服端和服务端通信的媒介,当bindService的时候,服务端会返回一个包含服务端业务调用的Binder对象,通过这个Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。
Android 中的IPC方式
- 使用Bundle:通过Intent中附加extras来传递信息
- 使用文件共享:通过共享文件的方式来共享数据
- 使用Messenger
- 使用AIDL:通过Binder方式来跨进程通信
- 使用ContentProvider:ContentProvider支持跨进程访问
- 使用Socket:Socket通过网络通信实现数据传递
- BroadcastReceiver:广播是一种被动跨进程通信方式。当某个程序向系统发送广播时,其他的应用程序只能被动地接收广播数据。
第三章 View的事件体系
- 弹性滑动:
- 使用Scroller
- 通过动画
- 使用延时策略
第四章 View的工作原理
View的工作流程主要是指measure、layout、draw这三大流程,即测量、布局、绘制。其中measure确定View的测量宽/高,layout确定View的最终宽/高和四个顶点的位置,而draw则将View绘制到屏幕上。
直接继承View的自定义控件需要重写onMeasure方法并设置wrap_content时的自身大小,否则在布局中使用wrap_content就相当于使用match_parent。
在某些极端情况下,系统可能需要多次measure才能确定最终的测量宽/高,在这种情形下,在onMeasure方法中拿到的测量宽/高可能是不准确的。一个比较好的习惯是在onLayout方法中去获取View的测量宽/高或者最终宽/高。
在onCreate、onStart、onResume中均无法正确得到某个View的宽/高信息,这是因为View的measure过程和Activity的生命周期方法不是同步执行的,因此无法保证Activity执行了onCreate、onStart、onResume时某个View已经测量完毕。
四种方法解决这个问题:
Activity/View#onWindowFocusChanged.
1
2
3
4
5
6
7
8
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
}View.post(runnable)
1
2
3
4
5
6
7view.post(new Runnable() {
public void run() {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
});ViewTreeObserver
1
2
3
4
5
6
7
8view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
});View.measure(int widthMeasureSpec, int heightMeasureSpec)
通过手动对View进行measure来得到View的宽/高。要分情况处理,根据View的LayoutParams来分:
matche_parent无法measure出具体的宽/高,直接放弃。
具体的数值(dp/px),比如宽高都是100px,如下measure:
1
2
3
4int wideMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
view.measure(wideMeasureSpec,heightMeasureSpec);
Log.d(TAG, "measureView, width= " + view.getMeasuredWidth() + " height= " + view.getMeasuredHeight());wrap_content
1
2
3
4int wideMeasureSpec = View.MeasureSpec.makeMeasureSpec((1<<30)-1, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(1<<30)-1, View.MeasureSpec.AT_MOST);
view.measure(wideMeasureSpec,heightMeasureSpec);
Log.d(TAG, "measureView, width= " + view.getMeasuredWidth() + " height= " + view.getMeasuredHeight());
自定义View避免内存泄露:
- 只要针对View中含有线程或者动画的情况:当View退出或者不可见时,记得及时停止该View包含的线程和动画,否则会造成内存泄露的问题。
- 启动或者停止线程/动画的方式:
- a.启动线程/动画:使用view.onAttachedToWindow(),因为该方法的调用时机是当包含View的Activity启动的时刻。
- b.停止线程/动画:使用view.onDetachedFromWindow(),因为该方法调用的时机是当包含View的Activity退出或当前View被remove的时刻。
第五章 理解RemoteViews
- PendingIntent支持三种待定意图:
- 启动Activity
- 启动Service
- 发送广播BroadcastReciever
五、算法与数据结构
一. 玩转数据结构
- 线性结构:
- 数组
- 栈
- 队列
- 链表
- 哈希表
- 等等
- 树结构:
- 二叉树
- 二分搜索树
- AVL
- 红黑树
- Treap
- Splay
- 堆
- Trie
- 线段树(字典树、前缀树)
- K-D树
- 并查集
- 哈夫曼树
- 等等
- 图结构:
- 邻接矩阵
- 邻接表
- 等等
- 大量的算法,以数据结构为基石
- 数组基础:
- 数组最大的优点:快速查询。scores[2]。
- 数组最好应用于“索引有语义”的情况 。
- 但并非所有有语义的索引都适用于数组,比如:身份证号 110126198845345683,需要开辟很大的内存空间。
- 泛型:不可以使用基本数据类型,但是可以使用基本数据类型的包装类。自动拆箱,自动装箱。
- 动态数组、栈、队列:底层依托静态数组,靠resize解决容量问题。
- 链表:真正的动态数据结构。
- 优点:真正的动态,不需要处理固定容量问题。
- 缺点:丧失了随机访问的能力。
极客时间有关链表的题目推荐:
- 单链表反转 (Leetcode-206)
- 链表中环的检测(Leetcode-141)
- 两个有序的链表合并 (Leetcode-21)
- 删除链表倒数第 n 个结点(Leetcode-19)
- 求链表的中间结点(Leetcode-876)
堆:
将n个元素逐个插入到一个空堆中,时间复杂度是O(nlogn)。因为每次添加一个元素,往上堆化的过程是O(logn),n个元素就是O(nlogn)。
heapify的方式,时间复杂度是O(n)。
二. 玩转算法
二分查找法:
- 对于有序序列,才能使用二分查找法
数组:
双指针
双索引技术(滑动窗口)
六、我对问题的理解
GC机制:
首先
七、深入理解Java虚拟机
第一章:走进Java
- 从Android5.0开始,Dalvik虚拟机全面替代ART虚拟机。
八、动脑:移动架构
- TreadLocal的工作原理:
- 定义:ThreadLocal 是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其他线程来说则无法获取到数据。
九、资源索引:
Android系统源码8.0:
网盘下载
链接:https://pan.baidu.com/s/1Vc0rWucfsbse_5TdgtROxw
提取码:wy00
复制这段内容后打开百度网盘手机App,操作更方便哦
在线地址:
阅读源码辅助文档:
优秀技术博客:
Android 学习笔记:
Git可视化练习工具:
练习使用Git的一个开源项目,Github 项目地址:https://github.com/pcottle/learnGitBranching
SQL:
- SQLZOO 是一款很好用的 SQL 练习平台:https://sqlzoo.net/
十. 书籍
- Darren:
- 《正念的奇迹》