0%

二叉树

二叉树
1
2
3
4
5
6
7
8
9
10
11
12
13
//Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
阅读全文 »

其实有两种思路

1.通过组合组件实现

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import 'package:flutter/material.dart';

class RoundCheckBox extends StatefulWidget {
final bool value;

final ValueChanged<bool> onChanged;

RoundCheckBox({Key key, @required this.value, this.onChanged})
: super(key: key);

@override
_RoundCheckBox1State createState() => _RoundCheckBoxState();
}

class _RoundCheckBoxState extends State<RoundCheckBox1> {
bool _value;
ValueChanged<bool> _onChanged;

@override
void initState() {
super.initState();
_value = widget.value;
_onChanged = widget.onChanged;
}

/// value: _throwShotAway,
/// onChanged: (bool newValue) {
/// setState(() {
/// _throwShotAway = newValue;
/// });
/// },

@override
Widget build(BuildContext context) {
return Center(
child: GestureDetector(
onTap: () {
_value = !_value;
_onChanged(_value);
},
child: Padding(
padding: const EdgeInsets.all(2),
child: _value
? Icon(
Icons.check_circle,
size: 18.0,
color: Colors.blue,
)
: Icon(
Icons.panorama_fish_eye,
size: 18.0,
color: Colors.grey,
),
)),
);
}
}

2 参考CheckBox,将绘制方形代码部分改成圆角

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 CheckBox.class
/// The width of a checkbox widget.checkBox的宽度
static const double width = 18.0;
///边框的Size
const double _kEdgeSize = Checkbox.width;
///边框的圆角
const Radius _kEdgeRadius = Radius.circular(1.0);
///绘制外边框
RRect _outerRectAt(Offset origin, double t) {
final double inset = 1.0 - (t - 0.5).abs() * 2.0;
final double size = _kEdgeSize - inset * _kStrokeWidth;
final Rect rect = Rect.fromLTWH(origin.dx + inset, origin.dy + inset, size, size);
return RRect.fromRectAndRadius(rect, _kEdgeRadius);
}

可以看到方形边框的绘制是通过_outerRectAt()方法实现的,那么把圆角增大,是不是可以达到圆形边框的效果.

所以我把CheckBox的源码拷贝下来了,把圆角改成了宽度的一半,即可实现圆形边框的CheckBox.修改的代码如下

1
2
3
4
///修改前
const Radius _kEdgeRadius = Radius.circular(1.0);
///修改后
const Radius _kEdgeRadius = Radius.circular(9.0);

Java中有四种引用,强引用、软引用、弱引用、虚引用。

强引用

强引用不会被回收

1
2
Object obj = new Object();
String str = new String("str");

软引用(SoftReference)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String str1 = new String("softReferenceTest1");
String str2 = new String("softReferenceTest2");
SoftReference<String> softReference1 = new SoftReference<>(str1);
SoftReference<String> softReference2 = new SoftReference<>(str2);

System.out.println(softReference1.get());
System.out.println(softReference2.get());
//解除强引用,让对象可被回收
str2 = null;
System.gc();
System.out.println("===gc===");

System.out.println(softReference1.get());
System.out.println(softReference2.get());
1
2
3
4
5
softReferenceTest1
softReferenceTest2
===gc===
softReferenceTest1
softReferenceTest2

可以看到str2并没有被回收。

当内存充足的时候,软引用对象不会被JVM回收,而当内存不足时,软引用对象会被回收掉。

Android的SoftReferences代码注释里写了,要避免使用SoftReferences进行缓存

在实践中,软引用在缓存场景中效率低下。运行时(Runtime)缺乏足够的信息来决定应该清除哪些引用、保留哪些引用。最致命的是,当面临“清除软引用”和“扩展堆内存”之间的选择时,运行时无法做出合理决策。

由于缺乏对每个引用在应用中的价值评估,软引用的实用性大打折扣:

  • 引用过早被清除会导致重复计算(不必要的性能开销)。

  • 引用过晚被清除则会浪费内存(可能导致内存压力或OOM崩溃)。

推荐替代方案:LruCache

弱引用(WeakReference)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String str1 = new String("weakReferenceTest1");
String str2 = new String("weakReferenceTest2");
WeakReference<String> weakReference1 = new WeakReference<>(str1);
WeakReference<String> weakReference2 = new WeakReference<>(str2);

System.out.println(weakReference1.get());
System.out.println(weakReference2.get());
//解除强引用,让对象可被回收
str2 = null;
System.gc();
System.out.println("===gc===");

System.out.println(weakReference1.get());
System.out.println(weakReference2.get());
1
2
3
4
5
weakReferenceTest1
weakReferenceTest2
===gc===
weakReferenceTest1
null

str1没有被回收,str2被回收了。当没有强引用指向weakReference,一gc就会被回收。Android中经常使用WeakReference来规避内存泄漏的风险。

虚引用(PhantomReference)

1
2
3
4
ReferenceQueue<String> queue = new ReferenceQueue<>();
String str = new String("phantomReferenceTest");
PhantomReference<String> phantomReference = new PhantomReference<>(str, queue);
System.out.println(phantomReference.get());
1
null

phantomReference.get()永远返回null。

虚引用很少使用,且虚引用只有一个构造方法,必须配合ReferenceQueue一起使用。

配合ReferenceQueue使用

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
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();

String str = new String("weakReference+referenceQueue");
WeakReference<String> weakReference = new WeakReference<>(str, referenceQueue);
System.out.println("weakReference=" + weakReference);
System.out.println(weakReference.get());
str = null;
System.gc();
System.out.println("===gc===");

try {
Thread.sleep(100);
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println(weakReference.get());

System.gc();

Reference<? extends String> ref = referenceQueue.poll();

if (ref != null) {
System.out.println("========");
System.out.println(ref);
System.out.println(ref.get());
}
1
2
3
4
5
6
7
weakReference=java.lang.ref.WeakReference@566776ad
weakReference+referenceQueue
===gc===
null
========
java.lang.ref.WeakReference@566776ad
null

可以看到当gc之后weakReference.get()已经为null,但是在referenceQueue.poll()却有值,并且为WeakReference@566776ad,和weakReference相等。也就是 gc之后会将weakReference添加进WeakReference关联的ReferenceQueue。 可以用来监听某个对象是否被回收,android中的LeakCanary框架就是利用这个原理进行分析是否有内存泄漏。

开始

数据接口为wanandroid的开放api,返回数据类型如下:

1
2
3
4
5
{
"data": ...,
"errorCode": 0,
"errorMsg": ""
}

errorCode>=0时为网络请求成功,data则为返回的数据;

errorCode<0时为网络请求失败,errorMsg则为返回的错误信息;

阅读全文 »

前言

在看源码分析博客时,常常能看到下面的类图。最初不懂,经常看的云里雾里,然后自己学习了一下UML图的基本用法,发现基本使用还是很简单的。学习其基本使用是很有必要的这里也和大家一起学习一下在AndroidStudio上画简单UML图。

图例UML

阅读全文 »

错误

在使用retrofit2请求正式https接口时报错:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for cert

原因

服务端https证书配置错误

解决方法

忽略证书检查

阅读全文 »