0%

Flutter 配置

最近尝试进行移动端开发,了解了Flutter框架以及Dart语言,希望能够对其进行深入的探索。

FlutterAndroidIOSWebDesktopDart

Flutter 运行Android和iOS模拟器i

1
2
3
flutter emulators --launch avd_name # Android

open -a Simulator #运行ios模拟器

Flutter

  1. “Everything is a widget” 是指所有代码片段都可以用Widget表示,并非指Flutter只有Widget。有点类似函数第一性,Widget是Flutter的页面构成单位,Style,Animation,Lists,Text,Button…这些都可以用Widget 表示,Widget嵌套是Flutter的应用构建方式。举例来说,并没有一个统一的叫App的作为应用入口,所有的Widget理论上都可以作为应用的入口。Flutter当然也包含其他非Widget的对象。
  2. 组合优于继承。实践中,很少通过继承方式扩展一个Widget。一般都通过组合Widget的方式构建特定的Widget对象。这有点类似React的方式。
Flutter Widgetstateless 不保存状态,用于展示UI,静态文本等stateful 保存状态StatefulWidgetState (setState() 通知Flutter,相关区域需要重新绘制) ConstructorWidget.createState() ConstructormountedinitStatedirty statebuildclean statedisposedidChangeDependenciessetStatedidUpdateState


Docker 学习笔记

使用动机

Docker 容器是一种轻量级的应用部署、运行单元,历经几代发展,今天发现Windows 10 家庭版不再需要依赖Visualbox,只要安装好WSL即可使用,启动和运行均非常便捷,因此想把学习使用的经历记录下来,以便后续回顾。

目标是在本地建立开发所需要的各种依赖,使用最省的资源,提升开发效率。

基本使用命令

搜寻镜像

docker search –no-trunc xxx

no-trunc 的选项可以不截断结果中的文字。比如Description过长,默认会被截断。

下载镜像

docker pull image-name

列举本地镜像

docker image ls

运行镜像

1
2
3
docker run --itd --name *name_of_a_new_container*  -p6379:6379 *image_name* 
#-d表示后台运行
#-p本地映射端口:远程端口

-p端口映射相应说明可以参考这个网站

如果遇到运行时报名字冲突,证明已经创建过相应名字的容器了。此时需要通过start启动容器

1
docker start -a image_name #-a指attach到stdin/stderr,可以在命令行中看到连接后的容器输出

停止docker镜像

1
docker stop image_name

docker rm image_name 删除掉容器,再重建。

查询当前运行的镜像

docker ps 显示运行的镜像

显示所有已经创建的镜像

1
docker ps -a

实战

运行一个redis容器

1
2
3
4
5
$docker pull redis
$docker run -d --name redis-test -p 6379:6379 redis
$docker exec -it redis-test /bin/bash
$root@878972df>redis-cli
#:D

可以通过如下命令看本机端口是不是被打开(状态为LISTENING,windows环境)

1
netstat -na | find "6379"

可以尝试通过redis客户端或者telnet操作下redis

1
telnet localhost 6379 #quit命令退出

运行一个Mysql 容器

mysql容器运行方法与redis大同小异,如果启动失败,比如通过 docker ps -a看到异常终止,则可通过如下命令查看日志:

1
docker logs container_name

比如,我运行mysql失败,产生了如下日志:

2020-12-02 16:14:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.
2020-12-02 16:14:17+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql’
2020-12-02 16:14:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.22-1debian10 started.
2020-12-02 16:14:17+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD

显然,需要提供更多参数以便运行mysql,如日志所述,可以运行如下命令设置一个root密码

1
docker run --name=mysql_server -e MYSQL_ROOT_PASSWORD=12345 -p3306:3306 -p33060:33060 -d mysql

之后,即可通过如下命令登录容器。

3306是经典的mysql端口,其他可用端口可以参考如下链接Mysql Ports Reference

1
2
3
4
5
docker -it mysql_server /bin/bash


----
root@wejfio22> mysql -uroot -p #打开一个mysql shell

今日遗留问题

  • 如何改变容器中的配置,比如更改redis的默认运行port?
  • 数据在容器停止时似乎没有丢失,如果是容器意外退出呢?
  • 已经创建的容器,如果需要改变本地映射端口,应该怎么做?

