0%

本文旨在记录学习 Flutter 在 Framework 层面的渲染原理时的所得,通过对整个渲染过程的整理,可以有效的理解 Widget 的行为,高效完成 UI 实现。

UI 编程的两种方式

从 Web 到 Android 和 iOS,大家普遍熟知的便是命令式 UI 编程风格 (Imperative UI),随着近年来 UI 框架的飞速发展,声明式 UI 编程风格 (Declarative UI) 逐步进入大家的视野。Flutter 则采用了声明式 UI 的思想来实现 UI。

Imperative UI

所谓命令式 UI,即在实现 UI 时创建带有各种属性和方法的 UI 实例,如 UIView,随后在 UI 发生变更时调用这个实例对应的方法或属性的 setter 方法来修改。

从下面这样一个例子入手:

uiChanges

阅读全文 »

最近开始学习 JVM,跟着『深入理解 Java 虚拟机』一起趟坑,记下这篇笔记。以下内容都是在 64 位的 Ubuntu 18.04 的环境中进行操作的结果。由于书中写的是 OpenJDK 7 的相关内容,所以先熟悉书中相应版本的内容,之后再研究新版本的特性。

前期准备

首先当然是获取 OpenJDK 的源码,获取源码有两种方式:第一种是直接从官网下载打包好的源码,下载完解压到本地就可以了,但是,这种方式下载,不知道是我没找对地方还是官网真的改的一言难尽,很多超链接都 404 了,所以这种方式不是很推荐,这里还是放上我找到的下载地址;另一种方式就是版本控制工具下载,不过这个版本控制工具不是 Git、SVN 这类比较常见的,而是 Mercurial。以下命令可以安装 Mercurial:

1
sudo apt-get install mercurial

安装好 Mercurial 就可以通过 OpenJDK 的仓库地址将源码拉下来了:

阅读全文 »

动画效果不仅能带来视觉上的享受,还能保证交互的连贯性,使整个 APP 一举一动看上去更加优雅美观。在 Android 系统中,动画主要有两大类,一类是 Animation,即针对单个对象做出的一些效果;另一类是 Transitin,即两个场景或者说两个 UI 界面切换时的效果,可以理解为转场效果。其中 Animation 又可以分为 View Animation、Property Animation、Drawable Animation 和 Physics-based Animation。

在官方之前的文档中,View Animation 被分类为 Tween Animation(补间动画) 和 Frame-by-frame Animation(帧动画),而随着 API 21 中 AnimatedVectorDrawable 以及 Support Library 25.3.0 中 DynamicAnimation 的引入,动画分类也发生了变化。Frame Animation 与 AnimatedVectorDrawable 被归类为 Drawable Animation,Tween Animation 即 View Animation,新增了 Physics-based Animation。本篇文章只记录 View Animation 相关的内容。

阅读全文 »

RXJava操作符——转换类

buffer

Observable 的缓存区,源 Observable 发送出来的对象会进过缓存区,当 buffer 里缓存了一定数量的对象,则将它们以 List 的形式发送出去,当源 Observable 发送出 onCompleted 或 onError 通知时,无论当前 buffer 中的对象数量是否足够都会将这个 buffer 发送出去并且传递 onCompleted 或 onError 通知。

flatmap

将源 Observable 对象转换成多个 Observable 对象并将其展开,再将得到的子项发送出去。由于最终将子项合并到到一个 Observable 对象,所以这些子项的顺序可能是相互交错的。

阅读全文 »

RXJava 操作符——创建类

create

创建一个 Observable 对象,这个操作符接收一个 Observer 对象,可以通过重写 Observe 接口中的方法自行控制 onNext,onError,onComplete 方法调用。create 不会默认在任何特定的调度器上运行。

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
33
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
// 在这里写控制 onNext,onError,onComplete方法的调用逻辑
try {
// 在操作前判断订阅的状态以免 Observable 做无用功
if (!subscriber.isUnsubscribed()) {
for (int i = 0; i < 5; i++) {
System.out.println("emit:" + i);
subscriber.onNext(i);
}
subscriber.onCompleted();
}
} catch (Exception e) {
subscriber.onError(e);
}
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.println("completed");
}

