1. 程式人生 > >【朝花夕拾】Android多執行緒之(三)runOnUiThread篇——程式猿們的貼心小棉襖

【朝花夕拾】Android多執行緒之(三)runOnUiThread篇——程式猿們的貼心小棉襖

       runOnUiThread()的使用以及原理實在是太簡單了,簡單到筆者開始都懶得單獨開一篇文章來寫它。當然這裡說的簡單,是針對對Handler比較熟悉的童鞋而言的。不過麻雀雖小,五臟俱全,runOnUiThread()好歹也算得上是一方諸侯,在子執行緒切換到主執行緒的眾多方法中,有著自己的一席之地,所以,必須得給它單獨列傳。

       好了,閒話休提,言歸正傳。runOnUiThread()是Activity類中的方法,它用於從子執行緒中切換到主執行緒來執行一些需要再主執行緒執行的操作。這裡先直接看一個例子,看看它是如何使用的:

 1 public class MainActivity extends AppCompatActivity {
 2     private TextView textView;
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.activity_main);
 7         textView = findViewById(R.id.tv_test);
 8         new Thread(new Runnable() {
 9             @Override
10             public void run() {
11                 //do something takes long time in the work-thread
12                 runOnUiThread(new Runnable() {
13                     @Override
14                     public void run() {
15                         textView.setText("test");
16                     }
17                 });
18             }
19         }).start();
20     }
21 }

簡單吧,在子執行緒中直接呼叫runOnUiThread方法,第15行就切換到主執行緒了,直接修改UI。如果使用Lambda表示式,看起來就更簡單了:

1 new Thread(() -> {
2     //do something takes long time in the work-thread
3     runOnUiThread(() -> {
4         textView.setText("test");
5     });
6 }).start();

相比於通過顯示使用Handler,重寫AsyncTask方法來說,是不是爽得不要不要的?

       不僅僅使用簡單,其原理也非常簡單,底層實際上也是封裝的Handler來實現的,如下是關鍵程式碼:

 1 //=========Activity=========
 2 final Handler mHandler = new Handler();
 3 
 4 private Thread mUiThread;
 5 
 6 final void attach(...){
 7     ......
 8     mUiThread = Thread.currentThread();
 9     ......
10 }
11 
12 /**
13  * Runs the specified action on the UI thread. If the current thread is the UI
14  * thread, then the action is executed immediately. If the current thread is
15  * not the UI thread, the action is posted to the event queue of the UI thread.
16  *
17  * @param action the action to run on the UI thread
18  */
19 public final void runOnUiThread(Runnable action) {
20     if (Thread.currentThread() != mUiThread) {
21         mHandler.post(action);
22     } else {
23         action.run();
24     }
25 }

mHander是Activity的成員變數,在Activity例項化的時候也跟著初始化了,MainActivity繼承自Activity,這裡mHandler使用的looper自然是main looper了。attach方法也是在主執行緒中呼叫的,mUiThread就表示主執行緒了。第19行的方法就很容易理解了,如果該方法是執行在主執行緒,Runnable的run方法會馬上執行;而如果不是在主執行緒,就post到主執行緒的looper的MessageQueue中排隊執行。

       基本使用和基本原理就講完了,夠簡單吧,也確實沒多少重要的東西可講的了!真不愧是廣大程式猿們的貼心小棉襖,要是Android的各個方法都這麼簡單,想必就沒有那麼多禿頂了!

       好了,洗澡睡