自定义View

[TOC]

View基础

  1. getLeft(), getRight(),getTop(),getBottom(),是相对于父view的位置

    view的左边距离父view左边的距离

    view的右边距离父view左边的距离

    view的顶部距离父view的顶部的距离

    view的顶部距离父view的顶部的距离

    点击事件的距离:

触摸点相对于其所在组件坐标系的坐标

event.getX() view自己左边的距离

event.getY() view自己顶部的距离

触摸点相对于屏幕默认坐标系的坐标

event.getRawX()

event.getRawY()

角度增大是逆时针,

颜色值:

1
2
3
int color1 = Color.argb(147,22,33,33);
int color2 = Color.GRAY;
int color3 = 0xffffddaa;

先measure ,然后OnMeasure
在unspacified 默认的 宽/高=默认大小 ,会去判断是否有背景大小

显示布局, 贝塞尔曲线

b(t) = p0 + t(p1 - p0) = (1-t)p0 + tp1 , 0<=t<=1;

一阶的没有控制点

所以三阶是2个控制点,三个点就可以确定了,控制点和结束点,贝塞尔曲线

paint 画线的话 用stroke

for循环耗时 和 减少个for循环进行判断

onMeasure - 》 onSizeChange

Path , 贝塞尔曲线,canvas

1
2
3
4
5
6
7
>mPath.reset(); //这个就相当于重新将画笔放到0,0
>mPath.lineTo(100, 100);
>//相当于 ,但是有一点区别,这个不会重置原来画的界面
>mPath.moveTo(0, 0);
>mPath.lineTo(100, 100);
>对称的时候,用宽度- 那边的位移就可以了
>后面发现中心点没有找对,所以出现了问题

Kotlin:成员变量问题
kotlin 没有了 三目运算 用 if else 来代替

转Int的时候 用 toInt() 来进行转换

Reified 告别class

lateinit var c:String
val e: String by lazy {

​ String()

}

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
kotlin 中成员变量应该一开始就确定,进行初始化

get的修饰范围,随成员变量的属性走
private var c = 1
private get() {
return field;
}
private set(value) {
field = value
}

基本类型:
指定一个值就可以了

lateinit 不能作用在8的基本类型上

roomList?size ?: 0 //当list是空是就返回0

deiliget

运算符:
infix 中缀表达式 关键字 可以不用 DSL 里面使用, 代码可读性会降低

kotlin
jetbrains

readLine

文件操作

if 还可以有返回值

注解就相当于打标签, 注解的本质就是动态代理的实现

注解生成对象是proxy0吗

运行时,可以获取属性或方法,进行修改或调取

依赖注入,

dagger2和butterknife有一定的区别

什么是依赖? 就是一种需要,需要这个对象; 人需要买房子。

依赖倒置: 复习六大基本原则, 能用父类的地方用父类,如果有改变的时候,就要修改原来的源代码, 高层模块不应该有底层的依赖,,细节应该依赖抽象

上层 控制下层,就是依赖倒置了。

抽象约束行为,具体实现行为,

面向抽象编程,面向接口编程, 依赖倒置

控制反转。 person只要关系功能,不关心实现,

依赖-)依赖倒置-》控制反转(父类的应用,传子类对象)

构造方法注入:

set方法注入:

接口注入:

设计模式:就是六大基本原则的体现

工厂设计模式,

Jsr-330 是java的依赖注入的标准

a类型依赖b类型

运行时查找依赖的过程,称为“解析resolving”依赖

如果没找到实例,称该依赖unsatisfied

javax.inject 依赖注入

@Inject 方法,构造器,方法或字段

@Provider<T> 结构 Provider 用于类型T的实例

@Qualifier,定义新注解的时候用到它

@Named 基于String的限定器

@Scope,作用域,某个线程有效,某个范围有效

@Singleton, 注入器实例化一次类型,该注解不被继承

依赖注入只能做到解耦性,

程序员的最高境界,就是解耦 保证代码的健壮 灵活 可维护

Dagger2 : apt技术,生成一些辅助代码,
dagger2是dagger的升级版,是square公司出的第一版,然后dagger2是google工程师fork过去,然后重构了。

dagger2单例的原理

@Inject 标记要依赖的变量 2,标记构造函数,来为标记了@Inject的变量

@Module:提供依赖第三方的,需要提供依赖的构造函数,是三方,提供第三方的依赖

@Provides: 预先提供依赖的对象给标注了@Inject的变量赋值

@Inject 只能标志一个构造方法,编译的时候会报错

构造方法,也是可以的

如果既有inject的也有module,优先使用module的

提供两个一样类型的, 限定符

module也使用限定符,来进行注解

@Qualifier 可以当两个一样类型的时候,可以使用到

@Named就是限定符的一种

scope全局引擎

