Android4.0 Toast显示问题分析
来源:互联网 发布:怎么样注册淘宝店铺 编辑:程序博客网 时间:2024/05/18 03:06
在修复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() {@Overridepublic 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.Applicationorandroid.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注释就可以正常显示了。
- Android4.0 Toast显示问题分析
- Android4.0显示键盘问题
- Toast 多次显示问题
- Android4.0窗口机制token分析以及activitiy, dialog, toast 窗口创建过程分析
- Android4.0窗口机制token分析以及activitiy, dialog, toast 窗口创建过程分析
- Android4.0中控制Toast时间
- Android4.0中控制Toast时间
- Toast 不显示的问题
- Toast 多次创建显示问题
- Android Toast 重复显示问题
- Toast 多次创建显示问题
- Toast重复显示的问题
- 解决Toast不断显示问题
- Android toast重复显示问题
- Toast重复显示问题处理
- Android4.0 WifiP2p选项是否显示源码分析
- 解决android7.0+ 自定义Toast时长,但是toast不显示问题
- android4.0的edittext屏蔽输入法时候光标显示问题
- ARM9学习笔记之——SDRAM实验
- Serfj中文参考手册(自学版)
- java反射1——反射源头
- webrtc 编译运行官方文档http://www.webrtc.org/reference/getting-started
- 使用Thrift RPC编写程序 ---- 董的文章3
- Android4.0 Toast显示问题分析
- 关于VB的感想
- 最长公共子序列(LCS)问题
- 为什么不能在WM_CREATE中绘制
- flex 个人总结
- java反射2——Class类实例化的三种方法
- hunnu 11082 The Minesweeper Game(BFS)
- java反射3——类实例的方法1
- java反射3——类实例的方法2