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

智能推荐

14.真刀实枪做项目---博客系统(页面设计)-程序员宅基地

文章浏览阅读2.3k次,点赞80次,收藏76次。本次文章是博客系统项目文章,从0开始讲解怎么一步一步到1来完成一个博客系统网站的搭建,搭建完成后,我们可以从本地服务器上查询到我们的网站,部署到网站上的项目敬请参考之后的文章博客系统终章!!!

【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果,复制粘贴即用_charactercontroller 实现跳跃-程序员宅基地

文章浏览阅读6k次,点赞76次,收藏141次。其实一开始我是不打算写的,我感觉这种简单的功能,网上随便一搜一大堆,但是我发现网上很多都是复制粘贴,要么没有实操过,要么就是功能不全,或者毫无解释的把代码丢出来,我自以为简单的3D角色控制,我整整花了3-4天才研究明白(虽然每天只花几个小时),下面是记录我的一些思路过程,希望对你有帮助。【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1。_charactercontroller 实现跳跃

2019年前端技术有哪些新趋势_前端最新技术有哪些-程序员宅基地

文章浏览阅读290次。前端技术的更新迭代是所有技术里面是最快的,19年你变秃了吗?本文盘点2018-2019年比较热的技术点,大家好根据前端发展趋势对自己的技术栈做一定规划,抓住重点。1、Vue, React, AngularVue 在 2018、2019 年继续增长,其在 GitHub Stars 已经超过了 React ,国内公司更喜欢 Vue。虽然 Angular 与 React 和 V..._前端最新技术有哪些

Docker_实用篇_从入到高级_doker容器可以放不同的系统吗-程序员宅基地

文章浏览阅读213次。Docker实用篇_从入到高级Docker实用篇0.学习目标1.初识Docker1.1.什么是Docker1.1.1.应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结1.2.Docker和虚拟机的区别1.3.Docker架构1.3.1.镜像和容器1.3.2.DockerHub1.3.3.Docker架构1.3.4.小结1.4.安装Docker2.Docker的基本操作2.1.镜像操作2.1.1.镜像名称_doker容器可以放不同的系统吗

C语言分支和循环_c语言if else双重循环怎么用-程序员宅基地

文章浏览阅读926次,点赞24次,收藏18次。当计算机编译到if语句时会先对condition进行判断,当condition真命题时,会进入到if语句中依次向下执行语句,否则跳过if。当condition是布尔类型true即为真flase为假。我们还要知道在C语言中,数字与布尔类型的转换,非0数字代表true,0代表flase。//不加{}if就只能控制一条语句,下面各语句类似当表达式为真时,执行if语句,当表达式为假时,执行else语句。例1.输入两个数啊a,b,将较大的数输出。_c语言if else双重循环怎么用

go sync.pool优化测试-程序员宅基地

文章浏览阅读390次。最近在工作中,频繁用到一些结构体的申请,内存会频繁的进行释放和申请,于是想尝试一下sync.pool的优化效果。sync.pool,需要初始化 Pool,唯一需要的就是设置好 New 函数。当调用 Get 方法时,如果池子里缓存了对象,就直接返回缓存的对象。如果没有存货,则调用 New 函数创建一个新的对象。另外,我们发现 Get 方法取出来的对象和上次 Put 进去的对象实际上是同一个,Pool 没有做任何“清空”的处理。但我们不应当对此有任何假设,因为在实际的并发使用场景中,无法保证这种顺序,最_sync.pool优化

随便推点

fastapi 入门系列-程序员宅基地

文章浏览阅读7k次,点赞10次,收藏58次。FastAPI是一个现代、快速(高性能)的Web框架,用于构建API。它基于Python 3.7+的类型提示(type hints)和异步编程(asyncio)能力,使得代码易于编写、阅读和维护。FastAPI具有自动交互式文档(基于OpenAPI规范和JSON Schema)、数据验证、依赖注入(Dependency Injection)等功能,这些功能使得API的开发速度更快、更可靠。FastAPI还支持WebSocket和GraphQL,可以轻松地扩展到更复杂的应用场景。_fastapi

Android中使用http实现注册登录 1_andriodhttp协议登录信息-程序员宅基地

文章浏览阅读1w次。转载在项目中实现注册登录有很多种方式,一般对于初学者来说,不使用框架,采用http的post和get请求后台服务器,是一种更好理解底层源码的方式。使用框架实现注册登录虽然比自己封装post和get请求后台方便,但是不利于我们更好地理解其中的原理和机制。 实现的步骤大致分为以下几点: 1. 创建HttpPost对象,并将服务器接口地址url设置好。 2. 利用Name_andriodhttp协议登录信息

BAPI_SALESDOCU_CREATEFROMDATA1--VA01_bapisdhead1-程序员宅基地

文章浏览阅读361次。 实例1:REPORT Z_ORDER_CREATE_SPA_HBR.*----------------------------------------------------------------------** Parameters*----------------------------------------------------------------------*Parame_bapisdhead1

vue2.0 自定义组件的方法(vue组件的封装)_vue object 自定义对象中封装一个方法-程序员宅基地

文章浏览阅读799次。https://www.jb51.net/article/141458.htm这篇文章主要介绍了vue2.0 自定义组件的方法(vue组件的封装),本文通过实例代码相结合的形式给大家介绍的非常详细,需要的朋友可以参考下一、前言之前的博客聊过 vue2.0和react的技术选型;聊过vue的axios封装和vuex使用。今天简单聊聊 vue 组件的封装。vue 的ui框架现在是很多的,但是鉴于移动设备的复杂性,兼容性问题突出。像 Mint-UI 等说实话很不错了,但是坑也是不少,而且很多功能也_vue object 自定义对象中封装一个方法

Python实现一键生成微信好友头像墙_头像墙 自动生成-程序员宅基地

文章浏览阅读375次。效果图:具体代码实现如下:# -*- coding: utf-8 -*-from wxpy import *import mathfrom PIL import Imageimport os"""更多内容,请关注微信公众号:陈工的编程笔记"""# 创建头像存放文件夹def creat_filepath(): avatar_dir = os.getcwd(..._头像墙 自动生成

CISCO ASA安全应用问题集锦全集(51-69)-程序员宅基地

文章浏览阅读396次。问题编号:50提问内容: 我的pix os是7.22pix525# sh verCiscoPIXSecurityAppliance Software Version 7.2(2)但是没有DISABLE ESMTP这条命令pix525(config)# disable ?exec mode commands/options:回答内容:policy-map globa..._思科 asa inspect sip