当我的活动不可见时,如何在 Android WebView 中暂停 Flash 内容?

Posted

技术标签:

【中文标题】当我的活动不可见时,如何在 Android WebView 中暂停 Flash 内容?【英文标题】:How do I pause Flash content in an Android WebView when my activity isn't visible? 【发布时间】:2011-03-26 18:31:38 【问题描述】:

我正在尝试使用 WebView 在我的活动中显示 Flash 内容。一切运行良好,但是当用户点击 home 键将 Activity 置于后台时,Flash 内容继续运行(声音继续播放等)

我注意到现有的 android 浏览器和 Dolphin 浏览器似乎都避免了这个问题,并且在将浏览活动置于后台时会正确暂停 Flash 内容。

理想情况下,我想要一个解决方案,如果 Activity 正在完成,则完全终止 WebView,否则会暂停它(基本上是复制浏览器的默认行为)

这是我放在一起的一个简单测试,它在 Kongregate 上加载了一个带有一些背景音乐的游戏:

    public class BrowserTest extends Activity 
    private WebView mWebView;

        @Override
        protected void onCreate(Bundle savedInstanceState) 
            super.onCreate(savedInstanceState);

            mWebView = new WebView(this);
            mWebView.getSettings().setjavascriptEnabled(true);
            mWebView.getSettings().setPluginsEnabled(true);

            mWebView.loadUrl("http://m.kongregate.com/games/Jiggmin/the-game-of-disorientation-mobile");
            setContentView(mWebView);
        

        @Override
        protected void onPause()
            super.onPause();

            mWebView.pauseTimers();
            if(isFinishing())
                mWebView.loadUrl("about:blank");
                setContentView(new FrameLayout(this));
            
        

        @Override
        protected void onResume()
            super.onResume();
            mWebView.resumeTimers();
        
    

我查看了股票浏览器的最新源代码,它似乎在做类似的事情(调用 pauseTimers/resumeTimers),尽管我担心我一直在查看的代码已经过时,因为它正在调用似乎不再存在的功能。

我确实通过使用更新计数器的简单 JavaScript setInterval 进行测试来验证对 pauseTimers 的调用是否有效。在 Window 或 View 管理方面,我还应该尝试一些其他明显的事情吗?

移动 Flash 播放器的文档说:

Flash Player 还会自动暂停 SWF 播放(例如,当接到电话或警报响起时)不在视图或前台应用程序中,以降低 CPU 使用率、电池使用率和内存使用率。

这似乎在股票浏览器和海豚浏览器中都能完美运行,但在我的应用程序中却不行。任何想法/解决方案将不胜感激!

更新:这是我们最终添加到活动中以使其正常工作的功能。我们在 Activity 的 onPause 函数中使用“onPause”来调用它,在 Activity 的 onResume 函数中使用“onResume”来调用它:

private void callHiddenWebViewMethod(String name)
    if( mWebView != null )
        try 
            Method method = WebView.class.getMethod(name);
            method.invoke(mWebView);
         catch (NoSuchMethodException e) 
            Log.error("No such method: " + name, e);
         catch (IllegalAccessException e) 
            Log.error("Illegal Access: " + name, e);
         catch (InvocationTargetException e) 
            Log.error("Invocation Target Exception: " + name, e);
        
    

【问题讨论】:

你怎么称呼这个?有没有使用sn-p的code?​​span> 从 API 级别 11 开始无需使用反射。只需调用 WebView 的公共 onPause() 和 onResume() 方法即可。 【参考方案1】:

我看不到您在哪里看到 BrowserActivity 或任何正在调用 pauseTimers() 的东西。我确实看到onPause()BrowserActivity 最终路由到WebViewonPause()。但是,WebViewonPause() 具有 @hide 注释,因此不是 SDK 的一部分。从袖口开始,看起来 onPause() 就是你想要的,给出评论:

调用这个来暂停任何额外的 与此视图相关的处理 及其相关的 DOM/插件/javascript/等。为了 例如,如果取景 屏幕外,这可以调用 减少不必要的 CPU 和/或网络 交通。当景色再次 “活跃”,调用 onResume()。

注意对“插件”的引用,pauseTimers() 文档中没有提及。

我会尝试使用反射来查看onPause()(以及后来的onResume(),当您希望重新启动时)是否满足您的需求。如果是这样,请向b.android.com 发布有关此问题的问题,要求他们将这些方法(或等效方法)添加到 SDK。您的要求似乎很常见,超出 SDK 的解决方案不是一个好的解决方案。

【讨论】:

对 pauseTimers 的调用在 Browser 活动的 pauseWebViewTimers 方法内。我不熟悉 @hide 注释,所以这就是为什么我认为我可能正在浏览某种旧的/不同的代码。我认为您尝试使用反射调用 onPause/onResume 的建议很棒,我会让您知道结果如何,谢谢! 这非常有效,非常感谢您向我介绍@hide 注释,我什至没有意识到我可以使用反射来获得这些方法。我会按照您的建议将问题发布到 b.android.com! @BenV:很高兴听到它奏效了!如果您想到它,请在提交后在此处发表评论,并附上指向该问题的链接。我想关注这个。 没问题,这里是问题的链接:code.google.com/p/android/issues/detail?id=10282 仅供参考:WebView.onPause()WebView.onResume() 现在在 API 级别 11 和更高版本中公开。【参考方案2】:
@Override
protected void onPause() 
    super.onPause();
    this.callHiddenWebViewMethod("onPause");


@Override
protected void onResume() 
    super.onResume();
    this.callHiddenWebViewMethod("onResume");

这就是你在活动中的称呼......就像一个魅力。

【讨论】:

以上是关于当我的活动不可见时,如何在 Android WebView 中暂停 Flash 内容?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Web 应用程序启动 android 活动

如果在 Android 中不再可见,系统会终止 Activity 的问题

如何使 Android 的 Singleton 对象持久化

当我使用 Kotlin 在 Android Studio 中更改为另一个活动时如何停止崩溃

Android:清除活动堆栈

如何在不丢失数据的情况下返回我的父活动?