handler怎样更新UI线程中的数据
在安卓开发中,用handler传递数据时,如果不用内部类,写在独立的一个类里面,出了把UI线程中的变量设置成静态的,还有什么方法可以将子线程中的数据更新到主线程中?...
在安卓开发中,用handler传递数据时,如果不用内部类,写在独立的一个类里面,出了把UI线程中的变量设置成静态的,还有什么方法可以将子线程中的数据更新到主线程中?
展开
1个回答
展开全部
之前用过android-async-http,虽然没认真看过源码,但也有简单的浏览过,心里一直有个疑问,因为android-async-http也是采用hanlder机制来执行回调的,也就是说handler是它实例化的,可我们知道handler的一个重要作用是将一个任务切换到handler所在的线程去执行的,我的疑问就是:如果我们在子线程调用android-async-http的网络请求,这时候如果handler是在子线程被实例化的呢(当然我没认真研究过源码,也不知道它是怎么实现),还能更新UI吗?
我们都正常以为handler在哪个线程实例化的,我们通过handler就可以把任务切换到该任务去执行,我们看如下代码:
private void initd() {
new Thread(new Runnable() {
@Override
public
void run() {
Looper.prepare();
Handler handler = new
Handler() {
@Override
public void handleMessage(Message msg) {
Toast.makeText(MainActivity.this, "测试子线程弹出toast",
Toast.LENGTH_LONG).show();
((TextView)findViewById(R.id.main_tv_text)).setText("测试子线程");
}
};
Looper.loop();
handler.sendEmptyMessage(0);
}
}).start();
}
经过我的测试上面这段方法是无法更新UI的,因为handler是在子线程实例化的,并非在UI线程,也证实了我们的想法。
如果我的疑问存在(我没尝试过在子线程使用android-async-http,不知道什么情况,这里只是做个假设),那么它使怎么实现的呢。
最近看了android开发艺术探索,特意去研究了一下android的消息机制,才弄明白了Handler的工作原理,其实起关键作用的是Looper并不是handler,我们先来看下Looper的构造方法:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Looper会把所在的当前的线程保存起来,而handler的工作需要Looper,于是我尝试了一下如下代码:
private void init() {
new Thread(new Runnable() {
@Override
public
void run() {
Handler handler = new
Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
Toast.makeText(MainActivity.this, "测试子线程弹出toast",
Toast.LENGTH_LONG).show();
((TextView)findViewById(R.id.main_tv_text)).setText("测试子线程");
}
};
handler.sendEmptyMessage(0);
}
}).start();
}
handler实例化的时候,我传入的是UI线程的Looper,确实是可以更新UI。
总结:
1、handler执行任务不是在它实例化所在的线程决定的,而是关键在于Looper。
2、我们可以在子线程实例化handler并且可以用它来更新UI了。
我们都正常以为handler在哪个线程实例化的,我们通过handler就可以把任务切换到该任务去执行,我们看如下代码:
private void initd() {
new Thread(new Runnable() {
@Override
public
void run() {
Looper.prepare();
Handler handler = new
Handler() {
@Override
public void handleMessage(Message msg) {
Toast.makeText(MainActivity.this, "测试子线程弹出toast",
Toast.LENGTH_LONG).show();
((TextView)findViewById(R.id.main_tv_text)).setText("测试子线程");
}
};
Looper.loop();
handler.sendEmptyMessage(0);
}
}).start();
}
经过我的测试上面这段方法是无法更新UI的,因为handler是在子线程实例化的,并非在UI线程,也证实了我们的想法。
如果我的疑问存在(我没尝试过在子线程使用android-async-http,不知道什么情况,这里只是做个假设),那么它使怎么实现的呢。
最近看了android开发艺术探索,特意去研究了一下android的消息机制,才弄明白了Handler的工作原理,其实起关键作用的是Looper并不是handler,我们先来看下Looper的构造方法:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Looper会把所在的当前的线程保存起来,而handler的工作需要Looper,于是我尝试了一下如下代码:
private void init() {
new Thread(new Runnable() {
@Override
public
void run() {
Handler handler = new
Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
Toast.makeText(MainActivity.this, "测试子线程弹出toast",
Toast.LENGTH_LONG).show();
((TextView)findViewById(R.id.main_tv_text)).setText("测试子线程");
}
};
handler.sendEmptyMessage(0);
}
}).start();
}
handler实例化的时候,我传入的是UI线程的Looper,确实是可以更新UI。
总结:
1、handler执行任务不是在它实例化所在的线程决定的,而是关键在于Looper。
2、我们可以在子线程实例化handler并且可以用它来更新UI了。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询