自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android開發(fā)速成簡潔教程十九:線程 Bezier曲線

移動開發(fā) Android
Android中使用線程Thread的方法和Java SE相同。和大多數(shù)OS系統(tǒng)一樣,Android中也有稱為UI Thread的主線程。UI Thread 主要用來給相應(yīng)的Widget分發(fā)消息,包括繪制(Drawing)事件。UI Thread 也是用來處理用戶交互事件的線程。

Android中使用線程Thread的方法和Java SE相同。和大多數(shù)OS系統(tǒng)一樣,Android中也有稱為UI Thread的主線程。UI Thread 主要用來給相應(yīng)的Widget分發(fā)消息,包括繪制(Drawing)事件。UI Thread 也是用來處理用戶交互事件的線程。比如:如果你按下屏幕上某個按鈕,UI 線程則將Touch 事件通知對應(yīng)的控件(Widgets),Widget 則將其狀態(tài)設(shè)置成“按下”,并把“重繪”(Invalidate)事件發(fā)到Event Queue中去。 UI線程從Event Queue中讀取事件后通知Widgets重畫自身。 

如果你的應(yīng)用設(shè)計不好的話, UI線程的這種單線程模式就會導(dǎo)致非常差的用戶響應(yīng)性能。特別是你將一些費時的操作如網(wǎng)絡(luò)訪問或數(shù)據(jù)庫訪問也放在UI線程中,這些操作會造成用戶界面無反應(yīng),最糟糕的是,如果UI線程阻塞超過幾秒(5秒),著名的ANR對話框就會出現(xiàn): 

 

所以在設(shè)計應(yīng)用時,需要把一些費時的任務(wù)使用單獨的工作線程來運行避免阻塞UI線程,但是如果在工作線程中想更新UI線程的話,不能直接在工作線程 中更新UI,這是因為UI線程不是“Thread Safe”。因此所有UI相關(guān)的操作一般必須在UI Thread中進行。 

Android OS提供了多種方法可以用在非UI線程訪問UI線程。 

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

Bezier 示例動態(tài)顯示Bezier曲線,使用了Activity.runOnUiThread 來更新屏幕,完整代碼如下:

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

 

除了上述的方法外,Android還提供了AsyncTask類以簡化工作線程與UI線程之間的通信。這里不詳述。此外,上面Bezier曲線動畫在屏幕上顯示時有閃爍的現(xiàn)象,這是動態(tài)顯示圖像的一個常見問題,后面將專門討論。

責任編輯:閆佳明 來源: imobilebbs
相關(guān)推薦

2013-12-26 15:43:07

Android開發(fā)Android應(yīng)用Activities

2013-12-26 15:10:08

Android開發(fā)應(yīng)用和框架Linux 內(nèi)核

2013-12-26 15:18:09

Android開發(fā)安裝開發(fā)環(huán)境

2013-12-27 14:34:46

Android開發(fā)Android應(yīng)用短信觸發(fā)示例

2013-12-27 14:05:22

Android開發(fā)Android應(yīng)用Dialog

2013-12-26 15:34:19

Android開發(fā)Android應(yīng)用基本概念

2013-12-27 13:49:22

Android開發(fā)Android應(yīng)用Button

2013-12-26 16:59:12

Android開發(fā)Android應(yīng)用數(shù)據(jù)綁定Data Bi

2013-12-27 12:51:44

Android開發(fā)Android應(yīng)用引路蜂

2013-12-26 16:24:13

Android開發(fā)Android應(yīng)用Intents

2013-12-27 13:27:05

Android開發(fā)Android應(yīng)用RadioButton

2013-12-27 16:06:10

Android開發(fā)Android應(yīng)用發(fā)布應(yīng)用

2013-12-26 15:46:30

Android開發(fā)Android應(yīng)用用戶界面設(shè)計

2013-12-26 16:46:21

2013-12-27 15:31:26

Android開發(fā)Android應(yīng)用資源Resources

2013-12-26 17:08:36

Android開發(fā)Android應(yīng)用自定義Adapter顯

2013-12-27 13:00:30

Android開發(fā)Android應(yīng)用Context Men

2013-12-27 12:42:15

Android開發(fā)Android應(yīng)用引路蜂

2013-12-27 14:10:36

Android開發(fā)Android應(yīng)用Transform

2013-12-27 15:11:17

Android開發(fā)訪問Internet繪制在線地圖
點贊
收藏

51CTO技術(shù)棧公眾號