工作中在使用Kotlin和日常工作总结了一些小技巧点,不定期更新,这里记录下
1、根据上下文获取Lifecycle对象
/**
* 根据上下文获取Lifecycle对象
*/
fun Context.getLifeCycle(): Lifecycle? {
var context: Context = this
while (true) {
when (context) {
is LifecycleOwner -> return context.lifecycle
!is ContextWrapper -> return null
else -> context = context.baseContext
}
}
}
2、 协程的写法
private val answerScope = CoroutineScope(Job() + Dispatchers.Main)
private val durationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
3、携程计时的写法
durationScope.launch {
repeat(Int.MAX_VALUE) {
delay(1000)
if (lifecycle.currentState == Lifecycle.State.RESUMED) {
durationTime += 1
}
}
}
4、设计模式小结
1、桥接模式
将接口或抽象类组合起来,避免实现类继承或者实现多个接口或抽象类,传入各自的实现运转整个代码,举例带颜色多边形的实现,MVP模式种的P层抽象,
View和ViewGroup间的LayoutParam组合
涉及原则:里氏替换原则,依赖倒置原则
2、外观模式
通过接口对外暴露少量方法,实现类中涉及大量库的协同调用,在所有封装库场景均有涉及
涉及原则:本质上就是接口最少了解原则,即迪米特原则
3、享元模式
就是使用缓存池,利用对象复用提升性能,常见的有Handler的Message机制和哈希表等场景
4、装饰者模式
继承并持有一个抽象类,透明地使用其方法,与代理模式类似,不同的是它更强调对原抽象的扩展而不是完全代理
5、适配器模式
利用代理模式或者融合接口与抽象类,使得原本不相关的一系列接口结合到一个类中,实现这个类的对象能实现多个能力,这个类就是适配器类,
举例就是各种Adapter
6、组合模式
分为透明组合和安全组合,主要用于将类似的对象当作相同的对象处理,透明组合不符合接口隔离原则,所以我们一般使用安全组合,继承同一基类,各自扩展
函数,比如树状结构的根和子节点,View和ViewGroup
涉及原则:里氏替换原则,接口隔离原则
7、代理模式
代码模式分为静态和动态代理,比起装饰者模式,他更强调完全代理,一般不会扩展方法,而动态代理是利用java反射,在运行时生成对象或调用方法,比如
ViewModel的Proxy
8、中介者模式
在多对多场景,使用策略模式,中介对象负责对不同对象的请求经行区别处理,负责整体的决策,比如Activity协调各个控件的交互,控件间不需要耦合,
由Activity同一决策
9、访问者模式
用于被访问数据稳定,需要根据不同的访问者进行不同的处理,并且对所有被访问数据遍历的场景,比如Adapter和ViewHolder,Adapter作为访问者,
不同的Adapter对ViewHolder的处理不同,会对多个ViewHolder进行遍历处理
设计原则:单一职责 违背了迪米特原则(访问者了解了被访问者过多信息)
10、模板方法模式
用于固定流程的场景,实现方式为在抽象类的构造函数中定义各个方法的执行顺序,子类继承后各方法按构造函数中顺序执行,典型的有Activity的生命周期
11、迭代器模式
提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示,主要用于解耦遍历算法和容器间的联系,比如使用Iterator对List进行删除
12、备忘录模式
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态,
例如Activity使用savedInstanceState恢复和保存
13、观察者模式
定义一个被观察者和多个观察者,每当被观察者变化,所有观察者都会得到通知,比如LiveData
14、命令模式
将“行为请求者”与“行为实现者”解耦,将一组行为抽象为对象,实现二者之间的松耦合,Runnable和Thread就是最简单的命令模式
15、责任链模式
一个请求发送到接收者,接收者成连式结构,沿着链式结构传递请求,直到有对象处理请求,最典型的就是View的事件分发
16、状态模式
依据状态的不同,调用同样的方法却有不同的行为。每一个状态都有一个共同的状态基类,状态模式的目的就是在状态改变的时候,行为也跟着改变。
多用于一个对象的行为取决于它的状态,且必须在运行时根据状态改变它的行为。或者一个对象中有大量的操作判断比如if else switch,且依赖于该对象的状态
状态模式与策略模式代码实现基本一致,差异如下
1、策略模式的侧重点是提供不同的方法(策略)。
2、状态模式的行为是由状态来决定,不同状态有不同的行为。
假设我们现在对一个数组从小到大排序,这个时候我们写了两个策略,
一个冒泡排序,一个插入排序。两个策略。结果都能正常排序。所以策略模式的重点是不同的策略上。而状态模式重点在状态上
17、策略模式
对同一问题或方法的不同处理方式单独封装起来,多表现为算法或者功能实现,配置不同的插值器进行不同的处理,多用于算法或者功能实现的抽象实现切换,
比如播放器实现的配置,缓存策略实现的配置
18及19、工厂模式(普通工厂,抽象工厂)
一个用于创建对象的接口,让子类决定实例化哪个类,分为普通工厂和抽象工厂
普通工厂模式:生产具体的产品,创建的产品是类(Class)
抽象工厂模式:生产抽象的产品,创建的产品是接口(Interface)
20、原型模式
由原形实例指定创建对象的种类,并通过拷贝这些原形创建新的对象,注意区分值类型和引用类型
21、Builder构造者模式
将一个复杂对象的构建与对象的参数或部件的创建分离,使得同样的创建过程可以有不同的结果。Kotlin默认参数支持了构造者模式
22、单例模式
确保某一个类只有一个实例,并且自行实例化,向整个系统提供这个唯一实例 需要注意多线程,Kotlin中简单使用可以直接用Object
23、解释器模式
通常用于解析和执行特定的语言表达式或规则,以实现某种特定的功能或行为
IntentFilter类也可以被看作是一个解释器,解释Intent的属性并进行匹配。
面向对象的6大基本原则
1、单一职责 即类和方法尽量细化,实现功能的单一,减少代码耦合
2、开闭原则 类对于扩展是开放的,对于修改时闭合的,好的设计应该避免修改
3、迪米特原则 即最少了解原则,一个类或者对象对外只暴露业务相关的关键接口或者参数
4、接口隔离原则 接口的职责应该单一,避免继承接口后需要实现用不到的方法的情况
5、依赖倒置原则 实现依赖抽象,抽象不依赖实现,高层不直接依赖低层,而是依赖其抽象,即面向抽象编程
6、里氏替换原则 任何使用父类的地方,都可以显式的使用其子类
5、RecyclerView适配器的简单写法
class HomeUnitWritingTechListAdapter(
data: List<WritingTechniques>
) :
BaseQuickAdapter<WritingTechniques, BaseViewHolder>(
R.layout.item_unit_theme_home,
data
) {
override fun convert(
helper: BaseViewHolder,
item: WritingTechniques
) {
}
}
6、自定义View的简单写法
class HomeStudyStatueView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null) :
ConstraintLayout(context, attributeSet) {
private val viewBinding = ItemSentenceBinding.inflate(LayoutInflater.from(context), this, true)
/**
* setData
*/
fun setData(data: String) {
viewBinding.tvSentence.text = data
}
}
7、修改项目的git地址
git remote set-url origin
8、常用adb指令
查看屏幕尺寸 adb shell wm size
刷机指令 adb reboot autodloader
切换分辨率
adb root
adb shell
wm density 280
9、AndroidX升级
/1、第一步:使用AS的Refactor->migrate to AndroidX //会自动替换掉工程现有的support
//2、第二步: 检查自动替换的android x库版本是否正确,替换成上面的稳定版本号
//3、第三步:检查现在的三方依赖库是否是否是Android X, 完成第一步后,build 如果三方依赖库不支持AndroidX,会编译报错。 升级三方库到支持Android X的稳定版本
//4、第四步:升级三方库后,需要检查三方库的api是否有变化,是否有兼容问题,混淆规则是否有变化
10、强制使用依赖库
1、设置全局使用某个库的版本
configurations.all {
resolutionStrategy { force 'androidx.core:core:1.6.0' }
}
11、Fragment获取AcitivityViewModel
activity.isNotNull<AppCompatActivity> {
activityViewModel = ViewModelProvider(it)[TopicCommentViewModel::class.java]
}
12、多参数
int... eventTypes
varage
13、java判空
Objects.requireNonNull
14、进一步查看错误信息
gradlew processDebugManifest --stacktrace