【问题标题】:I have tried using FragmentStatePagerAdapter to destroy fragments but my app still crashes?我曾尝试使用 FragmentStatePagerAdapter 销毁片段,但我的应用程序仍然崩溃?
【发布时间】:2015-03-23 19:06:12
【问题描述】:

我使用 FragmentStatePagerAdapter 以便在碎片不在视野范围内时将其销毁,但我的应用程序仍然崩溃 - 当我滑动到第三个碎片然后应用程序崩溃时,内存监视器显示内存使用量达到峰值。当我试图构建一个音板应用程序时,我总共有 5 个片段。每个片段都是不同的音板。

这是我的 mainactivity.java

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;

public class MainActivity extends FragmentActivity {
ViewPager viewpager;

@Override
protected void onCreate(Bundle savedInstanceState )

{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    viewpager = (ViewPager) findViewById(R.id.pager);
    PagerAdapter padapter = new PagerAdapter(getSupportFragmentManager());
    viewpager.setAdapter(padapter);
    viewpager.setOffscreenPageLimit(0);
}
}

这是我的 pageradapter.java

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

public class PagerAdapter extends FragmentStatePagerAdapter {

public PagerAdapter(FragmentManager fm) {
    super(fm);
    // TODO Auto-generated constructor stub
}

@Override
public Fragment getItem(int arg0) {
    // TODO Auto-generated method stub
    switch (arg0) {
        case 0:

            return new FragmentOne();
        case 1:
            return new FragmentTwo();
        case 2:
            return new FragmentThree();
        case 3:
            return new FragmentFour();
        case 4:
            return new FragmentFive();


        default:
            break;
    }
    return null;
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return 5;
}


}

这是我五个片段中的第一个片段:

public class FragmentOne extends Fragment  {


SoundPool Clubb1;
int clubb1Id;
SoundPool Clubb2;
int clubb2Id;
SoundPool Clubb3;
int clubb3Id;
SoundPool Clubb4;
int clubb4Id;
SoundPool Clubb5;
int clubb5Id;
SoundPool Clubb6;
int clubb6Id;
SoundPool Clubb7;
int clubb7Id;
SoundPool Clubb8;
int clubb8Id;
SoundPool Clubb9;
int clubb9Id;
SoundPool Clubb10;
int clubb10Id;








@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState
) {

    Clubb1 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb1Id = Clubb1.load(getActivity(), R.raw.clubb1, 1);
    Clubb2 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb2Id = Clubb2.load(getActivity(), R.raw.clubb2, 1);
    Clubb3 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb3Id = Clubb3.load(getActivity(), R.raw.clubb3, 1);
    Clubb4 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb4Id = Clubb4.load(getActivity(), R.raw.clubb4, 1);
    Clubb5 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb5Id = Clubb5.load(getActivity(), R.raw.clubb5, 1);
    Clubb6 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb6Id = Clubb6.load(getActivity(), R.raw.clubb6, 1);
    Clubb7 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb7Id = Clubb7.load(getActivity(), R.raw.clubb7, 1);
    Clubb8 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb8Id = Clubb8.load(getActivity(), R.raw.clubb8, 1);
    Clubb9 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb9Id = Clubb9.load(getActivity(), R.raw.clubb9, 1);
    Clubb10 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);
    clubb10Id = Clubb10.load(getActivity(), R.raw.clubb10, 1);

    View rootView = inflater.inflate(R.layout.fragment_one_layout, container, false);

    Button buttonA = (Button) rootView.findViewById(R.id.buttonA);
    Button buttonB = (Button) rootView.findViewById(R.id.buttonB);
    Button buttonC = (Button) rootView.findViewById(R.id.buttonC);
    Button buttonD = (Button) rootView.findViewById(R.id.buttonD);
    Button buttonE = (Button) rootView.findViewById(R.id.buttonE);
    Button buttonF = (Button) rootView.findViewById(R.id.buttonF);
    Button buttonG = (Button) rootView.findViewById(R.id.buttonG);
    Button buttonH = (Button) rootView.findViewById(R.id.buttonH);
    Button buttonI = (Button) rootView.findViewById(R.id.buttonI);
    Button buttonJ = (Button) rootView.findViewById(R.id.buttonJ);

    View.OnClickListener ocl = new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            switch (v.getId()){
                case R.id.buttonA:
                    //A clicked
                    Clubb1.play(clubb1Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonB:
                    //B clicked
                    Clubb2.play(clubb2Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonC:
                    //C clicked
                    Clubb3.play(clubb3Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonD:
                    //D clicked
                    Clubb4.play(clubb4Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonE:
                    //E clicked
                    Clubb5.play(clubb5Id, 3, 3, 1, 0, 1);
                    break;
                case R.id.buttonF:
                    //F clicked
                    Clubb6.play(clubb6Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonG:
                    //G clicked
                    Clubb7.play(clubb7Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonH:
                    //H clicked
                    Clubb8.play(clubb8Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonI:
                    //I clicked
                    Clubb9.play(clubb9Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonJ:
                    //J clicked
                    Clubb10.play(clubb10Id, 1, 1, 1, 0, 1);
                    break;
            }
        }
    };

    buttonA.setOnClickListener(ocl);
    buttonB.setOnClickListener(ocl);
    buttonC.setOnClickListener(ocl);
    buttonD.setOnClickListener(ocl);
    buttonE.setOnClickListener(ocl);
    buttonF.setOnClickListener(ocl);
    buttonG.setOnClickListener(ocl);
    buttonH.setOnClickListener(ocl);
    buttonI.setOnClickListener(ocl);
    buttonJ.setOnClickListener(ocl);

    return rootView;
}}

任何想法如何阻止这种内存峰值和应用程序崩溃?当我只用 3 个片段尝试它时,该应用程序运行得非常好,并且没有崩溃或滞后。现在我已经添加了两个片段,当您滑动到第三个或第四个片段并且永远不会加载第 5 个片段时,应用程序会崩溃。它不会让你滑动那么远。我真的很迷茫,现在不知道该怎么办。

【问题讨论】:

    标签: java android memory android-fragments


    【解决方案1】:

    您对 SoundPool 类的使用看起来一点都不好。看看下面的教程; http://www.101apps.co.za/articles/using-android-s-soundpool-class-a-tutorial.html

    SoundPool 背后的理念是您可以在同一个池中加载多个样本。您可能应该为整个应用程序使用一个池;或者每个片段最多一个。

    由于 SoundPool 对象是原生的,您还必须注意手动调用它们的“释放”。官方文档说

    在我们的示例中,当玩家完成关卡后,游戏 逻辑应该调用 SoundPool.release() 来释放所有原生 资源,然后将 SoundPool 引用设置为 null。如果 玩家开始另一个关卡,创建一个新的 SoundPool,声音 加载完毕,然后继续播放。

    您可以在 Fragment 的 onCreate() 方法中创建 SoundPool,并在 onDestroy() 中调用 release

    您收到 OutOfMemoryError 是因为您已将 viewpager setOffscreenPageLimit 设置为 0,这意味着片段实例永远不会被缓存。每次向左或向右滑动时,都会创建一个新的 Fragment,其中包含 10 个从未释放的新 SoundPool 对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2020-02-07
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多