Android 避免位图被回收

Android 避免位图被回收,android,android-fragments,bitmap,android-viewpager,Android,Android Fragments,Bitmap,Android Viewpager,我有两个异步任务,其中一个下载图像,另一个添加模糊效果,但我的问题是,在下载任务的onPostExecute回调中,我想将位图放在ImageView中,然后将其传递给第二个任务以对其应用模糊效果,但有时我会 trying to use a recycled bitmap 我已经搜索了很多关于这个问题,但我没有找到一个明确的解决方案来避免这个问题,特别是我在一个查看页面的片段中使用了这个图像这是我的代码 protected void onPostExecute(Bitmap result

我有两个异步任务,其中一个下载图像,另一个添加模糊效果,但我的问题是,在下载任务的
onPostExecute
回调中,我想将位图放在ImageView中,然后将其传递给第二个任务以对其应用模糊效果,但有时我会

trying to use a recycled bitmap  
我已经搜索了很多关于这个问题,但我没有找到一个明确的解决方案来避免这个问题,特别是我在一个查看页面的片段中使用了这个图像这是我的代码

  protected void onPostExecute(Bitmap result) {
        Bitmap bitmap=result;
        bmImage.setImageBitmap(bitmap);
        if(bitmap!=null && !bitmap.isRecycled()){
            Bitmap bb=bitmap;

        new blurTask().execute(bb);}
    }
这是我完整的片段代码

public class ScreenSlidePageFragment extends Fragment {
    int page;
    String img;
    // ImageView blured;
    String[] checkblur;
    int size;
    Boolean onCreateViewCalled = false;
    ImageView blur;
    ImageView imageView;

        public static ScreenSlidePageFragment newInstance(int page, String img, int size) {
            ScreenSlidePageFragment fragmentFirst = new ScreenSlidePageFragment();
            Bundle args = new Bundle();
            args.putInt("someInt", page);
            args.putString("img", img);
            args.putInt("size", size);
            fragmentFirst.setArguments(args);
            return fragmentFirst;
        }

        // Store instance variables based on arguments passed
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            page = getArguments().getInt("someInt", 0);
            img = getArguments().getString("img");
            size = getArguments().getInt("size");
            checkblur = new String[size];
            onCreateViewCalled = false;
        }

        public void ChangeAlpha(float alpha) {
            System.out.println(alpha);
            blur.setAlpha(alpha);

        }

        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);

        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View v = (View) inflater.inflate(
                    R.layout.fragment_screen_slide_page, container, false);

           imageView = (ImageView) v.findViewById(R.id.image);
            blur = (ImageView) v.findViewById(R.id.blur);
            //Glide.with(this).load(img).into(imageView);
            new DownloadImageTask(imageView).execute(img);
        return v;
        }
     class blurTask extends AsyncTask<Bitmap, Integer, BitmapDrawable> {
            Bitmap image;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }

            @Override
            protected BitmapDrawable doInBackground(Bitmap... params) {
                image = params[0];


                Bitmap b = Blur.blurBitmap(image, getActivity());
                final BitmapDrawable ob = new BitmapDrawable(getResources(), b);


                return ob;
            }

            @Override
            protected void onPostExecute(BitmapDrawable blur1) {
                // Do whatever you need with the string, you can update your UI from here
                // blured.setBackground(blur);
                if (blur1 != null)
                    System.out.println("yryryryry");
                blur.setBackground(blur1);
            }


        }
        class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
            ImageView bmImage;

            public DownloadImageTask(ImageView bmImage) {
                this.bmImage = bmImage;
            }

            protected Bitmap doInBackground(String... urls) {
                String urldisplay = urls[0];
                Bitmap mIcon11 = null;
                try {
                    InputStream in = new java.net.URL(urldisplay).openStream();
                    mIcon11 = BitmapFactory.decodeStream(in);
                } catch (Exception e) {
                    Log.e("Error", e.getMessage());
                    e.printStackTrace();
                }
                return mIcon11;
            }

            protected void onPostExecute(Bitmap result) {
                bmImage.setImageBitmap(Bitmap.createBitmap(result));
                new blurTask().execute(Bitmap.createBitmap(bmImage));

            }
        }
    }
