android viewpager内存不足

android viewpager内存不足,android,android-viewpager,out-of-memory,Android,Android Viewpager,Out Of Memory,首先,我想说英语不是我的母语。所以请原谅我的错误 我的问题是:我有一个ViewPager,有10个页面和选项卡。第一个窗口用于设置,其他窗口用于提问 你从第一个问题开始,我显示一张图片,如果你点击“是”“否”,那么你进入下一页,第二张图片显示另一个问题 每次我看到oom错误时(当我看到7页时)。我读了一些关于它的技巧,现在每次我将图像绑定到我的ImageView,我都会使用位图解码器。但这帮不了什么忙。我仍然有同样的问题。我的解码器有*。inpurgable=true 我知道可以选择更改mani

首先,我想说英语不是我的母语。所以请原谅我的错误

我的问题是:我有一个
ViewPager
,有10个页面和选项卡。第一个窗口用于设置,其他窗口用于提问

你从第一个问题开始,我显示一张图片,如果你点击“是”“否”,那么你进入下一页,第二张图片显示另一个问题

每次我看到oom错误时(当我看到7页时)。我读了一些关于它的技巧,现在每次我将图像绑定到我的
ImageView
,我都会使用位图解码器。但这帮不了什么忙。我仍然有同样的问题。我的解码器有
*。inpurgable=true

我知道可以选择更改manifest.xml以允许更大的堆大小,但我认为这只会延迟错误。请有人检查一下我的代码,告诉我我做错了什么。因为在我看来这很好,但因为我是编程新手,我可能会犯一些大错误:)

带适配器的我的viewpager:

public class WaldViewPager extends FragmentActivity implements ActionBar.TabListener {

    private static AppSectionsPagerAdapter mAppSectionsPagerAdapter;
    static private ViewPager mViewPager;
    private static Context context;
    public static int bitmap;
    private int width, height;
    private ViewGroup rootWald;
    private static int textSize = 0;
    private Dialog dialog;
    public static int lastUsed = 1;
    private static int ergebnis = 0;
    private static int[] fragenListe = new int[8];
    private static int[] antworten = new int[9];

    public static void setErgebnis(int zahl){
        ergebnis = zahl;
    }

    public static int getErgebnis(){
        return ergebnis;
    }

    public static void setAntwort(int position, int antwort){
        antworten[position-1] = antwort;
    }

    public static int getAntwort(int position){
        return antworten[position-1];
    }

    public static void setPage(int position){
        mViewPager.setCurrentItem(position, true);
    }

    public static int getPage(){
        return mViewPager.getCurrentItem();
    }

    private void resetListe(){
        for(int i=0; i<fragenListe.length; i++){
            fragenListe[i]=0;
        }
    }

    private void resetAntworten(){
        for(int i=0; i<antworten.length; i++){
            antworten[i]=0;
        }
    }

    public static boolean getFrage(int position){
        if(fragenListe[position-2] == 1){
            return true;
        }else{
            return false;
        }
    }

    public static void setPageVisible(int position, boolean status){
        if(status == true){
            fragenListe[position-2] = 1;
        }else if(status == false){
            fragenListe[position-2] = 0;
        }
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_viewpager);
        overridePendingTransition(R.anim.fade_out, R.anim.fade_in);
        mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
        WaldViewPager.context = getApplicationContext();
        berechneSchriftgroese();
        setupHelpInfoDialog();
        resetListe();
        resetAntworten();

