15.Android 异步更新UI 技巧

本文介绍了Android应用程序中更新用户界面(UI)的各种方法,包括使用Handler消息传递机制、AsyncTask异步任务处理、Handler.post()方法及Activity.runOnUiThread()方法。通过这些技术实现UI线程与后台线程间的有效交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

15.Android 异步更新UI 技巧


Handler消息传递

    private TextView handlerTV;
    private static final int HANDLER_SUCCESS = 206;
    private static class RefreshHandler extends Handler {
        private final WeakReference<RefreshUIActivity> mActivity;

        public RefreshHandler(RefreshUIActivity activity) {
            mActivity = new WeakReference<>(activity);
        }

        /**
         * Subclasses must implement this to receive messages.
         *
         * @param msg
         */
        @Override
        public void handleMessage(Message msg) {
            RefreshUIActivity activity = this.mActivity.get();
            if (activity != null) {
                switch (msg.what) {
                    case HANDLER_SUCCESS: {
                        activity.handlerTV.setText("success");
                        break;
                    }
                }
            }
        }
    }


    private final RefreshHandler refreshHandler = new RefreshHandler(RefreshUIActivity.this);
    private final Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            Message message = RefreshUIActivity.this.refreshHandler.obtainMessage();
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            message.what = HANDLER_SUCCESS;
            refreshHandler.sendMessageDelayed(message, 2000);
        }
    };
    private final Thread mThread = new Thread(mRunnable);
this.mThread.start();

AsyncTask异步任务

对AsyncTask原理不熟悉的,可以看看Android AsyncTask 技巧

    private TextView asyncTaskTV;

    public class MAsyncTask extends AsyncTask<String, Integer, String> {

        private TextView textview;

        public MAsyncTask(TextView textview) {
            super();
            this.textview = textview;
        }

        /**
         * 对应AsyncTask第一个参数
         * 异步操作,不在主UI线程中,不能对控件进行修改
         * 可以调用publishProgress方法中转到onProgressUpdate(这里完成了一个handler.sendMessage(...)的过程)
         *
         * @param params The parameters of the task.
         * @return A result, defined by the subclass of this task.
         * @see #onPreExecute()
         * @see #onPostExecute
         * @see #publishProgress
         */
        @Override
        protected String doInBackground(String... params) {
            int i = 0;
            for (; i < 100; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.publishProgress(i);
            }
            return i + params[0];
        }

        /**
         * 对应AsyncTask第二个参数
         * 在doInBackground方法当中,每次调用publishProgress方法都会中转(handler.sendMessage(...))到onProgressUpdate
         * 在主UI线程中,可以对控件进行修改
         *
         * @param values The values indicating progress.
         * @see #publishProgress
         * @see #doInBackground
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            int value = values[0];
            this.textview.setText(value+"%");
        }

        /**
         * 对应AsyncTask第三个参数 (接受doInBackground的返回值)
         * 在doInBackground方法执行结束之后在运行,此时已经回来主UI线程当中 能对UI控件进行修改
         *
         * @param s The result of the operation computed by {@link #doInBackground}.
         * @see #onPreExecute
         * @see #doInBackground
         * @see #onCancelled(Object)
         */
        @Override
        protected void onPostExecute(String s) {
            this.textview.setText("执行结束:" + s);
        }

        /**
         * 运行在主UI线程中,此时是预执行状态,下一步是doInBackground
         *
         * @see #onPostExecute
         * @see #doInBackground
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        /**
         * <p>Applications should preferably override {@link #onCancelled(Object)}.
         * This method is invoked by the default implementation of
         * {@link #onCancelled(Object)}.</p>
         * <p/>
         * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
         * {@link #doInBackground(Object[])} has finished.</p>
         *
         * @see #onCancelled(Object)
         * @see #cancel(boolean)
         * @see #isCancelled()
         */
        @Override
        protected void onCancelled() {
            super.onCancelled();
        }

    }
MAsyncTask mAsyncTask = new MAsyncTask(this.asyncTaskTV);
mAsyncTask.execute("%");

Handler post

Handler.post(Runnabel r)的原理:也就是调用了Handler.sendMessageDelayed(…)

Handler post 源码

    /**
     * Causes the Runnable r to be added to the message queue.
     * The runnable will be run on the thread to which this handler is 
     * attached. 
     *  
     * @param r The Runnable that will be executed.
     * 
     * @return Returns true if the Runnable was successfully placed in to the 
     *         message queue.  Returns false on failure, usually because the
     *         looper processing the message queue is exiting.
     */
    public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }

Handler post模板

    private TextView postHandlerTV;
    private final Runnable postRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            RefreshUIActivity.this.postHandlerTV.setText("Handler.post(...)");
        }
    };
Handler postHandler = new Handler();
postHandler.post(this.postRunnable);

Activity runOnUiThread

Activity.runOnUiThread(Runnable r)原理:如果是主UI线程,则直接调用post(Runnable r)方法,交给post()去处理线程,不是主UI线程则执行Runnable.start。

Activity runOnUiThread 源码

    /**
     * Runs the specified action on the UI thread. If the current thread is the UI
     * thread, then the action is executed immediately. If the current thread is
     * not the UI thread, the action is posted to the event queue of the UI thread.
     *
     * @param action the action to run on the UI thread
     */
    public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

Activity runOnUiThread 模板

    private TextView runOnUiThreadTV;
    private final Runnable uiRunnable = new Runnable() {
        @Override
        public void run() {
            RefreshUIActivity.this.runOnUiThreadTV.setText("success");
        }
    };
    private class MThread extends Thread{

        /**
         * Calls the <code>run()</code> method of the Runnable object the receiver
         * holds. If no Runnable is set, does nothing.
         *
         * @see Thread#start
         */
        @Override
        public void run() {
            RefreshUIActivity.this.runOnUiThread(RefreshUIActivity.this.uiRunnable);
        }
    }
    private final MThread runThread = new MThread();
this.runThread.start();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值