您的位置:首页 > 其它

如何在底层发送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