如何在底层发送toast消息
2016-09-01 09:34
155 查看
问题:
在开发过程中,有如下需求,需要在协议层的最底层将服务器返回的错误信息toast出来,告知用户此次请求的错误,可是协议层底层是一个类,它没有上下文参数(context),按正常思路就是将context参数从activity层往下传到需要context的层,可是目前工程的框架已经定下来,从activity到协议层有四五层,这样一层一层地传费时,并且要将工程所有的activity都加一遍,这个工程量是非常巨大的!于是查询了一些资料,试一下能否使用全局的context来toast。
使用了myapplication保存下来的context,发现报错了Can't
create handler inside thread that has not called Looper.prepare()
一般来说toast是要运行在activity才能够show出来,这次使用了全局的context显然是不行的。看一下toast的内部机制
Toast
public void show()
{
...
service.enqueueToast(pkg, tn, mDuration);
//把这个toast插入到一个队列里面
...
}
Looper
public static final void prepare()
{
if (sThreadLocal.get() != null)
{
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
//在当前线程中创建一个Looper
}
private Looper() {
mQueue = new MessageQueue();
//关键在这,创建Looper都干了什么。 其实是创建了消息队列
mRun = true;
mThread = Thread.currentThread();
}
一般如果不是在主线程中又开启了新线程的话,一般都会碰到这个问题。
原因是在创建新线程的时候默认情况下不会去创建新的MessageQueue。
主线程能够toast是因为安卓封装过程中,将一个消息队列跟activity绑定了,所以可以直接使用toast.show()
于是只要在我们的代码中加上
Looper.prepare();
Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_LONG).show();
Looper.loop();
Looper.myLooper().quit();即可
总结下:Toast 显示的必要条件:
Toast 显示需要出现在一个线程的消息队列中
在开发过程中,有如下需求,需要在协议层的最底层将服务器返回的错误信息toast出来,告知用户此次请求的错误,可是协议层底层是一个类,它没有上下文参数(context),按正常思路就是将context参数从activity层往下传到需要context的层,可是目前工程的框架已经定下来,从activity到协议层有四五层,这样一层一层地传费时,并且要将工程所有的activity都加一遍,这个工程量是非常巨大的!于是查询了一些资料,试一下能否使用全局的context来toast。
使用了myapplication保存下来的context,发现报错了Can't
create handler inside thread that has not called Looper.prepare()
一般来说toast是要运行在activity才能够show出来,这次使用了全局的context显然是不行的。看一下toast的内部机制
Toast
public void show()
{
...
service.enqueueToast(pkg, tn, mDuration);
//把这个toast插入到一个队列里面
...
}
Looper
public static final void prepare()
{
if (sThreadLocal.get() != null)
{
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
//在当前线程中创建一个Looper
}
private Looper() {
mQueue = new MessageQueue();
//关键在这,创建Looper都干了什么。 其实是创建了消息队列
mRun = true;
mThread = Thread.currentThread();
}
一般如果不是在主线程中又开启了新线程的话,一般都会碰到这个问题。
原因是在创建新线程的时候默认情况下不会去创建新的MessageQueue。
主线程能够toast是因为安卓封装过程中,将一个消息队列跟activity绑定了,所以可以直接使用toast.show()
于是只要在我们的代码中加上
Looper.prepare();
Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_LONG).show();
Looper.loop();
Looper.myLooper().quit();即可
总结下:Toast 显示的必要条件:
Toast 显示需要出现在一个线程的消息队列中
相关文章推荐
- 如何给另一个桌面的程序发送消息?
- 控件间如何发送消息
- 如何向CEDIT发送EN_CHANGE消息
- BCB 如何实现在不同的程序间发送和响应自定义消息?
- 如何向SysListView32里的某一行发送双击消息
- 如何调用NetMessageBufferSend发送消息?(改编)
- 如何在Qt中处理(接收/发送)MFC或Windows消息(message)
- SQL Server:如何在Service Broker发送消息验证失败后获取源消息
- SQL Server:如何在Service Broker发送消息验证失败后获取源消息
- Android: 如何利用Handler处理和发送消息来实现页面刷新的功能
- VB:如何发送WM_KEYDOWN和WM_KEYUP消息
- 如何调用NetMessageBufferSend发送消息?(改编)
- 如何利用jgroups实现分布式环境下消息的接受和发送
- 如何更改msn发送消息的快捷键
- 如何让你的系统具有向外发送手机短信或即时消息的功能?
- 如何利用jgroups实现分布式环境下消息的接受和发送
- 如何设置loadrunner ,使得发送消息时保持长连接
- NET中如何发送广播消息
- 如何在WCF中用TcpTrace工具查看发送和接收的SOAP消息
- Socket编程中如何发送结构体,拼接多次接收消息及获取通信双方地址