如何释放我的 soundPool 媒体?

Posted

技术标签:

【中文标题】如何释放我的 soundPool 媒体?【英文标题】:How do I release my soundPool media? 【发布时间】:2015-03-23 21:07:39 【问题描述】:

由于内存过载,我的应用程序不断崩溃。之前我有多个声音池,但现在我改变了这一点,所以我只为整个应用程序使用一个声音池。这被称为“俱乐部 1”。但是我的应用程序在打开第三个片段后仍然崩溃,我想我需要在它们完成播放后释放声音,以免占用内存。我对吗?如果是这样,我该怎么做?我对所有这些编码都是新手,所以我有点困惑。

这是我的第一个片段:

public class FragmentOne extends Fragment  


SoundPool Clubb1;
int clubb1Id;

int clubb2Id;

int clubb3Id;

int clubb4Id;

int clubb5Id;

int clubb6Id;

int clubb7Id;

int clubb8Id;

int clubb9Id;

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);

    clubb2Id = Clubb1.load(getActivity(), R.raw.clubb2, 1);

    clubb3Id = Clubb1.load(getActivity(), R.raw.clubb3, 1);

    clubb4Id = Clubb1.load(getActivity(), R.raw.clubb4, 1);

    clubb5Id = Clubb1.load(getActivity(), R.raw.clubb5, 1);

    clubb6Id = Clubb1.load(getActivity(), R.raw.clubb6, 1);

    clubb7Id = Clubb1.load(getActivity(), R.raw.clubb7, 1);

    clubb8Id = Clubb1.load(getActivity(), R.raw.clubb8, 1);

    clubb9Id = Clubb1.load(getActivity(), R.raw.clubb9, 1);

    clubb10Id = Clubb1.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
                    Clubb1.play(clubb2Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonC:
                    //C clicked
                    Clubb1.play(clubb3Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonD:
                    //D clicked
                    Clubb1.play(clubb4Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonE:
                    //E clicked
                    Clubb1.play(clubb5Id, 3, 3, 1, 0, 1);
                    break;
                case R.id.buttonF:
                    //F clicked
                    Clubb1.play(clubb6Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonG:
                    //G clicked
                    Clubb1.play(clubb7Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonH:
                    //H clicked
                    Clubb1.play(clubb8Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonI:
                    //I clicked
                    Clubb1.play(clubb9Id, 1, 1, 1, 0, 1);
                    break;
                case R.id.buttonJ:
                    //J clicked
                    Clubb1.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;

我应该在代码中的什么地方以及什么地方来减少我正在使用的内存量?并阻止我的应用程序崩溃?

【问题讨论】:

【参考方案1】:

为了正确加载并避免在创建片段时出现滞后,请将每个加载代码放在其正确的 onClick 位置,如下所示:

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

        switch (v.getId())
            case R.id.buttonA:
                //A clicked
                clubb1Id = Clubb1.load(getActivity(), R.raw.clubb1, 1);
                Clubb1.play(clubb1Id, 1, 1, 1, 0, 1);
                break;
            case R.id.buttonB:
                //B clicked
                clubb2Id = Clubb1.load(getActivity(), R.raw.clubb2, 1);
                Clubb1.play(clubb2Id, 1, 1, 1, 0, 1);
                break;
             //And so on ....
 
 

然后当你以正确的方式完成释放它们时,通过调用release() 到你的SoundPool

【讨论】:

如何为我的声音池编写 release()?【参考方案2】:

在您的 Clubb1 SoundPool 实例上调用 release(),您想在何时何地释放您的 SoundPool 使用的内存。

public class FragmentOne extends Fragment implements View.OnClickListener ,  SoundPool.OnLoadCompleteListener 

    SoundPool Clubb1;
    Integer currentBtnId;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState
    ) 
        View rootView = inflater.inflate(R.layout.fragment_one_layout, container, false);
        Clubb1 = new SoundPool(10, AudioManager.STREAM_MUSIC, 1);

        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);

        buttonA.setTag(R.raw.clubb1);
        buttonB.setTag(R.raw.clubb2);
        buttonC.setTag(R.raw.clubb3);
        buttonD.setTag(R.raw.clubb4);
        buttonE.setTag(R.raw.clubb5);
        buttonF.setTag(R.raw.clubb6);
        buttonG.setTag(R.raw.clubb7);
        buttonH.setTag(R.raw.clubb8);
        buttonI.setTag(R.raw.clubb9);
        buttonJ.setTag(R.raw.clubb10);

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

        Clubb1.setOnLoadCompleteListener(this);

        return rootView;
    

    @Override
    public void onClick(View v) 

        if(currentBtnId != null)
            Clubb1.release();
        

        currentBtnId = v.getId();
        int sampleId = (Integer) v.getTag();
        Clubb1.load(getActivity(), sampleId, 1);
    

    @Override
    public void onLoadComplete(SoundPool soundPool, int sampleId, int status) 
        switch (currentBtnId)
            case R.id.buttonE:
                //E clicked
                soundPool.play(sampleId, 3, 3, 1, 0, 1);
                break;
            default:
                soundPool.play(sampleId, 1, 1, 1, 0, 1);
                break;
        
    

【讨论】:

把它放在你的OnClick监听器中,并带有一个标志,看看是否正在播放上一首歌,如果是则调用release 我需要写什么代码?对不起,我不太擅长这个 查看更新的答案,而不是转换为对象整数而不是原始整数。 当我运行应用程序时,它只播放第一个按钮声音一次,然后没有其他声音再次播放,当我将它添加到我的第二个片段时,应用程序在它开始之前就崩溃了 好吧,我假设您选择的每个按钮都会播放不同的声音,在这种情况下,只需在片段的 onDestroyView 中调用 release

以上是关于如何释放我的 soundPool 媒体?的主要内容,如果未能解决你的问题,请参考以下文章

单击按钮时如何发出随机声音?

如何正确释放 SoundPool 对象?

SoundPool 减慢应用程序

SoundPool 停止功能未停止

SoundPool 加载缓慢,MotionEvent 很奇怪

Sound Pool 只播放一次声音