公共类ScreenSlidePageFragment扩展片段{
整版;
字符串img;
//图像视图模糊;
字符串[]checkblur;
整数大小;
布尔onCreateViewCalled=false;
图像视图模糊;
图像视图图像视图;
公共静态屏幕SlidePageFragment newInstance(整型页面,字符串img,整型大小){
ScreenSlidePageFragmentFirst=新建ScreenSlidePageFragment();
Bundle args=新Bundle();
args.putInt(“someInt”,第页);
args.putString(“img”,img);
参数putInt(“大小”,大小);
fragmentFirst.setArguments(args);
首先返回碎片;
}
//根据传递的参数存储实例变量
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
page=getArguments().getInt(“someInt”,0);
img=getArguments().getString(“img”);
size=getArguments().getInt(“size”);
checkblur=新字符串[大小];
onCreateViewCalled=false;
}
公共无效更改alpha(浮动alpha){
系统输出打印项次(α);
模糊。setAlpha(alpha);
}
@凌驾
已创建视图上的公共void(视图,捆绑保存状态){
super.onViewCreated(视图,savedInstanceState);
}
@凌驾
创建视图上的公共视图(布局、充气机、视图组容器、,
Bundle savedInstanceState){
视图v=(视图)充气器。充气(
R.layout.fragment\u屏幕\u幻灯片\u页面,容器,错误);
imageView=(imageView)v.findViewById(R.id.image);
模糊=(ImageView)v.findViewById(R.id.blur);
//使用(this.load)(img.into)滑动(this);
新下载的ImageTask(imageView).execute(img);
返回v;
}
类任务扩展了异步任务{
位图图像;
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
}
@凌驾
受保护的BitmapDrawable doInBackground(位图…参数){
image=params[0];
位图b=Blur.blurBitmap(图像,getActivity());
final BitmapDrawable ob=新的BitmapDrawable(getResources(),b);
返回ob;
}
@凌驾
PostExecute上受保护的void(BitmapDrawable blur1){
//对字符串执行任何需要的操作,您可以从这里更新UI
//模糊。倒退(模糊);
如果(1!=null)
System.out.println(“yry”);
模糊。倒退(模糊1);
}
}
类DownloadImageTask扩展了AsyncTask{
图像视图bmImage;
公共下载ImageTask(ImageView bmImage){
this.bmImage=bmImage;
}
受保护位图doInBackground(字符串…URL){
字符串urldisplay=url[0];
位图mIcon11=null;
试一试{
InputStream in=newjava.net.URL(urldisplay.openStream();
mIcon11=BitmapFactory.decodeStream(in);
}捕获(例外e){
Log.e(“Error”,e.getMessage());
e、 printStackTrace();
}
返回mIcon11;
}
受保护的void onPostExecute(位图结果){
bmImage.setImageBitmap(Bitmap.createBitmap(结果));
新建blurTask().execute(Bitmap.createBitmap(bmImage));
}
}
}
因此,我得到了图像,然后出现了模糊效果,但当我尝试滑动到下一个viewpager页面时,我得到了此错误
有什么帮助吗?

谢谢。

通过在处理前将原始位图复制到新位图,可以避免尝试使用回收的位图。试试这个

protected void onPostExecute(Bitmap result) {
    bmImage.setImageBitmap(result);
    new blurTask().execute(Bitmap.createBitmap(result));
}

希望它对您有用。

我在使用位图和复制位图时有过不好的经验。为什么要先在
位图中复制
结果
,然后再在
bb
中复制?
只需缩小图像
。这就是解决方案。因为我有一个framelayout,其中包含两个图像,一个是原始图像,另一个是模糊图像image@MD能解释一下你们的解决方案吗?谢谢@Arkar,但这个解决方案会带来性能方面的糟糕体验吗?当我在寻呼机之间导航时,仍然会遇到同样的问题fragment@Tony仅当滑动到下一个时出错查看寻呼机页面?我想问题出在寻呼机适配器上。您使用哪种适配器?PagerAdapter或FragmentPagerAdapter?Fragment寻呼机适配器如果需要,我可以粘贴适配器代码