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