Android开发中如何使用线程Bezier曲线
Android开发中如何使用线程Bezier曲线,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
砀山网站制作公司哪家好,找创新互联!从网页设计、网站建设、微信开发、APP开发、自适应网站建设等网站项目制作,到程序开发,运营维护。创新互联自2013年起到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联。
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 public class Bezier extends Graphics2DActivity 2 implements OnClickListener,Runnable{ 3 4 /** 5 * The animation thread. 6 */ 7 private Thread thread; 8 private volatile boolean stopThread=false; 9 private boolean stopOrNot=false; 10 boolean drawn; 11 /** 12 * The random number generator. 13 */ 14 static java.util.Random random = new java.util.Random(); 15 /** 16 * The animated path 17 */ 18 Path path = new Path(); 19 /** 20 * Red brush used to fill the path. 21 */ 22 SolidBrush brush = new SolidBrush(Color.RED); 23 private static final int NUMPTS = 6; 24 private int animpts[] = new int[NUMPTS * 2]; 25 private int deltas[] = new int[NUMPTS * 2]; 26 long startt, endt; 27 28 private Button btnOptions; 29 @Override 30 protected void drawImage() { 31 drawDemo(100, 100); 32 33 } 34 35 public void onCreate(Bundle savedInstanceState) { 36 super.onCreate(savedInstanceState); 37 setContentView(R.layout.beziers); 38 graphic2dView 39 = (GuidebeeGraphics2DView) findViewById(R.id.graphics2dview); 40 btnOptions = (Button) findViewById(R.id.btnStopStart); 41 btnOptions.setOnClickListener(this); 42 reset(100,100); 43 if (thread == null) { 44 thread = new Thread(this); 45 thread.start(); 46 } 47 48 } 49 50 @Override 51 public void onClick(View view) { 52 53 if(!stopOrNot){ 54 btnOptions.setText("Start"); 55 stopThread=true; 56 } 57 else{ 58 stopThread=false; 59 btnOptions.setText("Stop"); 60 if (thread == null) { 61 thread = new Thread(this); 62 thread.start(); 63 } 64 } 65 stopOrNot=!stopOrNot; 66 67 } 68 /** 69 * Generates new points for the path. 70 */ 71 private void animate(int[] pts, int[] deltas, 72 int i, int limit) { 73 int newpt = pts[i] + deltas[i]; 74 if (newpt <= 0) { 75 newpt = -newpt; 76 deltas[i] = (random.nextInt() & 0x00000003) 77 + 2; 78 } else if (newpt >= limit) { 79 newpt = 2 * limit - newpt; 80 deltas[i] = -((random.nextInt() & 0x00000003) 81 + 2); 82 } 83 pts[i] = newpt; 84 } 85 86 /** 87 * Resets the animation data. 88 */ 89 private void reset(int w, int h) { 90 for (int i = 0; i < animpts.length; i += 2) { 91 animpts[i + 0] 92 = (random.nextInt() & 0x00000003) 93 * w / 2; 94 animpts[i + 1] 95 = (random.nextInt() & 0x00000003) 96 * h / 2; 97 deltas[i + 0] 98 = (random.nextInt() & 0x00000003) 99 * 6 + 4; 100 deltas[i + 1] 101 = (random.nextInt() & 0x00000003) 102 * 6 + 4; 103 if (animpts[i + 0] > w / 2) { 104 deltas[i + 0] = -deltas[i + 0]; 105 } 106 if (animpts[i + 1] > h / 2) { 107 deltas[i + 1] = -deltas[i + 1]; 108 } 109 } 110 } 111 112 final Runnable updateCanvas = new Runnable() { 113 public void run() { 114 int offsetX = (graphic2dView.getWidth() - 115 SharedGraphics2DInstance.CANVAS_WIDTH) / 2; 116 int offsetY = (graphic2dView.getHeight() 117 - SharedGraphics2DInstance.CANVAS_HEIGHT) / 2; 118 graphic2dView.invalidate(offsetX,offsetY, 119 offsetX+100,offsetY+100); 120 } 121 }; 122 /** 123 * Sets the points of the path and draws and fills the path. 124 */ 125 private void drawDemo(int w, int h) { 126 for (int i = 0; i < animpts.length; i += 2) { 127 animate(animpts, deltas, i + 0, w); 128 animate(animpts, deltas, i + 1, h); 129 } 130 //Generates the new pata data. 131 path.reset(); 132 int[] ctrlpts = animpts; 133 int len = ctrlpts.length; 134 int prevx = ctrlpts[len - 2]; 135 int prevy = ctrlpts[len - 1]; 136 int curx = ctrlpts[0]; 137 int cury = ctrlpts[1]; 138 int midx = (curx + prevx) / 2; 139 int midy = (cury + prevy) / 2; 140 path.moveTo(midx, midy); 141 for (int i = 2; i <= ctrlpts.length; i += 2) { 142 int x1 = (curx + midx) / 2; 143 int y1 = (cury + midy) / 2; 144 prevx = curx; 145 prevy = cury; 146 if (i < ctrlpts.length) { 147 curx = ctrlpts[i + 0]; 148 cury = ctrlpts[i + 1]; 149 } else { 150 curx = ctrlpts[0]; 151 cury = ctrlpts[1]; 152 } 153 midx = (curx + prevx) / 2; 154 midy = (cury + prevy) / 2; 155 int x2 = (prevx + midx) / 2; 156 int y2 = (prevy + midy) / 2; 157 path.curveTo(x1, y1, x2, y2, midx, midy); 158 } 159 path.closePath(); 160 // clear the clipRect area before production 161 162 graphics2D.clear(Color.WHITE); 163 graphics2D.fill(brush, path); 164 165 this.runOnUiThread(updateCanvas); 166 } 167 168 169 170 public void run() { 171 Thread me = Thread.currentThread(); 172 173 if (!drawn) { 174 synchronized (this) { 175 graphics2D.clear(Color.WHITE); 176 graphics2D.fill(brush, path); 177 graphic2dView.refreshCanvas(); 178 drawn = true; 179 } 180 } 181 while (thread == me && !stopThread) { 182 drawDemo(100,100); 183 } 184 thread = null; 185 } 186 }
除了上述的方法外,Android还提供了AsyncTask类以简化工作线程与UI线程之间的通信。此外,上面Bezier曲线动画在屏幕上显示时有闪烁的现象,这是动态显示图像的一个常见问题。
看完上述内容,你们掌握Android开发中如何使用线程Bezier曲线的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!
网页名称:Android开发中如何使用线程Bezier曲线
标题链接:http://ybzwz.com/article/igidgc.html