15.Android 异步更新UI 技巧

来源:互联网 发布:webuploader php后端 编辑:程序博客网 时间:2024/05/16 05:38

15.Android 异步更新UI 技巧

  • Android 异步更新UI 技巧
    • Handler消息传递
    • AsyncTask异步任务
    • Handler post
      • Handler post 源码
      • Handler post模板
    • Activity runOnUiThread
      • Activity runOnUiThread 源码
      • Activity runOnUiThread 模板


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();
0 0
原创粉丝点击