同一个范围的,对象只会创建一次;使用了范围构造,就只会调用一次了,

提供第三方

注射器也要有个范围, doublecheck双重检测的方式来进行的

mv vm

mvp

Scope 不能放在module 类上面 ,放在provides的方法上面

@Inject 构造方法会生成对应的 factory 就是 类名_Factory

@Inject 成员变量 就会生成 对应的注解器_MembersInjector

@Module && @Provides 注入第三放对象,会生成
类名_方法名大写Factory 的这样的类

具体当在对应的注入类中初始化的时候用到

1
2
3
4
5
6
7
8
//就是注入容器的Builder方法调用,初始化的时候调用

private void initialize(final Builder builder) {

this.getActivityProvider =
DoubleCheck.provider(ActivityModule_GetActivityFactory.create(builder.activityModule));

}

在scope下,让后就通过这些factory进行创建独一的对象

1
2
3
4
5
6
7
8
9
10
11
//就是注入容器的Builder方法调用,初始化的时候调用

private void initialize(final Builder builder) {

this.getActivityProvider =
DoubleCheck.provider(ActivityModule_GetActivityFactory.create(builder.activityModule));

this.homePresenterProvider =
HomePresenter_Factory.create(MembersInjectors.<HomePresenter>noOp());
...
}

``这个符号是强行将不合法的改为合法的

在Kotlin中可以用反引号解决关键字冲突的问题,可以强行将一个不合法的字符变为合法。

cookie

HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话

Android 使用Okhttp/Retrofit持久化cookie的简便方式

1
2
3
4
5
var e: ApiException? = null
局部变量声明
@JvmOverloads //重载的标志
getRetrofit(baseUrl: String, provider: NetProvider? = null)
两个参数的方法竟然可以传一个值

okhttp3 interceptor 原理

Okhttp3 https标准的访问

Okhttp3 websocket

java网络这一块

JAVA基础知识之网络编程——-使用MutilcastSocket实现多点广播

应用层, 传输层, 网络层,网络接口层

Tcp端对端的传输

应用层,表示层,会话层

Seq =0
Seq=0 ack = 1
Seq =1 ack=1

HTTP 的3次握手是准备资源的过程;HTTP 的4次握手是释放资源的过程

Tcp 三次握手:tcp目的是为了通讯 ,客户端和服务端都要确保,能读能写

断开,也可以服务器断开,也可以客户端断开

fin + 1 ack

服务端还有数据没发完,当发完的时候,然后 在发送 服务器端的 fin 数据,所以分两次

http2.0 2015出现的

socket去请求,可以保持这次socket,可以下次拿来使用,如果是connecttion:keep-alive 就是可以进行长连接,通信

spdy google提出来的 okhttp也实现了这个,被http2.0代替了

http2.0,和http.1x想是一个全新的一个协议了。1.x的时代是字符串通信。2.0是二进制通信了

\r\n

读取449行,然后就成功响应了

builder,okhttp有责任链模式
接口设计是否合理

http有一种keepalive connections的机制,可以在传输后仍然保持连接,当客户端需要再次获取数据时,直接使用刚刚空闲下来的连接而不需要再次握手

责任链设计模式

1、开闭原则 对扩展开放,对修改关闭 多使用抽象类和接口
2、里氏代换原则 基类可以被子类替换 使用抽象类继承,不使用具体类继承
3、合成复用原则 要依赖于抽象,不依赖于具体 要针对接口编程,不根据实现编程
4、接口隔离原则 使用多个隔离的接口,比使用单个接口好 建立最小的接口
5、迪米特法原则 一个软件实体应尽可能少地与另一个实体发生相互作用 通过中间类建立联系
6、依赖倒转原则 尽量使用合成/聚合,而不是使用继承 尽量使用合成/聚合,而不是使用继承

单一职责:一个类就干一个事情
里氏替换:能用到父类的地方就用父类(这个指抽象类)
依赖倒置:能用接口的地方就用接口(这个指接口)
开闭原则:对修改关闭,对扩展开放
接口隔离:尽量把接口拆分成多个接口,让接口不那么的臃肿
迪米特(也叫 最小知识):一个实体尽可能少的更另一个实体接触

单一职责和接口隔离,感觉是有点像,但是接口隔离注重接口;单一职责重点值 职责单一
里氏替换和依赖倒置:也差不多,只不过一个是指抽象类,一个指的是接口

序列化


如果传输用serializable
进程之间的通信,传输数据:

AIDL,contentProvide

远程 rpc 也可以数据通信

内核内存共享

xml json protobuf 都是序列化的一个手段,不能叫序列化吧
序列化:将对象或数据结构转换成二进制的过程

反序列化,

谷歌出的序列化方案,可以压缩32位数据,
很多im传输用protobuf来实现的

为什么activity之间是同一个进程为什么还要序列化??

