Jetpack源码 之 ViewModel
0. 前言ViewModel作为MVVM中最重要的一层,他的作用就是对数据状态的持有与维护。
根据源码里面的注释,我们可以知道,它在Android中事实上是为了解决一下两个问题:
UI组件间实现数据共享
Activity配置更改重建时保留数据
对于第一条,如果不同VM,那么各个UI组件都需要持有共享数据的引用,这样会带来两个麻烦:
如果新增共享数据,则各个UI组件需要再次声明并初始化新增的共享数据
某个组件对于数据的修改,没办法直接通知其他UI组件,需手动实现观察者模式
对于第二条,如果不使用VM,那么还是可以通过onSaveInstanceState保存的,但是如果数据量比较大,数据的序列化和反序列化都会产生一定的性能开销。
所以我们看ViewModel的源码,就需要从这两个问题入手:
ViewModel是如何解决UI组件间共享数据的
ViewModel是怎么解决重建时保留数据的
1. ViewModel是什么我们直接看下源码:1234567891011121314151617181920212223242526272829303132333435363738394041 ...
Jetpack源码 之 LiveData
Jetpack源码 之 LiveData0. 前言LiveData是Jetpack中一个响应式开发框架,官方文档对它的说明是一种可观察的数据存储器类,具有生命周期感知能力。有点类似于感知生命周期的RxJava。
0.1 用法通常LiveData都是结合着ViewModel使用的,一般都是在ViewModel中创建LiveData:1234567891011121314151617class MvvmViewModel : ViewModel() { // 通过MutableLiveData创建一个可读可写的LiveData // 设置为Private,避免外部对数据直接进行修改,并暴露对外接口,让外部通过接口来修改 private val _count = MutableLiveData(0) // 暴露给外部一个只读的LiveData副本,让外部监听数据通过此LiveData监听 val count: LiveData<Int> get() = _count fun increaseCount() { ...
Jetpack源码 之 Lifecycle
0. 前言0.1 用法Lifecycle可以说是Jetpack中最基础的一个库,他的主要作用就是帮我们实现的生命周期监听。
对于他的用法也很简单,由于我们的Activity(间接通过ComponentActivity实现)、Fragment(直接实现)都已经实现了LifecycleOwner接口,所以我们可以直接在他们中调用getLifecycle()获得到Lifecycle对象,然后调用他的addObserver()将我们自定义的LifecycleObserver传入进入即可。123456789101112131415161718192021222324252627282930313233/* 以Activity为例 */// MainActivityclass MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentV ...
Jetpack入门 之 LiveData的map()和switchMap
LiveData的map()和switchMap官方文档中的介绍在Android Developer官网上,对于map和switchMap的解释是这样的:
map:
Applies a function on the value stored in the LiveData object, and propagates the result downstream.
对存储在 LiveData 对象中的值应用函数,并将结果传播到下游。
switchMap:
applies a function to the value stored in the LiveData object and unwraps and dispatches the result downstream. The function passed to switchMap() must return a LiveData object, as illustrated by the following example:
对存储在 LiveData 对象中的值应用函数,并将结果解封和分派到下游。传递给 sw ...
Android源码之SharedPreferences
SharedPreferences源码分析0. 前言SharedPreferences可以说是Android中最常用的一种存数据到文件的方式。他的数据是以键值对的方式存储在 ~/data/data/包名/shared_prefs 这个文件夹中的。
这个存储框架是非常轻量级的,如果我们需要存一些小数据或者是一个小型的可序列化的Bean实体类的,使用SharedPreferences是最明智的选择。
1. 使用方法1.1 获取SharedPreferences在使用SharedPreferences前,我们得先获取到它。
由于SharedPreferences是Android内置的一个框架,所以我们想要获取到它非常的简单,不需要导入任何依赖,直接写代码就行。下面我们就来介绍下获取对象的三个方式:
1.1.1 Context # getSharedPreferences()首先就是可以说是最常用的方法,通过Context的getSharedPreferences() 方法去获取到SharedPreferences对象。由于是通过Context获取的,所以基本上Android的所有场景我们都 ...
Kotlin入门(四)——类和对象的进阶
Kotlin入门(四)——类和对象的进阶
本章内容包括:
可空性
数据类
密封类
枚举类
0. 前言在上一篇《Kotlin入门(三)——类、对象、接口》
我们只聊到了Kotlin中基本类的写法以及继承,但是我们说过,Kotlin的本质就是解决Java的繁琐,如果Kotlin只有这么简单的话怎么还能被称为Kotlin。
首先我们思考在Java中的几个场景:
在方法中每次都得对传进来的对象进行判空,并且很多时候都会忘记判空或者不知道别人在调用你这个方法的时候到底会不会给空,然后就导致程序空指针异常了
123456void nullTest(Obj obj) { if (obj == null) { return } ...}
每次在Java中写JavaBean的时候,一旦数据变多,就得写一大堆的getter、setter、toString、equals等等方法
123456789101112131415161718192021222324252627282930313233343536373839404 ...
Kotlin入门(三)——类、对象、接口
本章内容包括:
类的基本要素
类的继承结构
修饰符
接口
0. 前言在上一篇的末尾,我们提到了Kotlin的包和导入。
原本我是准备把这篇的内容也放在上一篇的,但是后来一想,这张的内容会很有点多,放进去的话可能会导致上一篇太大了,所以就单独分成一篇了。
在说类之前,我们先来看下一个类的Java版和Kotlin版的对比,这个会一下子就让你对Kotlin感兴趣。
我们现在有一个需求,需要定义一个JavaBean类Person,这个类中包含这个人的姓名、电话号码以及地址。
我们先来看下Java的实现:123456789101112131415161718192021222324252627282930313233343536373839404142434445public class Person { private String firstName; private String lastName; private String telephone; private String address; public Person(String ...
Kotlin入门(二)——基本类型、包
本章内容包括:
kotlin的基本类型
包
类与对象
0. 前言在上篇文章我们涉及到了kotlin的一些最基本的语法内容,并完成了kotlin的HelloWorld。但是上篇我们在谈到类的时候,说了只介绍下最基本的类,于是在这篇,我们就着重看下类和对象。(更新:由于类和对象的内容过多,我会放在下一篇来说这个)
但是在说到类之前,我们先来看下基本类型。
1. kotlin的基本类型在说基本类型之前,我们先提及一个Kotlin的基本定义,也是Kotlin和Java最明显的区别之一:
在kotlin中,所有的东西都是对象那么熟悉Java的同学可能要说了:不对啊,你不是说Kotlin的基础是Java吗,那么Java的基本类型不是对象啊,那Kotlin的基本类型怎么可能不是对象了。
但是事实就是,Kotlin的基本类型,都是对象。
Kotlin的基本类型也被分为了:数字、字符、布尔值、数组与字符串。我们就来逐一谈下。
1.1 数字1.1.1 整型和Java一样,Kotlin也有四种不同大小的整型类型:
类型
大小(比特)
最小值
最大值
Byte
8
-128
127
...
Kotlin入门(一)——基本要素
Kotlin入门(一)——基本要素
本章内容包括:
kotlin的HelloWorld
变量、控制流、函数
包和类(最基础的内容,具体的后面会介绍)
智能转换
0. 前言我之前写过一篇《Kotlin入门》博客,但是一方面是这篇博客写的比较早,写的时候单纯是为了学习anko而写的,所以感觉写的并不好,另一方面,在写的时候只是写了点基础知识,当时也没有系统的学习kotlin。
所以在看完kotlin实战后,就想回过头来写一篇总结博客
写这个主要是为了几个目的:
对于看我博客的人来说有一个更加系统更加全面更加完善的kotlin入门指南。
对于我自己,单纯的看书还是不够好,就写一篇总结博客总结下书本中的知识。
注:由于我之前只会Java,并且目前主要是在做Android开发,所以我的博客更多的会将kotlin与Java进行比较,并且可能会偏向Android开发中的实践。
1. Hello World万恶之源,我们从程序员的第一个程序“Hello World”开始。
我们先来看下kotlin版的Hello World是怎么写的,如果你之前学习过Java,你会立马被kotlin语法的简 ...
Android编译变体
编译流程我们都知道Android编译就是将我们自己写的Java文件编译成了.apk,但是他到底是如何将java编译成.apk的呢?
我们引入一张Google官方的流程图:
我们可以看到,一个APP编译的大致流程就是这样的:
先将项目的源代码编译成dex文件(Android虚拟机可识别的字节码文件,至于为啥不是.class,最根本的原因就是Android并没有直接使用Java的虚拟机。并且单个dex文件可被引用的方法总数被限制为65536,如果我们的项目过于庞大超出这个限制时,可能会被打包成多个dex文件),其中这个源代码除了我们自己写的代码之外还包括我们导入的依赖库的代码;并将其他除源文件之外比如资源文件等等所有文件都转成编译的资源。
APK打包器将dex文件和编译的资源组合成单个APK,不过必须先为APK签名才能将打包的应用安装在设备上。
APK打包器通过调试或者发布密钥库为APK签名:
如果编译的版本是调试版本,打包器会使用调试密钥库为应用签名。AndroidStudio会自动使用调试密钥库配置新项目。
如果编译的版本是最终正式发布版本,则需要你自己提供签名信息,然后生成密钥用于 ...