android APP 的work thread怎么不能更新UI的问题求解

本文探讨了Java中异步线程的工作原理及如何通过回调机制实现远程方法调用。重点介绍了如何避免在工作线程中直接更新UI,提出了使用Handler对象和Activity.runOnUiThread(Runnable)两种有效的方法。

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

java中的异步线程回调方法实现


这个问题一直环绕在我的脑海里,android APP 的work thread怎么不能更新UI

一.实现workthread 调用远程方法
二.实现远程方法执行完后调用回调方法
三.判断回调方法是否执行在workthread
四.android异步线程更新UI的方式总结
五.后台服务怎么跟前台UI解耦




/**
 * 回调接口
 * */
public interface CallBack {
    void execute(Object... objects);
}

/**
 * 远程方法
 * */
public class Remote {
    public void executeMessage(String msg,final CallBack callBack){
        for(int i=0;i < 1000;i++){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("remote excute msg:"+msg);
        msg = msg+" change...";
        callBack.execute(msg);
    }
}


/**
本地对象
*/
public class Local implements CallBack{
    public String message;
    public Local() {
    }
    public Local(String message){
        this.message = message;
    }
    /**
     * 执行异步调用
     * */
    public void sendMessage(){
        System.out.println("start..");
        Thread thread = new Thread(new WorkThread(new Remote(),this));
        thread.start();
    }

    public static void main(String[] args) {
        Local local = new Local("hello World");
        local.sendMessage();
        System.out.println("main thread exec complete...");
        //主线程虽然执行完成,但是不会结束,在线程栈里,他启动的子线程没有结束,主线程不会结束
        //console output:
        //start..
        //main thread exec complete...
        // current thread:Thread-0
        //remote excute msg:hello World
        //receive from workthread data:hello World change...
        // current thread:Thread-0
        //callback done!
        //由此可见回调函数是运行在工作线程里的. android里的回调函数里不能更新UI,就是因为这个原因
        //工作线程没有UI线程的对象句柄
    }
    //回调接口方法
    @Override
    public void execute(Object... objects) {
        System.out.println("receive from workthread data:"+objects[0]);
        System.out.println(" current thread:"+Thread.currentThread().getName());
        System.out.println("callback done!");
        }

    /**
    工作线程
**/
    class WorkThread implements Runnable{
        Remote mremote;
        CallBack callback;
        /**
         * @param remote 远程对象
         * @param call 回调接口
         * */
        public WorkThread(Remote remote,CallBack call){
            this.mremote=remote;
            this.callback=call;
        }
    @Override
    public void run() {
        System.out.println(" current thread:"+Thread.currentThread().getName());
        mremote.executeMessage(message,callback);
    }
    }
}

上面的代码可以得到一个结论,在UI线程编写的回调接口实现是 运行在工作线程里的,所以在回调方法里面更新UI会导致线程报错.

如何正确在工作线程实现更新Ui呢

一.通过handler对象,在异步线程里面handler.sendMessage(),因为异步线程与UI线程公用一个handler对象.handler可以传递数据,ui的更新还是在主线程中.
二.利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)
Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程。

service与Ui解耦

1.通过broadcast receiver
2.通过Ui上注册事件响应监听器队列监听器(响应回调),后台service循环事件队列调用事件回调.
3….还没想到

4/26/2018 23:28

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值