四种异步更新UI的方法

Android要求只能在UI线程中更新UI,要想在其他线程中更新UI,大致有四种方式:

1.使用Handler消息传递机制(推荐)
2.使用AsyncTask异步任务(推荐)
3.使用runOnUiThread(action)方法;
4.使用View的post(Runnabel r)方法;
5.使用handler的post


一.Handler:

public class MainActivity extends Activity {

    TextView tip;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            tip.setText("handl更新");
            if( msg.what == 0 ){
                tip.setText("handl更新");
            }
        }
    };

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

        tip = (TextView)findViewById(R.id.tip);
    }

    protected void myClick(View v){
        if( v.getId() == R.id.btn ){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        Thread.sleep(1000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    Message msg = handler.obtainMessage();
                    msg.what = 0;
                    handler.sendMessage(msg);
                }
            }).start();
        }
    }
}


二.AsyncTask:
简单示例:

public class MainActivity extends Activity {

    TextView tip;
    MyAsyncTask myAsyncTask;

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

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

        myAsyncTask = new MyAsyncTask();
        myAsyncTask.execute();
    }

    class MyAsyncTask extends AsyncTask<Void,String, Boolean>{

        // 非UI线程中,独立线程
        @Override
        protected Boolean doInBackground(Void... params) {
            try{
                Thread.sleep(1000*5);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            return true;
        }

        // UI线程
        @Override
        protected void onPostExecute(Boolean aBoolean) {
            tip.setText("AsyncTask更新了");
        }
    };
}

更详细的用法:http://www.cnblogs.com/itfenqing/p/6748261.html


三.runOnUiThread
runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。 这样Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程

public class MainActivity extends Activity {

    TextView tip;

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

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

        new Thread(new Runnable() {
            @Override
            public void run() {

                try{
                    Thread.sleep(10*1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tip.setText("runOnUiThread");
                    }
                });
            }
        }).start();
    }
}

  


四.使用View的post方法:

public class MainActivity extends Activity {

    TextView tv;

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

        tv = (TextView)findViewById(R.id.tip);

        new Thread(new Runnable() {
            @Override
            public void run() {

                try{
                    Thread.sleep(10000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }

                tv.post(new Runnable() {
                    @Override
                    public void run() {
                        tv.setText("view post");
                    }
                });
            }
        }).start();
    }
}

五.Handler.post

public class MainActivity extends Activity {

    TextView tv;
    Handler handler;

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

        tv = (TextView)findViewById(R.id.tip);
        handler = new Handler();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Thread.sleep(10000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }

                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        tv.setText("home");
                    }
                });
            }
        }).start();
    }
}

可以在子线程里更新的控件及方法:
ProgressBar
ListView 的notifyDataSetChanged()

原文地址:https://www.cnblogs.com/itfenqing/p/6753503.html