新建Module
修改library让单个Module运行
Gradle版本
依赖库的版本
# Gradle Version
compile_sdk_version = 28
build_tools_version = 28.0.2
min_sdk_version=16
target_sdk_version=28
version_code=1
version_name=1.0.0
#系统内置库的依赖
support_group=com.android.support
support_version=28.+
#测试依赖
test_version = 2.2.2
这些都是通过网络下载下来的,可以把这些module上传到Maven仓库,给它定义目录结构($support_group),再定义版本号($support_version),就不需要通过本地依赖加载了
记得添加构建依赖
http :业务和基础的架构分离
不明确的时候,就先定义一个面向抽象编程类(如:IRequest)
通过LfHttpServer封装execute()方法
public class LfHttpServer {
protected <T> IResult<T> execute(IRequest request, Map<String,Object> params) {
return HttpHelper.execute(request,params);
}
}
自动测试
//Espresso UI自动化测试框架,测试运行速度很快,它允许应用程序处于静止时操作和断言等
androidTestImplementation('com.android.support.test.espresso:espresso-core:$test_version',{
exclude group:'com.android.support',module:'support-annotations'
})
todo 代码重构(可自定义)
队列
队列:是一种特殊的线性结构,允许在线性结构的前端进行删除/读取操作;允许在线性结构的后端进行插入操作;这种线性结构具有“先进先出”的操作特点:
但是在实际应用中,队列中的元素有可能不是以“进入的顺序”为排序依据的。例如我们将要讲到的PriorityBlockingQueue队列。
● SynchronousQueue:
“是这样 一种阻塞队列,其中每个 put 必须等待一个 take,反之亦然。同步队列没有任何内部容量。翻译一下:这是一个内部没有任何容量的阻塞队列,任何一次插入操作的元素都要等待相对的删除/读取操作,否则进行插入操作的线程就要一直等待,反之亦然。
● ArrayBlockingQueue:
一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。
● LinkedBlockingQueue:
LinkedBlockingQueue是我们在ThreadPoolExecutor线程池中常用的等待队列。它可以指定容量也可以不指定容量。由于它具有“无限容量”的特性,所以我还是将它归入了无限队列的范畴(实际上任何无限容量的队列/栈都是有容量的,这个容量就是Integer.MAX_VALUE)。
LinkedBlockingQueue的实现是基于链表结构,而不是类似ArrayBlockingQueue那样的数组。但实际使用过程中,不需要关心它的内部实现,如果指定了LinkedBlockingQueue的容量大小,那么它反映出来的使用特性就和ArrayBlockingQueue类似了。
● PriorityBlockingQueue
PriorityBlockingQueue是一个按照优先级进行内部元素排序的无限队列。存放在PriorityBlockingQueue中的元素必须实现Comparable接口,这样才能通过实现compareTo()方法进行排序。优先级最高的元素将始终排在队列的头部;PriorityBlockingQueue不会保证优先级一样的元素的排序,也不保证当前队列中除了优先级最高的元素以外的元素,随时处于正确排序的位置。
● LinkedTransferQueue
LinkedTransferQueue也是一个无限队列,它除了具有一般队列的操作特性外(先进先出),还具有一个阻塞特性:LinkedTransferQueue可以由一对生产者/消费者线程进行操作,当消费者将一个新的元素插入队列后,消费者线程将会一直等待,直到某一个消费者线程将这个元素取走,反之亦然。
拒绝任务
当提交给线程池的某一个新任务无法直接被线程池中“核心线程”直接处理,又无法加入等待队列,也无法创建新的线程执行;又或者线程池已经调用shutdown()方法停止了工作;又或者线程池不是处于正常的工作状态;这时候ThreadPoolExecutor线程池会拒绝处理这个任务,触发创建ThreadPoolExecutor线程池时定义的RejectedExecutionHandler接口的实现
● CallerRunsPolicy:
这个拒绝处理器,将直接运行这个任务的run方法。但是,请注意并不是在ThreadPoolExecutor线程池中的线程中运行,而是直接调用这个任务实现的run方法。
● AbortPolicy:
这个处理器,在任务被拒绝后会创建一个RejectedExecutionException异常并抛出。这个处理过程也是ThreadPoolExecutor线程池默认的RejectedExecutionHandler实现。
● DiscardPolicy:
DiscardPolicy处理器,将会默默丢弃这个被拒绝的任务,不会抛出异常,也不会通过其他方式执行这个任务的任何一个方法,更不会出现任何的日志提示。
● DiscardOldestPolicy:
这个处理器很有意思。它会检查当前ThreadPoolExecutor线程池的等待队列。并调用队列的poll()方法,将当前处于等待队列列头的等待任务强行取出,然后再试图将当前被拒绝的任务提交到线程池执行
Executors
https://www.xuanyusong.com/archives/2439
CachedThreadPool(弹性缓存线程池),特点:用newCachedThreadPool()方法创建该线程池对象,创建之初里面一个线程都没有,当execute方法或submit方法向线程池提交任务时,会自动新建线程;如果线程池中有空余线程,则不会新建;这种线程池一般最多情况可以容纳几万个线程,里面的线程空余60s会被回收。
SingleThreadPool(单线程线程池),特点:池中只有一个线程,如果扔5个任务进来,那么有4个任务将排队;作用是保证任务的顺序执行。
FixedThreadPool,特点:固定池子中线程的个数。
ScheduledThreadpool(定时器线程池)
ForkJoinPool,JDK 1.7 引入,根据CPU 把任务分成小模块执行,执行后合并。
补充知识点
什么是泛型
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
泛型的作用
比如大家常用的 ArrayList等,通过注入相应的参数,可承载不同的类和对象,当类型不匹配时会报错,某种程度上提高了编码的安全性。
泛型有哪些使用技巧
泛型接口、类,泛型函数,Class<T>,泛型数组,类型绑定,通配符等。
Java 关于泛型<T> 中字母的规范分类
E — Element,常用在java Collection里,如:List<E>,Iterator<E>,Set<E>
K,V — Key,Value,代表Map的键值对
N — Number,数字
T — Type,类型,如String,Integer等等
这仅仅是一个规范而已,传入其他也不会报错。
序列化与反序列化
https://www.cnblogs.com/xdp-gacl/p/3777987.html
HTTPS
https://www.jb51.net/article/130874.htm
https://www.jianshu.com/p/4a6b731d5c60
OKHTTP 缓存