@Override
public void onError(Throwable throwable) {
System.out.println(throwable.getMessage());
}

@Override
public void onNext(Integer integer) {
System.out.println("onNext:" + integer);
}
});
阅读全文 »

RXJava相关术语

Upstream(上游),DownStream(下游)

RXJava 中的数据流由数据源和 0 或多个连续的立即执行的操作或组合操作组成:

1
2
3
source.operator1().operator2().operator3().subscribe(consumer);

source.flatMap(value -> source.operator1().operator2().operator3());

如上,如当前处于operation2,则左侧为upstream,右侧为downstream。

运动中的对象

在 RXJava 中,emission, emits, item, event, signal, data 和 message 都表示沿着流传播的对象。

Backpressure(背压)

当数据流运行在多个线程中,数据流中每一个操作处理的速度可能会不同,如果上游处理速度比下游快,则会造成堵塞。通常表现为由与暂时缓存或需要跳过、抛弃部分数据而增加内存使用。这时可以使用背压策略解决,即当前操作可以告诉上游它可以处理多少事件,在无法预知上游会发送多少事件过来的情况下可以控制内存的使用。

在 RXJava 中,Flowable 专为背压设计并且 Observable 专为无背压操作设计。

阅读全文 »

概览

ConstraintLayout是16年随着Android Studio2.2一起发布的一款布局组件,支持Android2.3及以上的版本,而且从AS2.3开始,新建layout的默认根布局就是ConstraintLayout。ConstraintLayout跟RelativeLayout有点类似,组件的位置根据各兄弟组件及组件与父级之间的相对位置来确定,但是它要比RelativeLayout强大很多,它的出现,应该说是解决了以往开发中过多的布局嵌套带来的卡顿、程序性能不够等问题。与传统的利用XML编辑器编写页面UI不同,AS2.2中的可视化布局编辑器专门针对ConstraintLayout进行了改善,在ConstraintLayout中使用布局编辑器进行控件的拖拽操作和属性调整,比编写XML代码更为简单快速,嗯。。。有点照着UI图绘制高保真原型的味道。

阅读全文 »

Android内置了SQLite数据库,而且可以利用JDBC对数据库进行操作,还提供了一个辅助类SQLiteOpenHelper对SQLite进行了简单的封装,但是一遍一遍的重复调用不仅枯燥而且敲代码的效率也很难上去。所以聪明的人类又想到把数据库底层进一步封装起来,只把操作接口,比如增删改查这一类的暴露给开发者,这样一来,不仅提升了开发效率,而且开发者不需要再花心思去关注底层逻辑实现了。这一类封装了底层数据库的数据库框架又被称为ORM框架,greenDAO就是其中之一。ORM框架有很多,之所以选择学习greenDAO,是综合了广大网友的评估意见,greenDAO确实是杠杠的,其他的框架之后有时间再进行学习。

greenDAO-orm

阅读全文 »

Android中的存储问题,是每个Android开发者都需要面对的一个问题,而且,数据存储应该是一个关键,网上很多说Android有五大存储方式,其中包括SharedPreference、File、Content Provider、SQLite数据库存储和网络存储,不过看API指南中的数据存储并没有包括Content Provider,而且按文档所说的,严格意义上来讲,Content Provider只是用于管理应用的数据访问权限的,是Android的组件之一。当然这不是本文的重点,重点是,Android的存储方式中包括了SQLite数据库存储,所以在学习了SQLite的相关内容之后,记下我认为有必要的内容作为总结,其他的语法语句都可以在网上搜到。

阅读全文 »

remoteconfig

Remote Config是什么?

远程配置(Remote Config)是Firebase的功能之一。开发者可以通过在云端配置键值对来更改APP的一些属性,例如行为和外观。这样的功能也可以通过产品迭代更新来进行变换,但是产品的迭代是一个漫长的过程,少说也要几天。RemoteConfig可以快速实现这一过程,首先在本地设置一个参数名A和一个参数值a,当该参数的值需要改变时,在云端赋予参数名A一个新值b,发布之后,用户在下次打开APP的时候就会发现这个参数的值已经由a变成了b,省去了迭代一个版本的时间。

阅读全文 »