Andoird主子线程通信,子线程不能更新UI,4大方法子线程更新UI

考虑这个问题的原因:子线程不能更新UI


子线程向主线程传值:发送消息

new Thread() {
public void run() {
        Message message = new Message();
        message.obj = "你好主线程,我是子线程";
        mHandler .sendMessage(message);
        };
        }.start();

(讲一下handler的另一个方法,post,是直接post一个线程进队列,逻辑线程自己执行。)

所以只要在主线程里接受一下就可以更新UI了

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
       //更新UI
    }
};  

下面借鉴自http://blog.csdn.net/shaoenxiao/article/details/54561753?utm_source=itdadao&utm_medium=referral

主线程向子线程传值:

这个时候需要为子线程创建一个looper(主线程中是不需要的,本来就封装好的)

class MyThread extends Thread{
    private Looper looper;//取出该子线程的Looper
    public void run() {

        Looper.prepare();//创建该子线程的Looper
        looper = Looper.myLooper();//取出该子线程的Looper
        Looper.loop();//只要调用了该方法才能不断循环取出消息
    }
}

然后子线程有了looper,handler就可以指定消息发到这个线程里了

private Handler mHandler;//mHandler指定轮询的Looper

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    thread = new MyThread();
    thread.start();//千万别忘记开启这个线程
    //下面是主线程发送消息
    mHandler = new Handler(thread.looper){
        public void handleMessage(android.os.Message msg) {
            Log.d("当前子线程是----->",Thread.currentThread()+"");
        };
    };
    mHandler.sendEmptyMessage(1);
}
但是代码是有错的,很容易就知道是空指针。子线程的looper用来告诉handler消息要发送到哪。thread.looper。主线程执行到这里的时候,虽然那个子线程已经开启了,但是他绝对没有主线程跑得快,所以就空指针了。


这个时候主线程等待子线程肯定是不正确的做法,用一个while循环也是一个不太可行的做法,用HandlerThread是最优的选项。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    tv = new TextView(this);
    tv.setText("Handler实验");
    setContentView(tv);

    //实例化一个特殊的线程HandlerThread,必须给其指定一个名字
    HandlerThread thread = new HandlerThread("handler thread");
    thread.start();//千万不要忘记开启这个线程
    //mHandlerthread相关联
    mHandler = new Handler(thread.getLooper()){
        public void handleMessage(android.os.Message msg) {
            Log.d("当前子线程是----->", Thread.currentThread()+"");
        };
    };
    mHandler.sendEmptyMessage(1);//发送消息
}
他的源码是一直等到这个子线程的looper对象被创建出来以后才会执行后续代码。


子线程间的通信:(最好学一下AIDL)

就是声明一个成员变量的handler,两个子线程间公用它就行了。一个负责new出那个handler,一个使用那个handler。

new Thread(new Runnable() {

@Override
public void run() {
        String msg;
        Looper.prepare();

        childHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
        super.handleMessage(msg);

        System.out.println("这个消息是从-->>" + msg.obj+ "过来的,在" + "btn的子线程当中" + "中执行的");

        }

        };
        Looper.loop();//开始轮循

        }
        }).start();   

new Thread(new Runnable() {

@Override
public void run() {
        Looper loop = Looper.myLooper();
        Message msg = childHandler.obtainMessage();
        msg.obj = "btn2当中子线程";
        childHandler.sendMessage(msg);
        }
        }).start();


还有在子线程中更新UI还可以About_Activity.this.runOnUiThread(new Runnable() ,asynctask


最后总结下

1.mHandler.post

2.mHandler.sendMessage

3.runOnUiThread(本质上也是调用了post)

4.view.post(view自己封装的异步机制)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值