zoukankan      html  css  js  c++  java
  • 实现RunOnUiThread和RunOnUiThreadBlock

    现在需要实现一个工具类,RunUtils,这个类中包含runOnUiThread(Context context, Runnable runnable)和runOnUiThreadBlock(Context context, Runnable runnable)两个方法。两个方法都使runnable在UI线程执行,runOnUiThread立即返回,runOnUiThreadBlock等待runnable执行完毕后才返回。

    根据context创建一个Handler,这个Handler用于发送消息。runOnUiThread这个方法不需要同步,runOnUiThreadBlock需要同步。

    RunUtils内容

    package com.letv.handlertest;
    
    import android.content.Context;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    
    import java.lang.ref.WeakReference;
    
    public class RunUtils {
    
        private static final int WHAT_BLOCK = 0x1001;
    
        private static WeakReference<Context> weakContext;
        private static WeakReference<Handler> weakHandler;
        private static Object lock = new Object();
    
        private static void init(Context context){
            if(RunUtils.weakContext == null ||
                    (RunUtils.weakContext!=null && RunUtils.weakContext.get()!=context) ){
                RunUtils.weakContext = new WeakReference<Context>(context);
    
                Handler handler = new Handler(context.getMainLooper()) {
                    @Override
                    public void dispatchMessage(Message msg) {
                        if(msg.what == WHAT_BLOCK){
                            Log.i(MainActivity.TAG, "what block");
                            synchronized (lock){
                                super.dispatchMessage(msg);
                                lock.notify();
                                Log.i(MainActivity.TAG, "notify");
                            }
                        }
                        else{
                            super.dispatchMessage(msg);
                            Log.i(MainActivity.TAG, "what not block");
                        }
                    }
                };
                weakHandler = new WeakReference<Handler>(handler);
                handler = null;
            }
        }
    
        public static void runOnUiThread(Context context, Runnable runnable){
            init(context);
            weakHandler.get().post(runnable);
            Log.i(MainActivity.TAG, "run ui over!");
        }
    
        public static void runOnUiThreadBlock(Context context, Runnable runnable){
            init(context);
    
            Message msg = Message.obtain(weakHandler.get(), runnable);
            msg.what = WHAT_BLOCK;
            msg.sendToTarget();
    
            synchronized (lock){
                Log.i(MainActivity.TAG, "begin wait!");
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.i(MainActivity.TAG, "run ui block over!");
            }
        }
    
    }
    

      主类MainActivity内容

    package com.letv.handlertest;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    public class MainActivity extends Activity implements View.OnClickListener {
    
        public static final String TAG = "HandlerTest";
    
        private Button btnRunOnUiThread, btnRunOnUiThreadBlock;
        private TextView tvShow1, tvShow2;
    //    private RunUtilsB utils;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
    
    //        utils = new RunUtilsB(this);
        }
    
        private void initView(){
            btnRunOnUiThread = (Button)findViewById(R.id.btnRunOnUiThread);
            btnRunOnUiThreadBlock = (Button)findViewById(R.id.btnRunOnUiThreadBlock);
            tvShow1 = (TextView)findViewById(R.id.tvShow1);
            tvShow2 = (TextView)findViewById(R.id.tvShow2);
    
            btnRunOnUiThread.setOnClickListener(this);
            btnRunOnUiThreadBlock.setOnClickListener(this);
        }
    
        private void runUi(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    RunUtils.runOnUiThread(MainActivity.this, new Runnable() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(2000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            tvShow1.setText("run ui");
                        }
                    });
                }
            }).start();
        }
    
        private void runUiBlock(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    RunUtils.runOnUiThreadBlock(MainActivity.this, new Runnable() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(2000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            tvShow2.setText("run ui block");
                        }
                    });
                }
            }).start();
        }
    
        @Override
        public void onClick(View v) {
            if(v == btnRunOnUiThread){
                runUi();
            }
            else if(v == btnRunOnUiThreadBlock){
                runUiBlock();
            }
        }
    }
    

    运行结果正常。点击RunOnUiThread实现2s后更新textView1的值,点击调用后立马返回,点击RunOnUiThreadBlock后实现2s后更新textView2的值,更新完后才返回。

  • 相关阅读:
    netty入门
    zookeeper安装
    nginx
    链式调用方法的实现原理和方法
    UI设计篇·入门篇·简单动画的实现,为布局设置动画,用XML布置布局动画
    UI设计篇·入门篇·简单动画的实现,透明动画/旋转动画/移动动画/缩放动画,混合动画效果的实现,为动画设置监听事件,自定义动画的方法
    UI设计篇·入门篇·绘制简单自定义矩形图/设置按钮按下弹起颜色变化/设置图形旋转
    XML文档的生成和解析操作方法
    ListView的基本使用方法和RecyclerView的基本使用方法
    Fragment的粗浅理解
  • 原文地址:https://www.cnblogs.com/MiniHouse/p/6701168.html
Copyright © 2011-2022 走看看