Android在子线程中更新UI的三种方式

·  阅读 556

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

一、使用runOnUiThread()方法

其本质是异步消息处理机制的接口封装

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button bt_button = (Button) findViewById(R.id.button);
        tv_text = (TextView) findViewById(R.id.textView);
        bt_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            //
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                    //这里对UI界面进行操作
                        tv_text.setText("我爱中国");
                    }
                });
            }
        });
    }
复制代码
 new Thread(){
            @Override
            public void run() {
                try {
                    Thread.sleep(2000); //此处没有延时界面不会显示
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
​
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            for (int i = 0; i < 10; i++) {
                                Thread.sleep(1000);
                                button_led1.performClick();
                                Thread.sleep(1000);
                                button_led2.performClick();
                                Thread.sleep(1000);
                                button_led3.performClick();
                                Thread.sleep(1000);
                                button_led4.performClick();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }.start();
复制代码

二、使用Handler

往Handler中发送一个消息,当Handler接受到发来的消息,再在Handler中执行相应的操作。

  • 新建一个Handel

    • 接收button发送的参数
    • 对主线程中的UI进行修改
private static final int UPDATE_TEXT = 1;
    TextView tv_text;
​
    /**
     * 新建一个Handel
     * 接收button发送的参数
     * 对主线程中的UI进行修改
     */
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATE_TEXT:
                    //在这里进行UI操作
                    tv_text.setText("大聪明");
                    break;
            }
        }
    };
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button bt_button = (Button) findViewById(R.id.button);
        tv_text = (TextView) findViewById(R.id.textView);
        bt_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //新建一个线程
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Message message = new Message();
                        message.what = UPDATE_TEXT;
                        //将Message对象发送出去
                        handler.sendMessage(message);
                    }
                }).start();
            }
        });
    }
​
复制代码

三、使用AsyncTask

在MainActivity中新建一个内部类,这个内部类继承了AsuncTask类,然后重写AsyncTask的内部方法。

AsyncTask的三个构造参数分别为:

  • params 传入的参数
  • Progress 进度显示指定的泛型作为返回值类型
  • Result 任务执行完成后的返回值

其中的方法有:

protected void onPreExecute()

在开始任务之前执行的一个方法 用于进行一些界面的初始化操作,比如显示一个进度条对话框

Boolean doInBackground(Void... voids)

在任务开始时执行的方法 执行耗时操作,如果AsyncTask任务一旦完成 通过return语句将结果返回 如果为void则不返回结果。 在此方法 中不能执行UI操作 若需要,调用publishProgress(Progress...)方法来完成 在调用这个方法之后onProgressUpdate会得到执行

在doInBackground中调用了publishProgress方法之后,onProgressUpdate会得到执行 该方法中携带的参数就在后台任务汇总传递过来的 在这个方法中对uI进行操作

protected void onProgressUpdate(Integer... values)

在后再任务执行完毕并通过return语句进行返回时,这个方法就很快会调用。利用返回数据进行UI操作。如,提醒任务执行结果。以及关闭掉进度条对话框等。

public class MainActivity extends AppCompatActivity {
​
    TextView tv1;
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button bt_thread = (Button) findViewById(R.id.button);
        tv1 = (TextView) findViewById(R.id.textView);
        bt_thread.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //启动DownloadTask任务
                        new DownloadTask().execute();
                    }
                }).start();
            }
        });
    }
​
    class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
​
        @Override
        protected void onPreExecute() {
            //在开始任务之前执行的一个方法
            //用于进行一些界面的初始化操作,比如显示一个进度条对话框
            Log.d("MainActivity", "onPostExecute: 我要开始干活啦");
        }
​
        @Override
        protected Boolean doInBackground(Void... voids) {
            //在任务开始时执行的方法
            //执行耗时操作,如果AsyncTask任务一旦完成 通过return语句将结果返回 如果为void则不返回结果。
            //在此方法 中不能执行UI操作 若需要,调用publishProgress(Progress...)方法来完成
            Log.d("MainActivity", "doInBackground: 我在忙,我在忙,我在忙");
            //在调用这个方法之后onProgressUpdate会得到执行
            publishProgress();
            return null;
        }
​
        //在doInBackground中调用了publishProgress方法之后,onProgressUpdate会得到执行 该方法中携带的参数就在后台任务汇总传递过来的 在这个方法中对uI进行操作
        @Override
        protected void onProgressUpdate(Integer... values) {
            Log.d("MainActivity", "onProgressUpdate:我也在忙");
            tv1.setText("牛皮");
            super.onProgressUpdate(values);
        }
//在后再任务执行完毕并通过return语句进行返回时,这个方法就很快会调用。利用返回数据进行UI操作。如,提醒任务执行结果。以及关闭掉进度条对话框等。
        @Override
        protected void onPostExecute(Boolean aBoolean) {
            //任务执行完毕之后
            Log.d("MainActivity", "onPostExecute: 我忙完了");
        }
    }
}
​
复制代码

startForground()前台服务

在服务中开启线程 最后需要用stopself()关闭。

IntentService 执行完毕后知道自动停止

分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改