MVP(loader/dagger/rxjava2)
发表于
|
阅读次数:
MVP概念
- View
视图层,包含各种界面相关功能,例如Activity,Fragment,View,Adapter,专注于交互,一般持有Presenter的引用,或者通过依赖注入(Dagger)方式获得Presenter实例,将非UI逻辑操作委托给Presenter - Presenter
逻辑控制层,充当中间人,隔离View层,Model层,接收View层的数据请求,分发给Model层处理,监听Model处理结果,将结果反馈给View,实项界面的刷新 - Model
封装网络数据请求,本地数据请求,对Presenter提供简单易用的接口 - MVP,MVC区别
- MVP
1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试) - MVP优缺点 可以Mock一个实现了接口Contract.View的View对象便于测试,业务逻辑代码与View的隔离解耦 缺点:View中持有Presenter,Presenter中持有View,增加了复杂度,复杂业务中Presenter的代码会臃肿
- MVC中Model和View直接通信的,View中会包含业务逻辑代码,Controller控制层通常在Activity中实现业务逻辑代理,操作Model,但是不操作View,对View无知,Model数据更新完对视图进行更新,用户得到反馈
- MVC优缺点,逻辑代码在Controller中,模块化,业务逻辑代码更改后,不需要更新View,Model;测试困难,Activity包含业务代码,成为了Controller层,Model,View之间存在耦合
- MVP
Kotlin 入门
导入布局中所有控件属性
1
import kotlinx.android.synthetic.main.<布局>.*
实验模式包含
LayoutContainer`
Parcelable`1
2
3
4
5
6
7
8
9
10
11androidExtensions {
experimental = true
}
import kotlinx.android.extensions.LayoutContainer
class ViewHolder(override val containerView: View) : ViewHolder(containerView), LayoutContainer {
fun setup(title: String) {
itemTitle.text = "Hello World!"
}
}View缓存策略,默认为HASH_MAP,
findViewById()
被调用一次1
2
3
4
5
6
7
8
9
10
11androidExtensions {
defaultCacheImplementation = "HASH_MAP" // also SPARSE_ARRAY, NONE
}
可以通过注解改变策略
@ContainerOptions(cache = CacheImplementation.NO_CACHE)
fun MyActivity.a() {
// findViewById() will be called twice
textView.text = "Hidden view"
textView.visibility = View.INVISIBLE
}Parcelable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import kotlinx.android.parcel.Parcelize
@Parcelize
class User(val firstName: String, val lastName: String, val age: Int): Parcelable
序列化读写
@Parcelize
data class Value(val firstName: String, val lastName: String, val age: Int) : Parcelable {
private companion object : Parceler<User> {
override fun User.write(parcel: Parcel, flags: Int) {
// Custom write implementation
}
override fun create(parcel: Parcel): User {
// Custom read implementation
}
}
}@Parcelize支持类型
自定义序列号映射对象
1
2
3
4
5
6
7
8
9class ExternalClass(val value: Int)
object ExternalClassParceler : Parceler<ExternalClass> {
override fun create(parcel: Parcel) = ExternalClass(parcel.readInt())
override fun ExternalClass.write(parcel: Parcel, flags: Int) {
parcel.writeInt(value)
}
}使用
@TypeParceler @WriteWith
引用自定义序列号映射对象1
2
3
4
5
6
7
8
9
10
11
12// Class-local parceler
@Parcelable
@TypeParceler<ExternalClass, ExternalClassParceler>()
class MyClass(val external: ExternalClass)
// Property-local parceler
@Parcelable
class MyClass(@TypeParceler<ExternalClass, ExternalClassParceler>() val external: ExternalClass)
// Type-local parceler
@Parcelable
class MyClass(val external: @WriteWith<ExternalClassParceler>() ExternalClass)
MVVM
Todo-mvvm-databinding
- Model: 内存,本地,网络数据的实现与获取
- View: 对应Activity,Fragment,负责View的绘制,与用户交互,在xml中编写databinding对model层数据的引用绑定,
ViewModelHolder<VH>
作为非UI的Fragment持有ViewModel,并绑定到Activity的生命周期 - ViewModel: databinding框架绑定ViewModel,ViewModel持有View中引用的变量observable fields,以及数据管理类TasksRepository,数据或属性发生变化时,databinding自动更新UI
优缺点
- 低耦合,ViewModel的逻辑代码可重用性,解决MVP中,View,Presenter相互持有问题,响应界面操作无需由View传递,数据变换也无需Presenter调用View实现,开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。可测试,界面素来是比较难于测试的,而现在测试可以针对ViewModel来写
- ViewModel存在Model的依赖,databinding不方便调试
Android Notes(Performance)
Performance optimization
布局
- 人眼感觉流畅画面的帧数要达到40-60帧每秒
- 在Android中,系统通过VSYNC信号触发对UI的渲染,重绘,需要16ms,其实就是1000ms中显示60帧,1000/60=16.67.如果不能在16ms完成绘制,就会丢帧,例如绘制耗时20ms,在16ms有VSYNC信号时无法绘制,该帧被丢弃,等待下次信号才开始绘制,导致16*2ms 都显示同一帧画面
- 在开发者选项中有Profile GPU Rendering 选中On Screen as bars,中间的绿色横线代表VSYNC时间16ms柱状线包含3个部分
- 蓝色代表测量绘制Display List的时间
- 红色代表OpenGL渲染Display List的时间
- 黄色代表CPU等待GPU处理的时间
Android 6.0
Android Notes(System Info Manager Safety)
Android System Info
- android.os.Build
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22Build.BOARD 主板
Build.BRAND 系统定制商
Build.SUPPORTED_ABIS CPU指令集
Build.DEVICE 设备参数
Build.DISPLAY 显示屏参数
Build.FINGERPRINT 唯一编号
Build.SERIAL 硬件序列号
Build.ID 修订版本
Build.MANUFACTURER 硬件制造商
Build.MODEL 版本
Build.HARDWARE 硬件名
Build.PRODUCT 手机产品名
Build.TAGS Build 标签
Build.TYPE Build 类型
Build.VERSION.CODENAME 开发代号
Build.VERSION.INCREMENTAL 源码控制版本号
Build.VERSION.RELEASE 版本字符串
Build.VERSION.SDK_INT 版本号
// The following properties only make sense for internal engineering builds.
Build.HOST Host值
Build.USER User名
Build.TIME 编译时间
Android Notes(Activity)
Android Notes(SurfaceView)
Android Notes(View)
Android 绘图机制处理
系统屏幕密度,密度值,分辨率对应关系
1
ldpi=120(240*320),mdpi=160(320*480),hdpi=240(480*800),xhdpi=320(720*1280),xxhdpi=480(1080*1980)
独立像素密度(密度无关像素 (dp)在定义 UI 布局时应使用的虚拟像素单位,用于以密度无关方式表示布局维度 或位置)
1
ldpi:mdpi:hdpi:xhdpi:xxhdpi=120:160:240:320:480=0.75px:1px:1.5px:2px:3px=3:4:6:8:12
单位转换
1
2
3
4
5
6
7
8
9
10scale=getResources().getDisplayMetrics().density;
px2dp: pxValue/scale+0.5f;
dp2px: dpValue*scale+0.5f;
fontScale=getResources().getDisplayMetrics().scaledDensity;
px2sp: pxValue/fontScale+0.5f;
sp2px: pxValue*fontScale+0.5f;
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,
getResource().getDisplayMetrics());
Android Notes (ListView Scroller)
Docker 编译Android源码
1 | It is because there is no package cache in the image, you need to run: |
Android Notes (System ADB UI)
Android系统架构
- Android系统分四层:Linux内核层,库和运行时,Framework层和应用层。
- Linux包括硬件驱动,进程管理,安全系统
- Dalvik虚拟机,运行时编译;ART虚拟机安装时编译
- Framework
- ActivityManager
- BackupManager
- Bluetooth
- ContentProviders
- LocationManger
- Map libraries
- MediaPlayer
- NotificationManager
- PackageManager
- ResourceManager
- SearchManager
- SharedPreference
- TelephoneManager
- WidgetProvider
- WindowManager
- ViewSystem
- XMPPService
- 标准库
- Apache HTTP
- OpenGL ES
- Open SSL
- SQLite
- Webkit
- ICU
- Android NDK/SDK APP(解压后包含内容中有)
- AndroidManifeset
- Dalvik Classes
- Resource bundle
- NDK APP中包含JNI lib
Linux 常用快捷键 命令 设置等操作
常用快捷键
- Ctrl+Alt+T 打开终端
- Ctrl+L 清空屏幕(功能相当于命令clear)
- Ctrl+U 剪切文本直到行的起始(可以用于清空行)
- Ctrl+K 剪切文本直到行的末尾
- Ctrl+Y 粘贴最近剪切的文本
- Ctrl+C 杀死当前进程(也可以用来清空当前行)
- Ctrl+D 退出当前Shell(功能相当于命令exit) 或者 删除当前的字符
- Ctrl+A 行首
- Ctrl+E 行尾
- Home/End 行首/行尾
- Ctrl+F 向前移动一个字符
- Ctrl+B 向后移动一个字符
- Ctrl+P 或 Ctrl+N 上下历史记录
- 上下方向键 上下历史记录
- Ctrl+Shift+C 复制
- Ctrl+Shift+V 粘贴
- 还有Tab补全,按住Ctrl键进行块选择.
- 鼠标中键:粘贴(在gnome-terminal中使用”菜单键+P”也是可以粘贴的)