ams是跨进程的。

序列化只对变量进行序列化,针对于对象,不针对方法进行序列化

序列化协议:

  1. 技术层面:是否要跨平台,跨语言,通用性问题
  2. 流行程度:

健壮性:xml json protobuf

成熟度不够

性能:

空间和时间方面:

空间开销:

时间开销:复杂的序列化协议会导致较长的解析时间,这可能会使用序列化和反序列化阶段成为整个系统的瓶颈,

可扩展性/兼容性

安全性/访问限制

Protocol buffers 19000 -19999 不能使用,是保留字段

32,这里是4个字节原因,会压缩32位

压缩算法在里面,压缩算法32位

proto的目录
Base-128 整形可变长编码

rpc 调试 rpc效率优先

protobuf 32位的可以压缩合成一个,几十倍的压缩率,

transient 修饰的不需要进行序列化。静态变量不会进行序列化。
需要一个无参的构造方法

不加入 serialVersionUID ,不好兼容了,如果修改信息了,然后就会又根据类进行反序列化成新的 serialVersionUID了,兼容性可能不好

Externalable 也是实现Seralzible接口,只不过要手动实现里面的方法

.java的文件,jvm,怎么知道是java文件, 也有个魔术,文件头,对象头

objectStream里面,会进行反射 writeObject 可以用于特殊需求

arrayList 中有 wirteObject实现了,但是elmentData进行了序列化,因为elmentData,大部分会为空,所以为空的就不进行序列化,只对有效数据序列化,这是jdk序列化的优化。

序列化的坑

  1. 同一个引用只会写一次,要做一些处理

    oos.wirteUnshare ,或者重置流

  2. 子类实现了序列化,父类实现 serializable

  3. 类的演化,反序列化的时候不会报错,但是会没有值

  4. 枚举类型

  5. 序列化单例对象:打单机游戏什么的可能有需求要存单例对象。

serializable,很多反射,会产生很多中间变量,导致大量的内存碎片,

parcel parcelable,就是打包的意思

parcelable,只是存在内存中,内存中序列化的方案,硬是要写硬盘也可以

parcelable 性能方面

存文件用serializable, 只是跨进程用parcelable

SQLite与SP

binder,的缓冲区是有限制的,一般默认一个进程只有16个binder,

xml:是基于树形结构

操作频繁,文档较小,动态添加,删除节点用DOM解析

js解析html就是dom解析

知识储备

版本问题,

移动端不怎么相关的但是是互联网端的:负载均衡

Keepalives -> okhttp复用池

找姐夫说一下,自己公司现在是个什么状态,听听他的意见,不一定要全听,但是要去提取有用的条件

依赖倒置-》 在构造方法里面直接用

父类的引用 = 子类对象

控制反转-》构造函数或者方法用父类的引用,外面传子类的对象,相当于内部的对象,有外部提供了,不在是自己亲自创建了

毒瘤应用-进程保活

json

writeObject 和 readObject 原理, 时序图很重要

json的网络请求

json是来传输的

json小于100m,数据多的时候用 protobuf

1
JSONObject //基于文档驱动的,会全部加载到内存中

retrofit有默认解析吗?默认是gson解析吗?

文档驱动:就是一次性把文档加入进去

gson基于事件的启动方式, gson,什么时候有隐藏bug了,忘记听了

jackson解析也是基于事件驱动, jackson效率比gson高,配置一下也可以不用一一对应可以进行正常解析

FastJson:有隐藏的bug

切片 , 按照 “\n\t\br” 来进行切片

算法匹配,
词法分析 “{” “}” 这种符号,是词法分析
然后再语法分析
jsonDe

getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。

getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。

具体编码如下:

ArrayList 增删,效率都不高,因为伴随的System.arraycopy这个操作符很低

Kotlin 中 实现 接口 ,没带括号,而抽象类,需要个括号

1
class MyLogiMouse(mouseName: String, override var j: Int) : LogiMouse(mouseName), USBInputDevice

Abstract 类默认是 open的,如果不是抽象类,需要添加open才能被继承

如果方法需要被复写,如果不是abstract的,就需要被添加open

kotlin中属性也能进行复写

接口代码 by 接口代理

当名字相同的时候。

internal 模块内可见

object 就是单例的

伴生对象和静态方法

@JvmStatic 这样java就可以正常的静态方法调用了

@JvmOverloads这个重载方法

jvm函数签名,默认参数和方法重载可以相互转换

在java中看到默认参数相当于重载,

反例就是 remove(Object o) , remove(int i)

字符串很多方法

扩展成员:二次加工

加了个 什么点

fun String.multiply() {}

1
2
3
set(value){
field = value;
}

lazy 前面的变量名字实际就是个傀儡

kotlin 的锁, 怎么数据源排序

()== data class 就是 componentN的调用