Fighting!

潜行者的沉默

阿里镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
buildscript {
ext.kotlin_version = '1.2.71'
repositories {
// 以下四行代码为阿里gradle 源
maven{ url 'https://maven.aliyun.com/repository/google'}
maven{ url 'https://maven.aliyun.com/repository/gradle-plugin'}
maven{ url 'https://maven.aliyun.com/repository/public'}
maven{ url 'https://maven.aliyun.com/repository/jcenter'}
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

allprojects {
repositories {
// 所有的model 都优先使用阿里源
maven{ url 'https://maven.aliyun.com/repository/google'}
maven{ url 'https://maven.aliyun.com/repository/gradle-plugin'}
maven{ url 'https://maven.aliyun.com/repository/public'}
maven{ url 'https://maven.aliyun.com/repository/jcenter'}
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

事件分发

  1. 事件分发的对象是MotionEvent,通过触摸屏幕和点击按键产生
  2. 事件分发的组件包括Activity,ViewGroup,View以及硬件驱动。
  3. 事件传递的方法,Native通过监听,读取dev/input/eventX文件产生新事件,发送给Java层。经过上面提到的组件,主要通过dispatchTouchEvent(),onInterceptTouchEvent(),onTouchEvent()三个方法传递,拦截和消费
  4. Activity和View没有OnInterceptTouchEvent方法,无需拦截事件
  5. 在调用子View的dispatchTouchEvent时会判断是否设置了onTouchListener,会回调onTouch方法,返回true则为已经消费了,就不会调用onTouchEvent()的方法及内部的OnClick()方法
  6. 处理滑动冲突的方式1.外部拦截:由重写父View在onInterceptTouchEvent()根据业务来判断move事件是否要拦截事件,down和up事件不拦截。2. 内部拦截,父View除了down事件都拦截,然后由子View通过requesDisallowInterceptTouchEvent()来控制父类是否要拦截,或者交给子View处理

模板方法模式

模板方法模式:在模板类中定义算法或任务执行的流程框架,将一些具体步骤延迟到子类中去实现。即可定义出不同的表现类。

项目实例

在项目中订单类型往往很多,订单的处理方式也是别有不同。现在介绍一个用户扫码点餐后,收银接受订单消息的处理流程。首先看一下流程

  1. 用户下单:下单来源:支付宝,微信,口碑等,订单类型:堂食,自提,外卖
  2. 服务端收到下单请求,定义与之对应的消息推送给收银机
  3. 商户在收银机上收到下单消息,进行处理
  4. 服务端收到收银的处理结果,推送消息给用户
  5. 用户收到消息
    上面流程在自动审核消息里就是一个通用的过程,因此可以多这个过程制定一个步骤,具体实现由开发者定义。

整个流程中收银机处理的就是订单消息。由于订单的来源及订单类型的多种多样,也就意味着存在两方面的不同。1. 订单数据:基础数据+扩展数据 2.业务处理不同,不同的订单类型需要有不同的UI透出和额外的特殊操作。因此我们可以定义一个基础的UI操作类,定义出,获取订单数据,填充数据等

四大引用

垃圾回收机制在回收对象的时候,会判断是否有引用指向对象

  1. 强引用
  • 程序中大部分的对象都是强引用,如果一个对象具有一个强引用指向它,那垃圾回收器是不会回收他的,在内存不足的情况,系统宁愿报outOfMemery也不会回收这些对象
  1. 软引用
  • 如果一个对象只具有软引用,那内存充足的情况是不会被回收的,但在系统内存不足的情况,垃圾回收器还是会回收的。在未被回收之前,程序能正常使用该对象。软引用和一个引用队列管理,若软应用被回收,就会将软应用加入的引用队列中
  1. 弱引用
    弱引用和软引用的区别在于,只具有弱引用的对象具有更短的生命周期,当垃圾回收器扫描到弱引用对象时,就会回收掉该对象。无论内存是否充足。回收后同样会将该引用加入到相关联的引用队列中
  2. 虚引用
  • 虚引用顾名思义就是形同虚设,对对象的生命周期毫无影响。一个对象被虚引用指引,就和没有引用一下。会被回收。与软引用和虚引用的区别在于:他必须和引用队列联合使用。唯一目的就是对象被回收的时候收到一个系统通知

HashMap

  1. HashMap是线程不安全的
  2. 允许key和value为null
  3. 不保证存储的有序性
  4. 影响HashMap性能的两个变量,init capacity(16)和loadFactor(0.75),load链表长度,减少Hash
  5. faile-fast机制,不允许迭代遍历时remove,add
  6. 1.7和1.8jdk版本的数据存储结构.Entry,数组+链表。Node,数组+链表/红黑树
  7. 扩容大小2倍,容量为2次幂,方便获取捅数组位置提高效率
  8. HashSet基于HashMap实现,value为object对象

HashTable

  1. 线程安全,synchronize修饰方法
  2. key,value不为null
  3. 不保证有序性
  4. initcapcity(11) loadFactor 0.75
  5. 扩容大小2倍+1,容量为奇数或者素数,使哈希更加均匀

ConcurrentHashMap

  1. 并发容器,多线程下更加高效
  2. key或者value不为null
  3. cas无所操作。inittable初始化.SIZECTl,synchronnize
  4. 扩容,rehash

Android中使用ProtoBuf

简介

Protobuf是一种Google开发的一种格式,这种格式与开发语言无关,与运行平台无关,用于序列化数据结构,并且很容易扩展,可用于通讯协议和数据存储等,类似于XML,json,但是序列化,反序列化,和数据的大小都远远高于其他数据结构。因为他会将具备可读性的key值的信息都进行过滤,转化更加精简的数据。

优势
  1. 数据更加精简
  2. 数据大小是json数据的3~10倍
  3. 压缩性能是可以提升20~100倍
  4. 数据歧义少
  5. 代码自动生成
    注意
    数据大小的减少是。对key值的特殊定义,及数据都转成了16进制。
    性能的提升,主要针对整形,浮点型的优化处理。字符型相对提升

Android打包流程

打包流程包括包含四步骤

  1. 通过aapt工具打包res资源文件,生成R.java,resources.arsc和res文件
  2. 处理.aidl文件,生成对应的java接口文件
  3. 通过java compiler编译R.java, java接口文件,java源文件,生成.class文件
  4. 通过dex命令,将.class文件和第三方库的.class文件处理称classes.dex
  5. 通过apkbuilder工具,将Dex文件,res资源合并成一个APK
  6. 通过jarsinger工具,为APK进行签名
  7. 通过zipalign工具进行apk的对齐优化

自定义Gradle插件

  1. 创建一个module,无论phone还是Android Library,因为后面会删掉大部分文件
  2. 删除module下的文件及文件夹,只保留空的src/main目录及build.gradle文件
  3. 创建groovy文件夹,定义包名。如java项目一样
  4. 创建一个类MyPlugin.groovy
  5. 在build.build中加入groovy引用和用于上传的maven的引用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    apply plugin: 'groovy'
    apply plugin: 'maven'

    dependencies {
    //gradle sdk
    compile gradleApi()
    //groovy sdk
    compile localGroovy()
    }

    repositories {
    mavenCentral()
    }
    group = 'com.zyx.plugin'
    version = '1.0.0'

    uploadArchives {
    repositories {
    mavenDeployer {
    //提交到远程服务器:
    // repository(url: "http://www.xxx.com/repos") {
    // authentication(userName: "admin", password: "admin")
    // }
    //本地的Maven地址设置为D:/repos
    repository(url: uri('/Users/zhengyangxin/StudioProjects/myProject/LibraryCollection/pluginrepos'))
    }
    }

    }
  6. 插件已经编好,接着需要告诉gradle我们定义了哪个插件,需要创建文件src/main/resources/META-INF/gradle-plugins/XXXX.properties, 这里的XXXX就是外部module引用的名称,在这里我们定义为com.zyx.plugin.properties
    1
    apply plugin: 'com.zyx.plugin'
  7. 然后在XXXX.properties指明我们定义的插件
    1
    implementation-class=com.hc.plugin.MyPlugin
  8. 最后可以进行打包一个plugin在本地,通过定义的uploadArchives Task
  9. 在需要的modlue中引用自定义的plugin
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    apply plugin: 'com.zyx.plugin'

    buildscript {
    repositories {
    maven {//本地Maven仓库地址
    url uri('/Users/zhengyangxin/StudioProjects/myProject/LibraryCollection/pluginrepos')
    }
    }
    dependencies {
    //格式为-->group:module:version
    classpath 'com.zyx.plugin:plugin:1.0.0'
    }
    }

Android开源框架 Aoppermission

Aoppermission是基于Aspect实现。实现过程及原理分析。Android的常用Aop有两种方式1.通过JNI Hook,2.静态织入

Acpect基础知识

  1. 注解@Aspect,申明切面标记类
  2. @Pointcut, 定义切点,标记方法
  3. @Befeore 前置通知,切点前执行
  4. @Around 围绕切点执行
  5. @after 后置通知,切点后执行
  6. @AfterReturening,返回返回值,切点返回值
  7. @AfterThrowing ,异常通知,切点抛出异常
  8. 首先需要依赖com.hujiang.aspectjx:gradle-android-plugin-aspectjx,配置好了所需的环境
  9. 通过定义注解,包括NeedPermission,PermissionCanceled,PermissionDenied,三个注解对应这申请权限的三种情况。通过源码看他们的作用域都是Method,保留时间都是一直到运行时期,那就意味着,我们可以通过反射的技术实现想做的,而本项目也恰恰是基于反射和Aspect实现

摘录

纵向关系OOP,横向关系AOP

  1. OOP是面向对象编程,按照单一职责原则会将会定义一个个类,每个类只负责一个责任。当我们要使用这个时会引用他,使他分散在个个模块,到处都有。如日志,埋点等。从对象组织角度来讲,采用的分类方式是类似生物学的方式,以继承为主线
  2. AOP是面向切面编程,我们从横向的的角度去观察这些对象,无需到处调用。这些需要打印日志的地方就是一个切点,AOp会在适当的时机打印
    OOP是将问题划分到某个单个模块里去,而AOP是将把涉及到众多模块的某一类问题进行统一管理。AOP是将这些功能集中起来放到一个地方进行管理。是与业务逻辑进行隔离解耦

实现特定方法的前后执行

  1. 硬编码,在执行方法前添加额外的执行方法
  2. 静态织入,通过AspectJ,通过扫描文件分析代码,找到切点JoinPoint,通过自动生成代码获取方法的各种信息,
  3. JDK动态代理是对接口的代理,CGLib是对类的代理,把被代理的对象的class加载起来修改字节码,修改其字节码生成一个继承被代理对象的子类.通过子类增强功能
0%