简介

以下是我在windows环境下,使用Msys2 64 / Mingw64 进行C语言编程的一些笔记。

熟悉C语言,以及熟悉linux编译工具链的原因,是因为大量的语言,比如Dart等,都可以通过C语言进行功能扩展,我希望能够掌握得更深入一些。

II. 改变默认安装路径

一般安装步骤如下

1
2
3
$ ./configure
$ ./make
$ ./make install
1
2
3
4
5
6
7
8
# 一般安装路径都是 /usr/local/bin, 但可以通过设置prefix为其他路径来调整。

## 将编译后的文件安装到$HOME/bin目录
$ ./configure --prefix=$HOME

## 将编译好的文件安装到当前目录的子目录下
$ ./configure --prefix=$PWD/mytest

一般来说,prefix指向的路径应该是全路径而非相对路径,因为编译时会跳转到不同目录,依赖相对路径将导致不稳定的文件生成。

II.安装Clang

1
2
3
4
pacman -S mingw64/mingw-w64-x86_64-clang

$ clang -Wall hello.c -o hello

KISS

Keep It Simple, Stupid.

CACE

Changing Anything Changing Everything.

牵一发动全身原则

e.g. 如果删除一个方法,其他所有的方法均会受影响。

SOLID

SRP

单一职责原则

OCP

开/闭原则

针对方法/类扩展,而不是修改。

LSP

里氏(Liskov) 替换原则

ISP

接口隔离原则

DIP

依赖倒置原则

TDD

测试驱动开发 / 设计

1
2
3
{% katex %}
c = \pm\sqrt{a^2 + b^2}
{% endkatex %}

命令行

1
2
3
4
5
6
7
8
9
10
11
12
13

$dart help

=================================================
analyze Analyze the project's Dart code.
compile Compile Dart to various formats.
create Create a new project.
format Idiomatically format Dart source code.
migrate Perform a null safety migration on a project or package.
pub Work with packages.
run Run a Dart program.
test Run tests in this package.
=================================================

创建Dart命令行工程

1
2
3
4
$dart create -t console-full projectName
$cd projectName
$dart run projectName
$dart compile exe bin/projectName.dart

整数除法

5 ~/ 2 == 2

Null-aware 操作

Operators Examples Descriptions
?. User = UserEntity**?.**user 如果UserEntity == null,User 设置为null,短路操作
?? age == User.age**??**30 如果User.age为空,则返回30作为默认值
??= x = 3;
x ??= 5;
如果x 为空,则将其设置为5,否则不赋值

命名变量参数

Dart通过如下方式支持命名变量参数

1
2
3
4
5
6
7
8

void testFunction( {String message, int code} ) { ... }

//Invokes
testFunction(message: "Hello", code: 111);

//默认情况下,参数命名是可选的,但可以通过引入meta package强制使用Named Parameters调用函数:

函数参数默认值

1
void foo ( int x, [int y=3]) {...}

var, const, final, static 和 dynamic

定义 类型 说明
var keyword 类型通过后期赋值确定,一旦确定类型则类型不可变更,但值可以改变。
const keyword 静态数据,必须在编译时即已经声明,完全不可变,且其不可变定义是传递的,比如 声明一个const数组,则const数组中的每一个值均无法改变。
final keyword 指向数据不可变。只有直接关联的数据是不能被改变的,不可变定义不传递,相对const较弱,近似于java的final
dynamic type Dart所有对象的基类型,多数情况不需要显式的声明使用。
static keyword 用来修饰类的成员,指相应方法在类实例上使用而不是类对象上。近似于java的static。

参考网站

dynamic 可以用在定义类型和定义变量上,但var只能用在定义变量。比如:

1
2
var any = 'String';
dynamic any = 'String';

均是合法的,但

1
Map<String, dynamic> any;

不可以使用var替换。

绘制各种图形

