美文网首页
一个“Toast”引发的bug

一个“Toast”引发的bug

作者: MarkShaun | 来源:发表于2016-03-31 15:46 被阅读880次

    哈哈,蛮开心的,今天收到了简友的第一个喜欢,谢谢~
    相信大家都用过Toast提示:Toast.makeText(context,message, duration).show();一行很简单的代码。但是有一个问题就是,当我频繁操作一个按钮的时候,就会看到Toast一直显示,甚至有时候跳出这个Activity或者是App它还是按照顺序逐一显示。今天优化代码,又想到了这个问题,所以就上网查了一下,搜索到这么一篇文章,其代码如下:

    //就是定义一个全局的成员变量Toast, 这个Toast不为null的时候才去make,否则直接setText.
    //为了按返回键后立即使Toast不再显示,重写父类Activity的onBackPressed()方法里面去cancel你的Toast即可
    private Toast mToast;
        public void showToast(String text) {  
            if(mToast == null) {  
                mToast = Toast.makeText(MobileSendTopicActivity.this, text, Toast.LENGTH_SHORT);  
            } else {  
                mToast.setText(text);    
                mToast.setDuration(Toast.LENGTH_SHORT);  
            }  
            mToast.show();  
        }  
          
        public void cancelToast() {  
                if (mToast != null) {  
                    mToast.cancel();  
                }  
        }  
          
        public void onBackPressed() {  
                cancelToast();  
                super.onBackPressed();
        }  
    

    按照他的思路,我就在自己的项目里去实现,但是由于我的项目里有自定义的Toast(通过new Toast(context)的方法实现)和Toast.makeText(context,message, duration).show();不同,两种混合使用,就会在程序中报类似以下错误:

    ToastError.png

    为了避免这种错误,要么不用自定义的Toast(不可能),要么全部用自定义的(工作量有点大,不想改),所以我就在类中定义了两个全局成员变量

    private static Toast mToast;
    private static Toast mCustomToast;
    

    下面贴上我的Tst.java代码:

    public class Tst {
        private Tst() {
            /* cannot be instantiated */
            throw new UnsupportedOperationException("cannot be instantiated");
        }
        private static Toast mToast;
        private static Toast mCustomToast;
        private static Toast initToast(Context context,CharSequence message, int duration) {
            if (mToast == null) {
                mToast = Toast.makeText(context, message,duration);
            }
            mToast.setText(message);
            mToast.setDuration(duration);
         return mToast;
        }
        private static Toast initToast(Context context,int message, int duration) {
            if (mToast == null) {
                mToast = Toast.makeText(context, message,duration);
            }
            mToast.setText(message);
            mToast.setDuration(duration);
            return mToast;
        }
        private static Toast initCustomToast(Context context, CharSequence message, ToastType toastType, int duration) {
            LinearLayout toastView = initToastView(context, message, toastType);
            if (mCustomToast == null) {
                mCustomToast = new Toast(context);
            }
            mCustomToast.setGravity(Gravity.CENTER, 0, 0);
            mCustomToast.setDuration(duration);
            mCustomToast.setView(toastView);
            return mCustomToast;
        }
        /**
         * 短时间显示Toast
         * @param context
         * @param message
         */
        public static void showShort(Context context, CharSequence message) {
            initToast(context,message,Toast.LENGTH_SHORT).show();
        }
        /**
         * 短时间显示Toast
         * @param context
         * @param message
         */
        public static void showShort(Context context, int message) {
            initToast(context,message,Toast.LENGTH_SHORT).show();
        }
        /**
         * 自定义view Toast
         */
        public static void showShort(Context context, CharSequence message, ToastType toastType) {
            initCustomToast(context, message, toastType, Toast.LENGTH_SHORT).show();
        }
        /**
         * 长时间显示Toast
         * @param context
         * @param message
         */
        public static void showLong(Context context, CharSequence message) {
            initToast(context,message,Toast.LENGTH_LONG).show();
        }
        /**
         * 长时间显示Toast
         * @param context
         * @param message
         */
        public static void showLong(Context context, int message) {
            initToast(context,message,Toast.LENGTH_LONG).show();
        }
        public static void showLong(Context context, CharSequence message, ToastType toastType) {
            initCustomToast(context, message, toastType, Toast.LENGTH_LONG).show();
        }
        /**
         * 自定义显示Toast时间
         * @param context
         * @param message
         * @param duration
         */
        public static void show(Context context, CharSequence message, int duration) {
            initToast(context,message,duration).show();
        }
        /**
         * 自定义显示Toast时间
         * @param context
         * @param message
         * @param duration
         */
        public static void show(Context context, int message, int duration) {
            initToast(context,message,duration).show();
        }
        public static void show(Context context, int msgId, int duration, ToastType toastType) {
            CharSequence message = context.getResources().getText(msgId);
            initCustomToast(context,message,toastType ,duration).show();
        }
        private static LinearLayout initToastView(Context context, CharSequence message, ToastType toastType) {
            int resId;
            int dp2px10 = DensityUtils.dp2px(context, 10);
            LinearLayout layout = new LinearLayout(context);
            layout.setBackgroundResource(R.drawable.bg_toast);
            layout.setOrientation(LinearLayout.VERTICAL);
            layout.setMinimumWidth(DensityUtils.dp2px(context, 122));
            ImageView imageCodeProject = new ImageView(context);
            switch (toastType) {
                default:
                case DONE:
                    resId = R.drawable.icon_toast_done;
                    break;
                case WARNING:
                    resId = R.drawable.icon_toast_warning;
                    break;
            }
            imageCodeProject.setImageResource(resId);
            LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            layoutParams1.setMargins(0, dp2px10 * 2, 0, 0);
            layout.addView(imageCodeProject, layoutParams1);
            LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            layoutParams2.setMargins(dp2px10, DensityUtils.dp2px(context, 14) , dp2px10, DensityUtils.dp2px(context, 22));
            TextView textView = new TextView(context);
            textView.setText(message);
            textView.setTextColor(Color.WHITE);
            textView.setGravity(Gravity.CENTER_HORIZONTAL);
            layout.addView(textView, layoutParams2);
            return layout;
        }
    }
    

    ———————————————分隔线———————————————————
    事实证明,我的这种方法不可取啊,由于toast被定义为static,并且在产生Toast的时候传入了Context,使得context一直得不到释放,最终导致了内存泄漏问题。在此,推荐大家读如何在你的应用中正确使用Context或者Context,什么是Context?这篇文章。

    相关文章

      网友评论

          本文标题:一个“Toast”引发的bug

          本文链接:https://www.haomeiwen.com/subject/ltielttx.html