无法对非静态方法 getAssets() 进行静态引用 - 无法在片段中播放音频

Posted

技术标签:

【中文标题】无法对非静态方法 getAssets() 进行静态引用 - 无法在片段中播放音频【英文标题】:Cannot make a static reference to the non-static method getAssets() - Trouble playing Audio in a fragment 【发布时间】:2013-08-13 12:51:51 【问题描述】:

所以,我正在制作一个带有 Scrollable Tabs + Swipe 导航的应用程序。 在每个标签页中,我想播放不同的音频文件。

下面是我的片段的 OnCreateView,包含媒体播放器的初始化、FileDescriptor 以及在 assets 文件夹中播放一个名为 a.mp3 的音频文件。

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


        ///Playing sound from here on 
             AssetFileDescriptor fda;
        MediaPlayer amp = new MediaPlayer();
        try 

            fda = getAssets().openFd("a.mp3");//// GIVES ERROR !
            amp.reset();
            amp.setDataSource(fda.getFileDescriptor());
            amp.prepare();
            amp.start();

         catch (IllegalArgumentException e) 
            e.printStackTrace();
         catch (IllegalStateException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        

        return rootView;

    

GetAssets() 方法报错如下:

Cannot make a static reference to the non-static method getAssets() from the type ContextWrapper

尽管从声明 FileDescriptor 到最终 Catch 语句的这段代码在普通空白活动的 OnCreate 中完美运行。它在这里不起作用。

有什么解决办法吗?

我可以让 getAssets() 方法静态吗?

还有其他方法可以从 Fragment 访问音频文件吗?

(请记住,我的目标是在每个不同选项卡的屏幕上播放不同的音频文件。稍后我会添加更多音频文件,只是尝试至少让这个文件首先工作。)

请帮助:)

谢谢!

【问题讨论】:

【参考方案1】:

你需要使用一个 Context 对象,所以在这个例子中你可以使用:

rootView.getContext().getAssets().openFd("a.mp3");

也就是说,我建议在视图层次结构实例化后,在片段生命周期中稍后将这段代码移动到onActivityCreatedonStart。将此代码放入 onCreateView 可能会延迟/减慢向用户显示 UI。

从后面的生命周期方法中,您可以安全地调用: getResources().getAssets().openFd("a.mp3");

【讨论】:

做到了 :-) ...我可能会有大约 15-20 个可滚动的标签,每个屏幕包含不同的音频文件、图像和一些文本......关于我怎样才能更有效地做到这一点,我认为这对 CPU 来说可能太多了。只想远离 ANR 至少,使用 FragmentStatePagerAdapter 来处理 Viewpager 中的 Fragment。但是,这样做的好方法 - 不是在每个片段中创建一个 MediaPlayer,而是在您的 Activity 中维护一个 SoundPool 对象,并根据需要将每个片段加载到其中/从中播放。【参考方案2】:

只需将 getAssets() 替换为 context.getAssets() :)

【讨论】:

【参考方案3】:

您可以在实用程序类中指定以下 2 种方法。他们为您返回AssetManager

public static AssetManager getMyAssets(Context context)

     return context.getResources().getAssets();


public static AssetManager getMyAssets(View view)

     return view.getContext().getResources().getAssets();

现在你可以像这样使用它们了:

fda = myUtil.getMyAssets(rootView).openFd("a.mp3");

fda = myUtil.getMyAssets(rootView.getContext()).openFd("a.mp3");

【讨论】:

以上是关于无法对非静态方法 getAssets() 进行静态引用 - 无法在片段中播放音频的主要内容,如果未能解决你的问题,请参考以下文章

无法从JavaPlugin类型对非静态方法getConfig()进行静态引用

如何在ios framework中引用其他静态库

字段初始值无法引用非静态字段、方法或属性

字段初始值设定项无法引用非静态字段、方法或属性

字段初始值设定项无法引用非静态字段、方法或属性

C# 字段初始值无法引用非静态字段、方法或属性