actoragentartifactboundarycardcirclecloudcollectionscomponentcontroldatabaseentityfilefolderframeinterfacelabelnodepackagequeuestackrectanglestorageusecase
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
@startuml
actor actor
agent agent
artifact artifact
boundary boundary
card card
circle circle
cloud cloud
collections collections
component component
control control
database database
entity entity
file file
folder folder
frame frame
interface interface
label label
node node
package package
queue queue
stack stack
rectangle rectangle
storage storage
usecase usecase
@enduml

并且相关图形是可以嵌套的。参考 deployment-diagram

如果需要使用包含空格的图形,可以使用如下方式:

1
rectangle "test with space" as t1 

设置颜色

test
1
rectangle test #red/white

预定义颜色参考
也可以使用类似css #rgb的方式定义颜色
颜色梯度渐变可以通过如下方式设置分隔两个颜色

1
2
3
4
5
//e.g #grey/white 
|,
/,
\,
-

绘制箭头

绘制简单箭头

1
2
3
4
5
@startuml
rectangle a #red
rectangle b
a --> b
@enduml
ab

###增加如下u/d/l/r改变箭头方向

abcde
1
2
3
4
-u->
-d->
-l->
-r->

###控制箭头形状

1
2
3
4
5
6
7
8
9
10
11
@startuml
rectangle a #red
rectangle b
rectangle c
rectangle d

