Android4.0 Toast显示问题分析_安卓4.0不支持uni.showtoast-程序员宅基地

技术标签: exception  null  string  android  thread  

在修复RUI桌面在4.0系统下的提示信息不完善的Bug过程的一些思路与大家分享一下。

Bug描述:

RUI在2.2的系统点击推荐图标下载后,就会进入下载队列中下载,如果再次点击相同的图标就会使用Toast提示“**已经在下载队列中”。但是在4.0的系统就会出现异常,第二次点击相同的推荐图标时没有出现Toast提示。

相关源码:

public static void showMessage(final Context act, final int gravity, final String msg) {
	    Toast.makeText(act, msg, Toast.LENGTH_SHORT).show();
		new Thread(new Runnable() {
			public void run() {
				handler.post(new Runnable() {
					@Override
					public void run() {
					    Log.v(TAG, "showMessage Runnable ThreadID: " + Thread.currentThread());
						synchronized (synLock) {
						    Log.v(TAG, "showMessage toast text: " + msg);
							if (toast != null) {
							    Log.v(TAG, "tosat != null");
							    // 修复4.0中推荐下载信息不完善
//								toast.cancel();
								toast.setText(msg);
								toast.setDuration(Toast.LENGTH_SHORT);
							} else {
								toast = Toast.makeText(act, msg, Toast.LENGTH_SHORT);
							}
//							toast.setGravity(gravity, 0, 0);
							try{
							    toast.show();
							} catch(Exception e) {
							    Log.d(TAG, "Exception " + e.getMessage());
							}
							Log.v(TAG, "toast: " + toast);
						}
					}
				});
			}
		}).start();
	}


分析Bug可能产生的原因:

1.      怀疑是context出现问题的原因。

因为Toast.makeText(Contextcontext, CharSequencetext, int duration)中有如下解释:

context The context to use. Usually yourandroid.app.Applicationor android.app.Activityobject.

而源码中传入的context是从NetworkService中传入的,所以怀疑这可能是出现Bug的原因。

我将context从Launcher中传入,Toast依然没有出现;直接Toast.makeText(act, msg, Toast.LENGTH_SHORT).show();结果出现Toast提示信息,所以不是context的原因。

2.      怀疑是互斥锁和handler.post()中的原因。

在代码中加入Log信息,从Log打印出来的信息可以得出已经运行到了互斥域内的代码。Log打印出来的运行线程是在主线程中,而且在run的代码中加入Toast.makeText(act, msg, Toast.LENGTH_SHORT),有Toast显示。所以排除了互斥锁和Handler.post()的原因。

 

 

经过上述分析后觉得很奇怪,就向其它人请教,让我慢慢调试。

后来看到cancel()的解释如下:

Closethe view if it's showing, or don't show it if it isn't showing yet. You do notnormally have to call this. Normally view will disappear on its own after theappropriate duration.

就怀疑问题出在这里。将代码toast.cancel()注释掉后运行,发现Toast提示信息出现,跟他人汇报后,提示“可以看看4.0中Toast的源码”。

 

下面是2.2和4.0中Toast源码的链接:

http://www.oschina.net/code/explore/android-2.2-froyo/android/widget/Toast.java

http://www.oschina.net/code/explore/android-4.0.1/core/java/android/widget/Toast.java

比较两者关于cancel()处理的差异发现了如下差异:

在4.0中如下:

final Runnable mHide = new Runnable() {

           public void run() {

                handleHide();

                // Don't do this in handleHide()because it is also invoked by handleShow()

                mNextView = null;

           }

       };

而2.2中没有mNextView = null;这一行代码。

再查看show()中有如下源码:

if (mNextView == null) {

           throw new RuntimeException("setView must have been called");

       }

 

所以判断产生的Bug的原因是2.2系统和4.0系统对cancel的处理的差异造成的,将cancel注释就可以正常显示了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sylcc_/article/details/7396452

智能推荐

Linux阅码场 - Linux内核月报(2020年06月)-程序员宅基地

文章浏览阅读1.4k次。关于Linux内核月报Linux阅码场Linux阅码场内核月报栏目,是汇总当月Linux内核社区最重要的一线开发动态,方便读者们更容易跟踪Linux内核的最前沿发展动向。限于篇幅,只会对..._memory tag

c++ pair make_pair_make_pair返回值-程序员宅基地

文章浏览阅读193次。pair 的用法std::pair主要的作用是将两个数据组合成一个数据,两个数据可以是同一类型或者不同类型。C++标准程序库中凡是“必须返回两个值”的函数, 也都会利用pair对象。class pair可以将两个值视为一个单元。容器类别map和multimap就是使用pairs来管理其健值/实值(key/value)的成对元素。pair被定义为struct,因此可直接存取pair中的个别值..._make_pair返回值

微信公众号开发工具汇总-程序员宅基地

文章浏览阅读8.4k次。前面写了篇入坑指南,介绍了下开发微信公众号的基本流程。最近又捣鼓了一阵,发现这开发工具的选择对于提高开发效率真是有莫大的帮助,所谓“只要工具选得好,月底奖金跑不了”。今天得空,笔者就给各位老哥列举几个绝对能派上用场的小工具,保证没毛病!微信公众平台技术文档这货实际上是必需品,没了它,您还真是寸步难行。官方文档包含了一个产品最直接也最全面的说明,在微信公众平台技术文档中,详细说明了微信公众号开发的概念_微信公众号开发工具

