奇特:子线程的Toast怎么显示不出来?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了奇特:子线程的Toast怎么显示不出来?相关的知识,希望对你有一定的参考价值。
我在子线程的run()中想显示Toast:……Toast.makeText(MainActivity.this,"This is a toast~~",Toast.LENGTH.SHORT).show();Log.d(TAG, "has excuted here~~");……发现log都显示出来了,但是Toast显示不出来,请教下大家,是什么原因?
因为Toast在创建的时候会依赖于一个Handler,并且一个Handler是需要有一个Looper才能够创建,而普通的线程是不会自动去创建一个Looper对象,比如说在某个Activity中能new一个Handler是因为android系统在启动一个Activity的时候会默认的创建一个Looper对象,因此不能够在子线程中显示Toast,你可以在开启的子线程中执行Looper.prepare()来构建一个Looper,然后在显示Toast,但是不要忘记执行Looper.loop()来加载这个Looper,当然,也可以使用主线程的Looper,获取主线程的Looper的方法是Looper.getMainLooper();同时需要注意的是,同样的不能在子线程中去更新UI界面,因为Toast是相对独立于UI界面的,就好比应用虽然crash掉了,并且已经返回到home界面,但是Toast依然会在hone界面显示出来。 参考技术A 晕,在子线程不能操作任何组件,你调用activity方法里面的runOnUIThread()就可以toast了 参考技术B 在Toast前调用loop.prare之后调用loop.looper。就可以了。 参考技术C Looper.prepare(); Toast.makeText(getActivity(), "十秒钟后", Toast.LENGTH_SHORT) .show(); Looper.loop(); 参考技术D 子线程里不能做此类操作,你在handler里面做toast显示塞!![Java Concurrent] 多线程合作 producer-consumers / queue 的简单案例
在多线程环境下,通过 BlockingQueue,实现生产者-消费者场景。
Toast 被生产和消费的对象。
ToastQueue 继承了 LinkedblockingQueue ,用于中间存储 Toast 。
Producer 生产 Toast ,并将生产出来的 Toast 放进队列 initialToastQ 中。
Processor 加工 Toast,从 initialToastQ 中获得生产出来的 Toast,将其加工并放进队列 finishedToast 中。
Consumer 消费 Toast,从 finishedToastQ 中获得加工完成的 Toast。
ThreadHelper 工具类,用于输出线程相关信息。
ProducerConsumerDemo 演示这个场景
代码实现:
Toast 实现
public class Toast { private int id; public Toast(int id){ this.id = id; } public String toString(){ return " toast#" + id; } }
ToastQueue 实现
import java.util.concurrent.LinkedBlockingQueue; public class ToastQueue extends LinkedBlockingQueue<Toast> { private static final long serialVersionUID = 1L; }
Producer 循环生产 Toast
import java.util.concurrent.TimeUnit; public class Producer implements Runnable { private ToastQueue toastQueue; private int count; public Producer(ToastQueue toastQueue){ this.toastQueue = toastQueue; this.count = 0; } @Override public void run() { try { while (true){ TimeUnit.MILLISECONDS.sleep(100); Toast toast = new Toast(count); count++; toastQueue.put(toast); ThreadHelper.print(" produced " + toast); } }catch (InterruptedException e) { e.printStackTrace(); } } }
Processor 从 intialToastQ 获得 Toast ,对其加工,并放进 finishedToastQ 中。
import java.util.concurrent.TimeUnit; public class Processor implements Runnable { private ToastQueue initialToastQ; private ToastQueue finishedToastQ; public Processor(ToastQueue initialToastQ, ToastQueue finishedToastQ){ this.initialToastQ = initialToastQ; this.finishedToastQ = finishedToastQ; } @Override public void run() { try { while (true){ Toast toast = initialToastQ.take(); ThreadHelper.print(" processing " + toast); TimeUnit.MILLISECONDS.sleep(180); finishedToastQ.put(toast); } }catch (InterruptedException e) { e.printStackTrace(); } } }
Consumer 消耗 Toast
public class Consumer implements Runnable { private ToastQueue finishedToastQ; public Consumer(ToastQueue finishedToastQ){ this.finishedToastQ = finishedToastQ; } @Override public void run() { try { while (true){ Toast toast = finishedToastQ.take(); ThreadHelper.print(" consumed " + toast); } }catch (InterruptedException e) { e.printStackTrace(); } } }
ThreadHelper 线程帮助类
public class ThreadHelper { public static void print(String msg){ System.out.println("[" + Thread.currentThread().getName() + " ] " + msg); } }
演示烤面包的生产、加工、消费的场景
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class ProducerConsumerDemo { public static void main() throws InterruptedException{ ToastQueue initialToastQ = new ToastQueue(); ToastQueue finishedToastQ = new ToastQueue(); ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new Producer(initialToastQ)); exec.execute(new Processor(initialToastQ, finishedToastQ)); exec.execute(new Consumer(finishedToastQ)); TimeUnit.SECONDS.sleep(2); exec.shutdownNow(); } }
输出结果:
[pool-1-thread-2 ] processing toast#0 [pool-1-thread-1 ] produced toast#0 [pool-1-thread-1 ] produced toast#1 [pool-1-thread-2 ] processing toast#1 [pool-1-thread-3 ] consumed toast#0 [pool-1-thread-1 ] produced toast#2 [pool-1-thread-1 ] produced toast#3 [pool-1-thread-2 ] processing toast#2 [pool-1-thread-3 ] consumed toast#1 [pool-1-thread-1 ] produced toast#4 [pool-1-thread-1 ] produced toast#5 [pool-1-thread-2 ] processing toast#3 [pool-1-thread-3 ] consumed toast#2 [pool-1-thread-1 ] produced toast#6 [pool-1-thread-1 ] produced toast#7 [pool-1-thread-2 ] processing toast#4 [pool-1-thread-3 ] consumed toast#3 [pool-1-thread-1 ] produced toast#8 [pool-1-thread-2 ] processing toast#5 [pool-1-thread-3 ] consumed toast#4 [pool-1-thread-1 ] produced toast#9 [pool-1-thread-1 ] produced toast#10 [pool-1-thread-2 ] processing toast#6 [pool-1-thread-3 ] consumed toast#5 [pool-1-thread-1 ] produced toast#11 [pool-1-thread-1 ] produced toast#12 [pool-1-thread-2 ] processing toast#7 [pool-1-thread-3 ] consumed toast#6 [pool-1-thread-1 ] produced toast#13 [pool-1-thread-1 ] produced toast#14 [pool-1-thread-2 ] processing toast#8 [pool-1-thread-3 ] consumed toast#7 [pool-1-thread-1 ] produced toast#15 [pool-1-thread-1 ] produced toast#16 [pool-1-thread-2 ] processing toast#9 [pool-1-thread-3 ] consumed toast#8 [pool-1-thread-1 ] produced toast#17 [pool-1-thread-2 ] processing toast#10 [pool-1-thread-3 ] consumed toast#9 [pool-1-thread-1 ] produced toast#18 java.lang.InterruptedException at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2048) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at concurrencyProducerConsumer.Consumer.run(Consumer.java:15) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at concurrencyProducerConsumer.Producer.run(Producer.java:19) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at concurrencyProducerConsumer.Processor.run(Processor.java:24) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
参考资料
Page 868, Produer-consumers and queue, Thinking in Java
以上是关于奇特:子线程的Toast怎么显示不出来?的主要内容,如果未能解决你的问题,请参考以下文章