a -[#pink,dashed,thickness=3]u-> b
a -[#black,dotted]d----> c
a -l-> d
a -r-> e
@enduml
abcde

控制箭头线长度

1
a ----> b

简介

本系列是我在熟悉Flutter编程语言时记录的一些笔记,希望通过这些记录,掌握Flutter在移动端的一般开发方法,目标是做出一些自己满意的产品。

Flutter 配置

最近尝试进行移动端开发,了解了Flutter框架以及Dart语言,希望能够对其进行深入的探索。

FlutterAndroidIOSWebDesktopDart

Flutter

  1. “Everything is a widget” 是指所有代码片段都可以用Widget表示,并非指Flutter只有Widget。有点类似函数第一性,Widget是Flutter的页面构成单位,Style,Animation,Lists,Text,Button…这些都可以用Widget 表示,Widget嵌套是Flutter的应用构建方式。举例来说,并没有一个统一的叫App的作为应用入口,所有的Widget理论上都可以作为应用的入口。Flutter当然也包含其他非Widget的对象。
  2. 组合优于继承。实践中,很少通过继承方式扩展一个Widget。一般都通过组合Widget的方式构建特定的Widget对象。这有点类似React的方式。
Flutter WidgetstatelessstatefulStatefulWidgetState (setState() to info Flutter redraw)

StateFul对象

ConstructorWidget.createState()
ConstructormountedinitStatedirty statebuildclean statedisposedidChangeDependenciessetStatedidUpdateState

Application Style

Flutter StyleMaterial Design ( Google )Cupertion (IOS Style, less widgets)

Widget类型

Flutter WidgetsLayoutRowColumnScaffoldStackAnimationsFadeInPhoteStructuresButtonToastMenuDrawerStyleTextStyleColorPaddingPosition and AlignmentCenterPadding

每一个Widget均提供build 方法,并且该方法均需返回一个Widget对象。

StateFulWidget的build方法由State对象提供,通过*createState()*方法建立。StateFulWidget的伴随对象State是可以改变的,但StateFulWidget自身与StateLess对象一样,是不可变的(Immutable)。

Widget的build方法以及BuildContext对象

1
Widget build(BuildContext context) 

BuildContext由Flutter框架构建,在其调用build方法时传入。

State对象的setState方法

setState接受一个VoidCallback函数对象作为参数,在调用时将会依照配置重新调用所有依赖对象的buid方法完成重绘。注意,相关数据准备应该在重绘开始前完成,这意味着不可以执行一个异步(Async) 方法且不等待其完成,并且期待其结束后再次重绘UI。

State对象的initState方法

当Widget对象被Flutter装载时调用,在Flutter试图执行绘制前执行,用来初始化数据。

一般需要先调用super.initState()方法。

使用码云开始搭建一个博客

基本步骤

1
2
3
4
5
6
7
## 安装hexo,需要配置nodejs环境
npm install hexo -g
## 创建博客,目录名任意,此处为blog
hexo create blog
## 进入blog
cd blog

修改配置文件

配置文件 _config.yml

1
2
3
4
# URL节调整如下
## If your site is put in a subdirectory, set url as 'http://example.com/child' and root as '/child/'
url: https://q0519.gitee.io/blog
root: /blog/

创建博客

使用如下命令创建一个新的markdown文件

1
hexo new "Hello World!"

之后可以在 _source 文件夹中找到相应的文件。如果使用自动建立Category插件,可能需要手工设置folder及建立文件。

常用命令

1
2
3
hexo clean #清理发布文件及缓存
hexo g #生成发布文件
hexo d #发布到远程(依赖自动发布插件)

一些有用的插件

目前我使用了如下一些插件

自动发布Blog插件

1
2
## 安装hexo 部署插件
npm install hexo-deployer-git --save
1
2
3
4
5
6
# deploy节调整如下
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
type: git
repo: git@gitee.com:q0519/blog.git
branch: master

如果需要将工程源码也保存在gitee/github上面,可以单独对整个项目建立git远端存储,和deploy设置不同的Repository,以满足在任意环境都可以通过同步源码独立维护发布blog的需求。

自动建立Category的插件

可以根据Folder分配情况自动建立Category。

1
npm install hexo-auto-category --save
1
2
3
auto_category:
enable: true
depth: 2

源码地址

建立RSS订阅的插件

1
npm install hexo-generator-feed --save
1
2
3
4
5
6
7
8
9
10
# Extensions
## Plugins: http://hexo.io/plugins/
#RSS订阅
plugin:
- hexo-generator-feed
#Feed Atom
feed:
type: atom
path: atom.xml
limit: 20

源码地址

渲染Plantuml

总共实验了两款plantuml插件,hexo-tag-plantuml以及hexo-filter-plantuml,我最后选择的是后者,理由如下:

  1. tag插件需要访问plantuml网站进行图形渲染,filter则可以配置为访问本地plantuml.jar,并且可以输出svg及base64图片到网页中,相对比较安全方便。
  2. filter对注释形式的uml tag支持比较好,可以兼容vscode + markdown + plantuml插件,整体体验较好。
1
npm install hexo-filter-plantuml --save

配置项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
plugin:
- hexo-filter-plantuml
plantuml:
# Local or PlantUMLServer.
render: "Local"
# "inline": <svg>xxx<svg/>
# "inlineUrlEncode": <img src='data:image/svg+xml;>
# "inlineBase64": <img src='data:image/svg+xml;base64>
# "localLink": <img src="/assert/puml/xxxx.svg">
link: "inline"
# where your dot binary
GraphvizDotFile: "C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot"
# where your jar
PlantJar: "C:\\Dev\\plantUml\\plantuml.jar"
asset_path: "asset" #这个路径不是必须的,只是纠正一个拼写错误
# common options: svg/png
outputFormat: "svg"

注意,如果使用hexo clean清理public目录,需要在之后创建public目录。由于filter-plantuml插件对于文件夹有硬性要求,需要在生成阶段保证public目录存在,才能进行后续路径创建。相信这个bug会在之后的发布修正。

另外,如上两个插件不可以在项目中并存。如果都安装了,可以通过如下命令卸载其中之一。

1
npm uninstall ???	

源码地址

文章中嵌入本地图片

如下只考虑与文章同文件路径的asset引用方法。

需要安装如下插件

1
$ npm i --save hexo-asset-link

该插件将自动转换markdown中的相对路径到发布的路径。比如,本地有一个markdown文件,名为 test.md,路径如下:

1
2
3
_post/
test/
test.md

则可以将test/文件夹作为asset文件夹,放置图片之类,之后通过markdown的图片引用语法

1
![image alt](test/test.jpg)

进行图片引用,asset-link将会自动调整路径。

使用Next theme

本站使用NexT Theme来风格化hexo,具体安装可以参考 NexT

国内多数站点介绍,需要修改theme/next/_config.yml文件,但不建议这么做。相关override的方法是增加如下文件:

1
source/_data/next.yml

则在默认情况下,next.yml中的配置项会覆盖掉NexT默认的,比较方便。