Android 安卓烤面包片放在烤面包片的顶部-当顶部的烤面包片消失时,底部的烤面包片仍然存在
我的应用程序通过调用Android 安卓烤面包片放在烤面包片的顶部-当顶部的烤面包片消失时,底部的烤面包片仍然存在,android,toast,android-toast,Android,Toast,Android Toast,我的应用程序通过调用 Toast.makeText(getBaseContext(), "Blah", Toast.LENGTH_SHORT).show(); (好的,我使用资源id而不是字符串)。在我使用过的从4到7的每个安卓版本上,一切都很好,但是在安卓8.1.0中,如果在第一个版本消失之前出现第二个吐司,第一个会在第二个版本消失后恢复。我的猜测是,显示管理器正在记住烤面包下面的像素,并在烤面包消失时恢复它们,但它不够聪明,无法处理一堆烤面包,因此第二个“记住”第一个的图像,并将其恢复,而
Toast.makeText(getBaseContext(), "Blah", Toast.LENGTH_SHORT).show();
(好的,我使用资源id而不是字符串)。在我使用过的从4到7的每个安卓版本上,一切都很好,但是在安卓8.1.0中,如果在第一个版本消失之前出现第二个吐司,第一个会在第二个版本消失后恢复。我的猜测是,显示管理器正在记住烤面包下面的像素,并在烤面包消失时恢复它们,但它不够聪明,无法处理一堆烤面包,因此第二个“记住”第一个的图像,并将其恢复,而不是恢复底层的窗口区域
我可以使用一个“makeToast”包装器来解决这个问题,该包装器每次都将Toast对象隐藏在一个静态变量中,并在调用新对象之前对旧对象调用.cancel()
。这是最终的解决方案,还是有更好的方法
private static Toast lastToast;
private static Context toastContext; // set in onCreate
public static void makeToast(int resId, int duration) {
if (lastToast != null) lastToast.cancel();
lastToast = Toast.makeText(toastContext, resId, duration);
lastToast.show();
}
这为我解决了问题-我用自己的类包装了Toast,该类是在调用新对象之前调用的最后一个对象。看起来像是一次大规模的黑客攻击,但它确实完成了任务,只需要在我的应用程序的其余部分更改导入android.widget.Toast的
行
package my.app.hacks;
import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
public class Toast extends android.widget.Toast {
public static final int LENGTH_SHORT = android.widget.Toast.LENGTH_SHORT;
public static final int LENGTH_LONG = android.widget.Toast.LENGTH_LONG;
private static Toast lastShown;
public Toast(Context context) {
super(context);
}
public void show() {
if (lastShown != null) lastShown.cancel();
super.show();
lastShown = this;
}
public static Toast makeText(Context context, CharSequence text, int duration) {
//
// this is almost copy-n-pasted from android.widget.Toast.makeText()
//
Toast result = new Toast(context);
LayoutInflater inflate = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// we can't directly access com.android.internal.R identifiers so use the public interface
int layout = Resources.getSystem().getIdentifier("transient_notification", "layout", "android");
View v = inflate.inflate(layout, null);
int id = Resources.getSystem().getIdentifier("message", "id", "android");
TextView tv = (TextView)v.findViewById(id);
tv.setText(text);
// the original code accesses private members here - again, we have to use the public interface
result.setView(v);
result.setDuration(duration);
return result;
}
public static Toast makeText(Context context, int resId, int duration)
throws Resources.NotFoundException {
return makeText(context, context.getResources().getText(resId), duration);
}
}
我的行为和你不一样。。。如果我运行Toast.makeText(getBaseContext(),“Blah”,Toast.LENGTH_SHORT).show(),在一个全新的android应用程序上代码>Toast.makeText(getBaseContext(),“Blah2”,Toast.LENGTH_SHORT).show()代码>一个接一个,第一个被第二个所取代。我也看到了除了8.1.0之外,我使用过的所有android和设备的行为。我确实想知道线程上下文,所以我使用Handler.post()将调用推送到主UI线程上。问题依然存在。仔细观察屏幕,当第二片烤面包片溶解时,显示屏会短暂恢复到原来的状态,但随后底层烤面包片信息会全力以赴地重新出现,就好像第二片烤面包片下的像素抓取突然恢复一样。奇怪的真奇怪。。。我已经在安卓9上运行了测试,所以在你所使用的特定安卓版本中可能有一个bug,这是很有可能的!但是我明天真的需要让它工作起来,所以与设备供应商的争论可能不会解决这个问题:-)@Quinn我完全尝试了你的代码:-Toast.makeText(这个“fu”,Toast.LENGTH_SHORT).show()代码>Toast.makeText(这个“条”,Toast.LENGTH_SHORT).show()一个调用紧跟着另一个调用,因此完全相同的上下文。“巴”出现在“福”之上,当“巴”消失后,“福”又回来了。有些东西绝对是福巴!