获得硬盘ID(序列号、机器码)的C++代码源码_硬盘id获取 c++-程序员宅基地

文章浏览阅读612次。获得硬盘的序列号(ID/机器码)的C++源码_硬盘id获取 c++

VRRP协议介绍_vrrp是什么协议-程序员宅基地

文章浏览阅读1w次,点赞5次,收藏60次。1.VRRP的工作原理2.Master路由器和Backup路由器3.VRRP报文格式4.虚拟路由器中的虚拟IP地址和虚拟MAC 地址_vrrp是什么协议

Google Earth Engine谷歌地球引擎GEE栅格代数与NDVI波段计算手动求取_gee波段计算-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏15次。  本文主要对GEE中的栅格代数与波段计算操作加以介绍。本文是谷歌地球引擎(Google Earth Engine,GEE)系列教学文章的第六篇,更多GEE文章请参考专栏:GEE学习与应用(https://blog.csdn.net/zhebushibiaoshifu/category_11081040.html)。  首先,依据第二篇GEE教学博客(https://blog.csdn.net/zhebushibiaoshifu/article/details/117296956)中内容,我们将Lands_gee波段计算

随便推点

Qt自定义控件9:波浪进度条1_qt 波浪进度球-程序员宅基地

文章浏览阅读502次。Qt自定义控件8:波浪进度条1先看效果图:思路:利用QPaintPath画出封闭路径,填充颜色,圆弧使用正弦函数,根据横坐标递增,画出正弦函数线。关键代码:void WaterProgressBar1::paintEvent(QPaintEvent *event){ int width = this->width(); int height = this->h..._qt 波浪进度球

5G协议批量下载 python3_批量下载3gpp 协议-程序员宅基地

文章浏览阅读673次。最近需要3GPP的5G协议,手动一个一个下载比较麻烦,抽空用python3写了个下载程序,可以从3gpp的ftp服务器批量下载协议文件。3GPP协议下载地址:https://www.3gpp.org/ftp/Specs/archive/38_series/代码使用了线程池,可以多线程从3gpp下载协议。代码流程:1、首先从下载地址获取要下载的所有文件的 文件名、url、大小、日期、本地存储地址,写入ini文件2、读取ini文件中的信息,使用线程池进行文件下载#coding:utf-_批量下载3gpp 协议

删除字符串中的所有相邻重复项python(leetcode1047)_python删除相邻字符,可得不同字符串-程序员宅基地

文章浏览阅读869次,点赞3次,收藏2次。删除字符串中的所有相邻重复项_python删除相邻字符,可得不同字符串

Python与各个编程语言对比_python 对比其他语言-程序员宅基地

文章浏览阅读134次。高级语言将与计算机架构的交互抽象化,你可以输入代码字(code word,比如 for 循环或变量定义),高级语言会将其编译成计算机可以执行的代码,而低级语言会直接处理这些代码字。有许多用 Python 编写的框架与 Node.js 类似,像 Flask 和 Django,但 Node.js 是用 JavaScript 语言编写的。正因为这一点,我们选择用 Python。同时学习 R(或 MATLAB)和 Python,你可以根据具体项目需求来选择使用哪种语言,这样可以更好地满足项目的需求,也更加方便。_python 对比其他语言

QGIS基本功 | 21 QGIS工程文件属性设置(2)——坐标参照系、变换、默认样式、数据源、关系和变量_qgis如何以原始坐标系-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏12次。今天继续分享工程文件属性的设置,包括工程坐标参照系、变换、默认样式、数据源、关系和变量六个部分。01坐标参照系工程坐标参照系定义了当前地图窗口所使用的坐标系,决定了如何将数据从其底层原始坐标绘制到QGIS地图画布中,并呈现为平面地图。QGIS支持自动动态投影,不管图层自带的坐标系是否与工程坐标系相同,均可自动重投影到当前工程坐标系,使数据可以正确叠加显示,这个过程对用户是完全透明的。因此,工程坐标系是各个图层正确显示的基础,为了使地图减少形变、正确反应现实世界地物的大小和相..._qgis如何以原始坐标系

我爱生煎包!--上海生煎-程序员宅基地

文章浏览阅读197次。对上海这个城市的印象,除了时尚、喧嚣、热闹,让人过目不忘的南京路上汹涌人潮,更多的是像电视剧《蜗居》中所展现出来的另一种风情。太阳初上的清晨,小弄堂里,各家各户陆续把自家大门打开,各自圾着拖鞋,拿着牙杯,走到公共水池边,开始洗漱。完事后,从家拿个小锅子,睡衣,去路边的小吃店买早饭。街边的那些小吃店,门口放着一个用汽油桶改造的大炉子,上面架着一个大大的平底锅,盖着厚实的木盖子,热气正袅袅的从锅中冒..._unable to open file 'calculatoreh.obj

推荐文章

热门文章

相关标签