        rootWald = (ViewGroup) findViewById(R.id.toast_layout_root);

        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setLogo(R.drawable.fake);

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mAppSectionsPagerAdapter);
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {

            @Override
            public void onPageSelected(int position){
                actionBar.getTabAt(position).select();
                ViewParent root = findViewById(android.R.id.content).getParent();
                findAndUpdateSpinner(root, position);
            }

            private boolean findAndUpdateSpinner(Object root, int position){
               if (root instanceof android.widget.Spinner){
                   Spinner spinner = (Spinner) root;
                   spinner.setSelection(position);
                   return true;
               }else if (root instanceof ViewGroup){
                   ViewGroup group = (ViewGroup) root;
                   if (group.getId() != android.R.id.content){
                       for (int i = 0; i < group.getChildCount(); i++){
                           if (findAndUpdateSpinner(group.getChildAt(i), position)){
                               return true;
                           }
                       }
                   }
               }
               return false;
           }
        });

        for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
            actionBar.addTab(actionBar.newTab().setText(mAppSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
        }

        mViewPager.setCurrentItem(1, true);
    }

    @Override
    public void onBackPressed() {
        if (mViewPager.getCurrentItem() == 1) {
            super.onBackPressed();
        } else {
            mViewPager.setCurrentItem(1, true);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.bottom_bar_frage, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_settings_frage:
                if(mViewPager.getCurrentItem()==0){
                    mViewPager.setCurrentItem(lastUsed, true);
                }else{
                    lastUsed = mViewPager.getCurrentItem();
                    mViewPager.setCurrentItem(0, true);
                }
                return true;
            case R.id.menu_info:
                dialog.show();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void setupHelpInfoDialog(){
        dialog = new Dialog(WaldViewPager.this);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCancelable(true);
        dialog.setContentView(R.layout.dialog_info);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
        TextView text = (TextView) dialog.findViewById(R.id.dialog_ueberschrift);
        text.setText("Bedienung der App");
        if(MainViewPager.getTextSize()!=0){
            text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
        }
        text = (TextView) dialog.findViewById(R.id.dialog_text1);
        text.setText("-Wischfunktion:");
        if(MainViewPager.getTextSize()!=0){
            text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
        }
        text = (TextView) dialog.findViewById(R.id.dialog_text1_sub);
        text.setText("Zum Navigieren können Sie entweder auf die Tabs zurückgreifen oder Sie wischen das Fenster links oder rechts");
        if(MainViewPager.getTextSize()!=0){
            text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
        }
        text = (TextView) dialog.findViewById(R.id.dialog_text2);
        text.setText("-Zoomfunktion:");
        if(MainViewPager.getTextSize()!=0){
            text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
        }
        text = (TextView) dialog.findViewById(R.id.dialog_text2_sub);
        text.setText("Wenn Sie auf das Bild klicken, können Sie es mit 2 Fingern vergrößern bzw. verkleinern");
        if(MainViewPager.getTextSize()!=0){
            text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
        }
        text = (TextView) dialog.findViewById(R.id.dialog_text3);
        text.setText("-Erklärungshilfe:");
        if(MainViewPager.getTextSize()!=0){
            text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
        }
        text = (TextView) dialog.findViewById(R.id.dialog_text3_sub);
        text.setMovementMethod(LinkMovementMethod.getInstance());
        text.setText(ClickableText.addClickablePart("Damit Sie wenig Zeit beim Suchen der Fremd/Fachwörtern verlieren, können Sie Wörter wie \u200EClypeus\u200E direkt hier nachschlagen", context, rootWald), BufferType.SPANNABLE);
        if(MainViewPager.getTextSize()!=0){
            text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
        }
        ImageView bild = (ImageView) dialog.findViewById(R.id.dialog_bild1);
        ImageView bild = (ImageView) dialog.findViewById(R.id.dialog_bild1);
        bild.setImageBitmap(DecodeImage.decode(bild.getContext().getResources(), R.drawable.swipe));
        bild = (ImageView) dialog.findViewById(R.id.dialog_bild2);
        bild.setImageBitmap(DecodeImage.decode(bild.getContext().getResources(),
R.drawable.swipe_bild));
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
        mViewPager.setCurrentItem(tab.getPosition(), true);
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub  
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub  
    }
我的图像

public class DecodeImage {

    public static Bitmap decode(Resources res, int resId){
        BitmapFactory.Options bfOptions=new BitmapFactory.Options();
        bfOptions.inDither = false;
        bfOptions.inPurgeable = true;               
        bfOptions.inInputShareable = true;
        bfOptions.inTempStorage = new byte[32 * 1024]; 
        return BitmapFactory.decodeResource(res, resId, bfOptions);
    }
}
我将感谢任何帮助。请随意询问代码的详细信息。 此应用程序在某些设备上运行正常,但在其他设备上运行不正常。我想一定是堆大小发生了变化

编辑:找到了解决方案。 用
bitmap.recycle()
的答案是可行的,但由于我的代码艺术,我懒得做很多更改,我使用了其他东西

至于
ViewPager
android为您提供

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
}
我升级了线路

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) { 
        //if you can see the fragment
    }else{
        //if you dont
    }
}

记住:
setUserVisibleHint()
的设置早于
onCreateView()


祝您好运

对于每个图像视图,您都必须调用
recycle()
方法。因此,在这一行之前:

setImageBitmap(DecodeImage.decode(bild.getContext().getResources(),R.drawable.swipe_-bild))

你必须把话说清楚:

((BitmapDrawable)bild.getDrawable()).getBitmap().recycle()


如果问题仍然存在,那是因为图像太大,然后您必须对其进行压缩

我遇到了同样的问题并解决了它,如下所示

android开发者指南中给出了最好的例子,请一步一步地遵循该指南

1.实施不公正的限制


2.遵循以下异步和缓存指南,您也可以从同一链接下载示例

我在带有图像(720*1200)的
ViewPager
中出现
OutOfMemory
错误。结合各种建议,我找到了对我有效的解决方案:

  • 将图像放入
    可绘制节点pi
    类别(从所有其他可绘制类别中删除)

  • 使用选项(inSampleSize=1,ARGB_8888)将可绘制位图解码


我用的是毕加索,也有这个问题。。。 只需删除放置在ImageView中的虚拟内容。删除src标签,因为毕加索不需要它

<ImageView
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        **android:src="@drawable/myDrawable"**/>


发生这种情况的原因是,即使您后来用毕加索替换了可绘制的图像,也必须加载它们,并且在您将许多图像加载到您的ViewPager中后,会导致OutOfMemory。

请参阅已接受的ans-对于回收位图,谢谢,我正在更改代码。代码已经运行,但我必须修改代码以循环使用,不会出现错误:)您尝试过使用持有者吗?它为您节省了大量不必要的硬件资源。如何避免NullPointerException?我是否必须在开始时创建位图保持器,然后观察它们是否为
null
?您必须将日志放在此处以查看nullpointer的位置。我知道我的问题所在。我必须清理我的
imageview
我将尝试
imageview.setImageDrawable(null)
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) { 
        //if you can see the fragment
    }else{
        //if you dont
    }
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) { 
        //if you can see the fragment
    }else{
        //if you dont
        imageViewToDelete.setImageDrawable(null); //this is ImageView from Fragment
    }
}
<ImageView
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        **android:src="@drawable/myDrawable"**/>