Android Viewpager-OutOfMemory-使用片段

Android Viewpager-OutOfMemory-使用片段,android,android-fragments,android-viewpager,out-of-memory,Android,Android Fragments,Android Viewpager,Out Of Memory,我在StackOverflow中读了这么多线程,但找不到解决问题的方法。在过去的一周里,我一直在试图解决这个问题,但没能解决。如果有人能帮我就好了 问题是 我有近50幅图像,我利用ViewPager和片段让用户浏览这些图像。所有图像均为250*350维,每个图像不超过20KB。在键入第30-35张图像时,我从内存异常中得到。。这是堆栈跟踪 09-07 16:30:09.126: E/MessageQueue-JNI(1023): java.lang.OutOfMemoryError 09-07

我在StackOverflow中读了这么多线程,但找不到解决问题的方法。在过去的一周里,我一直在试图解决这个问题,但没能解决。如果有人能帮我就好了

问题是

我有近50幅图像,我利用ViewPager和片段让用户浏览这些图像。所有图像均为250*350维,每个图像不超过20KB。在键入第30-35张图像时,我从内存异常中得到。。这是堆栈跟踪

09-07 16:30:09.126: E/MessageQueue-JNI(1023): java.lang.OutOfMemoryError
09-07 16:30:09.126: E/MessageQueue-JNI(1023):   at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
09-07 16:30:09.126: E/MessageQueue-JNI(1023):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:683)
09-07 16:30:09.126: E/MessageQueue-JNI(1023):   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:513)
09-07 16:30:09.126: E/MessageQueue-JNI(1023):   at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:541)
09-07 16:30:09.126: E/MessageQueue-JNI(1023):   at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:571)
下面是代码MyGallery.java

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        List<Fragment> fragments = getFragments();

        pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
        ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
        pager.setOffscreenPageLimit(2);
        pager.setAdapter(pageAdapter);
     }



private List<Fragment> getFragments() {
    List<Fragment> fList = new ArrayList<Fragment>();
    String picture_book = "";
    for (int i = 1; i <= 50; i++) {
        picture_book = "picture" + i;
        fList.add(MyGallery_Fragment.newInstance(picture_book));
    }
    return fList;
}

private class MyPageAdapter extends FragmentStatePagerAdapter {
    private List<Fragment> fragments;

    public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return this.fragments.get(position);
    }

    @Override
    public int getCount() {
        return this.fragments.size();
    }
}
这就是我试过的

  • 我使用了
    FragmentPagerAdapter
    ,并如前所述更改为
    FragmentStatePagerAdapter
    。。我认为,
    FragmentStatePagerAdapter
    只是将片段的视图直接保留在当前显示项目的左侧和右侧,并自动销毁其他项目。。但这并没有解决问题

  • 我甚至将
    setOffScreenPageLimit
    设置为2,这样旧片段就会被销毁。。但这也没有解决问题

  • 我尝试在赋值后销毁位图,但得到了相同的错误

  • 我还在MyGallery_片段类中尝试了这段代码

    public static final MyGallery_Fragment newInstance(String picture) {
    
            MyGallery_Fragment f = new MyGallery_Fragment();
            contextForDialog = f.getActivity();
            Bundle bdl = new Bundle();
            bdl.putString("picture", picture);
    
            f.setArguments(bdl);
            return f;
        }
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            context = activity.getApplicationContext();
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
    
            picture = getArguments().getString("picture");
    
            View v = inflater
                    .inflate(R.layout.mygallery_fragment, container, false);
    
    
            picture_img = (ImageView) v.findViewById(R.id.picture_iv);
            picture_resID = getResources().getIdentifier(picture, "drawable",
                    context.getPackageName());
    
    
            picture_biticon = BitmapFactory.decodeResource(getResources(),
                    picture_resID);
            picture_img.setImageBitmap(picture_biticon);
    
            return v;
        }
     }
    
    @覆盖
    公共空间{
    super.ondestory();
    Drawable Drawable=picture_img.getDrawable();
    if(BitmapDrawable的可绘制实例){
    BitmapDrawable BitmapDrawable=(BitmapDrawable)drawable;
    picture_biticon=bitmapDrawable.getBitmap();
    图片_biticon.recycle();
    }
    }

  • 我在Note II中测试了该应用程序,它在第30-35次图像扫描之间显示出
    outofmemory
    ,但在我新买的Moto E中,同样的代码运行良好


  • 如果有人能帮我解决这个问题,那就太好了。

    在developer.android.com网站上有一篇关于加载位图的文章。您可以将其视为最佳实践。你可以在

    它讨论了加载位图的不同机制。你考虑过这些吗

    查看您的代码,您将屏幕外限制设置为2。但同时,创建50个片段实例并将其添加到列表中。我认为你的代码应该是(未测试的代码)


    存储这么多的碎片是个坏主意——你不应该这么做。查看寻呼机缓存邻居以用于动画目的,这就足够了。而不是碎片。列表中,您应该考虑存储在您的适配器中创建特定视图和创建片段所需的模型列表。

    其他建议:

    三星设备处理内存的方式与其他设备不同,我在S3和S4上也有类似的问题。同样,你也应该知道,在当前片段的默认邻居中,视图寻呼机加载,所以如果你将屏幕限制设置为2,这意味着VIEWPGER将从当前的一个和右边的两个左边加载两个片段,所以你应该考虑留下默认值(1)。
    关于文件大小-如果文件大小为30KB,并不意味着它将在图形卡内存中使用相同的大小-通常要多得多。在提到VIO之前,应该考虑在运行时对那些进行重新缩放。您还可以尝试在清单应用程序节点中设置android:largeHeap=“true”。

    谢谢。。我已经看过你提到的Android开发者网站了。。这是关于处理大型位图的,但在我的例子中,所有的图像都是250*350维,大小不超过20KB。是的,我正在创建多个片段实例,但如果只加载TextView,我看不出有任何问题。。问题仅限于Imageview。谢谢您的建议。在我使用的过程中,我认为这些片段会被重用。请让我知道我应该改变什么来避免这种情况?任何教程都会非常有用。谷歌示例:是的,我看过你给出的示例。。我也指出了这一点——即使在本例中,它们也会创建新的片段实例。我认为Android将负责销毁视图中没有的片段。如果我的理解不正确,请纠正我。是的,未使用的片段应该由GC销毁。若你们正在存储对它们的引用,情况正好相反——GC不能接触它们。
    public MyPageAdapter(FragmentManager fm) {
        super(fm);
    }
    
    @Override
        public Fragment getItem(int position) {
            String picture_book = "picture" + i;
            return MyGallery_Fragment.newInstance(picture_book);
        }
    
        @Override
        public int getCount() {
            return 50;
        }