2017年7月16日 星期日

Android:使用Handler與Thread更新UI

在android中系统不允許在非Main Thread更新UI。當我們在非主線程做了耗時操作後,需要去更新UI的時候,我們就需要使用Handler來執行更新操作。

範例用一個線程,在線程裡不斷循環,線程每休眠1s,sendMessageHandle,在handleMessage方法裡更新UI線程即TextView的内容,讓TextView不斷更新時間。

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.user.service.MainActivity"
    android:orientation="vertical">
  
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/txt"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private TextView txt;
    private static final int msgKey1 = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txt = (TextView)findViewById(R.id.txt);

        Thread t = new Thread(runnable);
        t.start();
    }
    
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            do{
                try {
                    Thread.sleep(1000);
                    Message msg = new Message();
                    msg.what = msgKey1;
                    mHandler.sendMessage(msg);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }while (true);
        }
    };
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case msgKey1:
                    long time = System.currentTimeMillis();
                    Date date = new Date(time);
                    SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 EEE");
                    txt.setText(format.format(date));
                    break;
                default:
                    break;
            }
        }
    };
}

要不斷更新UI除了使用Handler外,還可以使用runOnUiThread()這個方法來更新UI

public class MainActivity extends AppCompatActivity {

    private TextView txt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txt = (TextView)findViewById(R.id.txt);

        Thread t = new Thread(runnable);
        t.start();


    }

    private Runnable runnable = new Runnable() {
    @Override
    public void run() {
        try {
            while (true) {
                Thread.sleep(1000);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // update TextView here!
                        long time = System.currentTimeMillis();
                        Date date = new Date(time);
                        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 EEE");
                        txt.setText(format.format(date));
                    }
                });
            }
        } catch (InterruptedException e) {
        }
    }
    };

沒有留言:

張貼留言