`

Android简明开发教程十九:线程 Bezier曲线

 
阅读更多

Android中使用线程Thread的方法和Java SE相同。和大多数OS系统一样,Android中也有称为UI Thread的主线程。UI Thread 主要用来给相应的Widget分发消息,包括绘制(Drawing)事件。UI Thread 也是用来处理用户交互事件的线程。比如:如果你按下屏幕上某个按钮,UI 线程则将Touch 事件通知对应的控件(Widgets),Widget 则将其状态设置成“按下”,并把“重绘”(Invalidate)事件发到Event Queue中去。 UI线程从Event Queue中读取事件后通知Widgets重画自身。

如果你的应用设计不好的话, UI线程的这种单线程模式就会导致非常差的用户响应性能。特别是你将一些费时的操作如网络访问或数据库访问也放在UI线程中,这些操作会造成用户界面无反应,最糟糕的是,如果UI线程阻塞超过几秒(5秒),著名的ANR对话框就会出现:

所以在设计应用时,需要把一些费时的任务使用单独的工作线程来运行避免阻塞UI线程,但是如果在工作线程中想更新UI线程的话,不能直接在工作线程中更新UI,这是因为UI线程不是“Thread Safe”。因此所有UI相关的操作一般必须在UI Thread中进行。

Android OS提供了多种方法可以用在非UI线程访问UI线程。

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Handler

Bezier 示例动态显示Bezier曲线,使用了Activity.runOnUiThread 来更新屏幕,完整代码如下:

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
public class Bezier extends Graphics2DActivity
implements OnClickListener,Runnable{
/**
* The animation thread.
*/
private Thread thread;
private volatile boolean stopThread=false;
private boolean stopOrNot=false;
boolean drawn;
/**
* The random number generator.
*/
static java.util.Random random = new java.util.Random();
/**
* The animated path
*/
Path path = new Path();
/**
* Red brush used to fill the path.
*/
SolidBrush brush = new SolidBrush(Color.RED);
private static final int NUMPTS = 6;
private int animpts[] = new int[NUMPTS * 2];
private int deltas[] = new int[NUMPTS * 2];
long startt, endt;
private Button btnOptions;
@Override
protected void drawImage() {
drawDemo(100, 100);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.beziers);
graphic2dView
= (GuidebeeGraphics2DView) findViewById(R.id.graphics2dview);
btnOptions = (Button) findViewById(R.id.btnStopStart);
btnOptions.setOnClickListener(this);
reset(100,100);
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
@Override
public void onClick(View view) {
if(!stopOrNot){
btnOptions.setText("Start");
stopThread=true;
}
else{
stopThread=false;
btnOptions.setText("Stop");
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}
stopOrNot=!stopOrNot;
}
/**
* Generates new points for the path.
*/
private void animate(int[] pts, int[] deltas,
int i, int limit) {
int newpt = pts[i] + deltas[i];
if (newpt <= 0) {
newpt = -newpt;
deltas[i] = (random.nextInt() & 0x00000003)
+ 2;
} else if (newpt >= limit) {
newpt = 2 * limit - newpt;
deltas[i] = -((random.nextInt() & 0x00000003)
+ 2);
}
pts[i] = newpt;
}
/**
* Resets the animation data.
*/
private void reset(int w, int h) {
for (int i = 0; i < animpts.length; i += 2) {
animpts[i + 0]
= (random.nextInt() & 0x00000003)
* w / 2;
animpts[i + 1]
= (random.nextInt() & 0x00000003)
* h / 2;
deltas[i + 0]
= (random.nextInt() & 0x00000003)
* 6 + 4;
deltas[i + 1]
= (random.nextInt() & 0x00000003)
* 6 + 4;
if (animpts[i + 0] > w / 2) {
deltas[i + 0] = -deltas[i + 0];
}
if (animpts[i + 1] > h / 2) {
deltas[i + 1] = -deltas[i + 1];
}
}
}
final Runnable updateCanvas = new Runnable() {
public void run() {
int offsetX = (graphic2dView.getWidth() -
SharedGraphics2DInstance.CANVAS_WIDTH) / 2;
int offsetY = (graphic2dView.getHeight()
- SharedGraphics2DInstance.CANVAS_HEIGHT) / 2;
graphic2dView.invalidate(offsetX,offsetY,
offsetX+100,offsetY+100);
}
};
/**
* Sets the points of the path and draws and fills the path.
*/
private void drawDemo(int w, int h) {
for (int i = 0; i < animpts.length; i += 2) {
animate(animpts, deltas, i + 0, w);
animate(animpts, deltas, i + 1, h);
}
//Generates the new pata data.
path.reset();
int[] ctrlpts = animpts;
int len = ctrlpts.length;
int prevx = ctrlpts[len - 2];
int prevy = ctrlpts[len - 1];
int curx = ctrlpts[0];
int cury = ctrlpts[1];
int midx = (curx + prevx) / 2;
int midy = (cury + prevy) / 2;
path.moveTo(midx, midy);
for (int i = 2; i <= ctrlpts.length; i += 2) {
int x1 = (curx + midx) / 2;
int y1 = (cury + midy) / 2;
prevx = curx;
prevy = cury;
if (i < ctrlpts.length) {
curx = ctrlpts[i + 0];
cury = ctrlpts[i + 1];
} else {
curx = ctrlpts[0];
cury = ctrlpts[1];
}
midx = (curx + prevx) / 2;
midy = (cury + prevy) / 2;
int x2 = (prevx + midx) / 2;
int y2 = (prevy + midy) / 2;
path.curveTo(x1, y1, x2, y2, midx, midy);
}
path.closePath();
// clear the clipRect area before production
graphics2D.clear(Color.WHITE);
graphics2D.fill(brush, path);
this.runOnUiThread(updateCanvas);
}
public void run() {
Thread me = Thread.currentThread();
if (!drawn) {
synchronized (this) {
graphics2D.clear(Color.WHITE);
graphics2D.fill(brush, path);
graphic2dView.refreshCanvas();
drawn = true;
}
}
while (thread == me && !stopThread) {
drawDemo(100,100);
}
thread = null;
}
}

除了上述的方法外,Android还提供了AsyncTask类以简化工作线程与UI线程之间的通信。这里不详述。此外,上面Bezier曲线动画在屏幕上显示时有闪烁的现象,这是动态显示图像的一个常见问题,后面将专门讨论。

分享到:
评论

相关推荐

    计算机图形学 Bezier曲线源代码

    掌握Bezier曲线的生成算法,掌握应用调和函数生成曲线的方法,掌握3次Bezier曲线的性质。 实验要求: 用鼠标交互输入控制点,绘制控制折线,生成并显示3次Bezier曲线。 实验原理: Bezier曲线的形状是通过一组多边...

    Bezier曲线的描绘

    Bezier曲线是一种在计算机图形学中广泛应用的数学工具,主要用于创建平滑、连续的曲线路径。在VC++环境中,我们可以利用编程API来实现Bezier曲线的绘制。这篇内容将深入探讨二阶、三阶和四阶Bezier曲线的概念、公式...

    Bezier曲线代码 java

    Bezier曲线是一种在计算机图形学中广泛应用的数学工具,主要用于创建平滑的曲线路径。在Java编程语言中,实现Bezier曲线的代码通常涉及到一系列数学运算,包括向量、矩阵和插值算法。以下是对Bezier曲线及其Java实现...

    Bezier曲线

    在VC6.0这样的集成开发环境中,可以使用C++语言来实现Bezier曲线的算法。 1. **Bezier曲线的基本概念**: Bezier曲线是由法国工程师Pierre Bézier在1962年提出的,它由n个控制点P0到Pn确定,其中n是曲线的阶数。...

    绘制bezier曲线

    在计算机图形学中,Bezier曲线是一种非常重要的概念,它被广泛应用于二维和三维图形的设计、游戏开发、动画制作等领域。VB(Visual Basic)是微软公司推出的一种编程语言,它允许开发者利用其简单易用的特性来实现...

    Bezier曲线_Bezier曲面_Matlab

    在Matlab GUI中实现了Bezier任意阶数曲线和曲面的绘制。曲线可使用鼠标生成控制点,控制点可随意拖动;也可手动输入控制点坐标。曲面控制点信息可使用xls文件导入,也可手动输入控制点坐标。 程序使用Matlab GUI...

    Matlab_画二次及三次Bezier曲线.rar_bezier利用MATLAB_三次曲线_二次及三次Bezier曲线

    在MATLAB中绘制二次及三次Bezier曲线是一项基本的图形绘制技能,这在计算机图形学、设计和工程领域中尤其重要。Bezier曲线是一种基于控制点的参数曲线,它们以法国工程师Pierre Bézier的名字命名,因其灵活性和计算...

    二次Bezier曲线源代码

    二次Bezier曲线是计算机图形学中常见的一种曲线表示方法,它在设计、动画和游戏开发等领域广泛应用。Bezier曲线的数学基础是伯恩斯坦多项式,它通过控制点来定义曲线的形状。二次Bezier曲线由三个点构成:起点P0,...

    图形学各种曲线--Bezier曲线,B-样条曲线,Hermit曲线

    在计算机图形学中,曲线是描绘形状和路径的重要工具,特别是在3D建模、游戏开发、动画设计等领域。本文将详细探讨三种常见的曲线类型:Bezier曲线、B-样条(B-Spline)曲线以及Hermit曲线,它们在C++编程环境中的...

    Bezier曲线vc++

    Bezier曲线在计算机图形学中是一种广泛应用的数学工具,主要用于创建平滑、连续的曲线路径。在VC++6.0环境中,我们可以使用C++语言来实现Bezier曲线的绘制。以下是对Bezier曲线及其在VC++编程中的应用进行的详细解释...

    三次Bezier曲线原理及实现代码

    ### 三次Bezier曲线原理及实现代码 #### 一、Bezier曲线简介 Bezier曲线是一种在计算机图形学中广泛应用的参数曲线,被广泛应用于图形设计、字体渲染以及计算机辅助设计等领域。这种曲线是由法国工程师皮埃尔·...

    Bezier曲线曲面下

    ### Bezier曲线的升阶 #### 一、Bezier曲线升阶的基本概念 ##### 1. 升阶的含义与目的 - **含义**:Bezier曲线的升阶是指在不改变曲线形状与方向的前提下,通过增加控制顶点的数量来实现。这里的“升阶”指的是将...

    n次Bezier曲线

    在vc上基于openGL编写的n次Bezier曲线,可以选择n的大小绘制指定次数的Bezier曲线,之后有较好的交互性,可以在n次Bezier曲线的基础上,将两点拖至重合,变成n-1次Bezier曲线

    自己写的三次Bezier曲线

    标题:“自己写的三次Bezier曲线” 描述:“三次Bezier曲线代码” 标签:“不错的” 知识点解析: **三次Bezier曲线原理与实现** 三次Bezier曲线是一种在计算机图形学中广泛应用的参数曲线,它由四个控制点定义...

    计算机图形学 Bezier曲线

    计算机图形学是信息技术领域的一个重要分支,它涉及图像的生成、处理和显示。...通过实践和编程,你可以更深入地了解如何在Win-TC2.0或其他开发环境中实现和使用Bezier曲线,为计算机图形学的学习打下坚实的基础。

    MFC下Bezier曲线的绘制

    在计算机图形学中,Bezier曲线是一种非常常见的数学模型,用于绘制平滑的曲线。MFC(Microsoft Foundation Classes)是微软提供的一种C++类库,用于构建Windows应用程序,它提供了丰富的界面元素和图形处理功能。本...

    MFC bezier曲线

    在计算机图形学中,Bezier曲线是一种非常重要的数学工具,它被广泛用于绘制平滑的曲线,如在2D和3D图形、动画、CAD系统以及游戏开发中。本实验是基于C++6.0编程环境,利用Microsoft Foundation Classes (MFC) 类库...

    Bezier_unity3d_Bezier曲线_

    在Unity3D游戏引擎中,Bezier曲线是一种广泛用于路径规划、动画曲线设计和图形渲染的技术。这个场景中,我们有两个关键文件:BezierUtils.cs和TestBezier.cs,它们分别实现了Bezier曲线的基本算法和在Unity环境中的...

    Bezier曲线生成算法(C++实现)

    Bezier曲线是一种广泛应用于计算机图形学、动画制作、游戏开发以及CAD设计等领域的数学工具。它是一种参数化的曲线,由一系列控制点定义,通过线性插值和多项式组合来生成平滑连续的曲线。在C++中实现Bezier曲线生成...

Global site tag (gtag.js) - Google Analytics