使用带闪光灯的 web 视图时屏幕闪烁
Posted
技术标签:
【中文标题】使用带闪光灯的 web 视图时屏幕闪烁【英文标题】:Screen blinking when using a webview with flash 【发布时间】:2011-07-03 00:44:51 【问题描述】:编辑:我做了一个演示apk,所以你可以理解我的意思:http://cl.ly/3g0s1p030j243y0p3m2F
对于我的应用程序,我想要在 android 平板电脑上使用所有 Android 优点、手势等进行某种“超级 Power Point”或主题演讲(商业团队将向他们的客户展示产品)。由于 Honeycomb 还没有准备好,而且我们在 3 月之前需要它,所以我们随机选择了一些 Froyo 平板电脑 (Archos 101),但我的问题是针对我尝试过的每一台平板电脑/手机。
我做了一个非常棒的应用程序,但是对于演示过程中的一些动画,客户想要使用 Flash 动画。因为我无法在 Android 中轻松编写动画(有点像小电影/动画图形),而且时间不够,所以这似乎是个好主意。
所以,在网上搜索了一番后,我使用了 webview 和这段代码:
WebView mWebView1 = (WebView) findViewById(R.id.webview1);
mWebView1.getSettings().setjavascriptEnabled(true);
mWebView1.getSettings().setPluginsEnabled(true);
mWebView1.loadUrl("file:///android_asset/graph_01.swf");
这项工作非常好,但在我尝试过的每台设备(Archos 101、Nexus One、Nexus S、Galaxy S、Xperia、Desire、HTC Hero 等等)上,每一个活动都带有 webview 闪烁,几毫秒的黑色屏幕,然后动画终于出现了。
PS:我的布局也很简单:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_
>
<WebView android:id="@+id/webview1" android:layout_
android:layout_></WebView>
</LinearLayout>
请帮助我,我无法想象我是唯一一个面临这个问题的人。
非常感谢您的帮助。你有我所有的代码和演示 apk。
【问题讨论】:
我在安卓浏览器上注意到了这种行为......我担心你可能需要等待很长时间才能修复它...... @Profete162 你能把你的项目文件分享给我吗... 【参考方案1】:这个答案稍后添加:
所以问题是 Adobe 的 Flash Player 在 WebView
内创建了一个 SurfaceView
,并且在 SurfaceView
出现和 Flash 引擎费心绘制任何内容之间存在延迟。在那个小间隙中,SurfaceView 看起来完全是黑色的。
我找到的解决方案是继承 WebView 并将自定义的 SurfaceView 添加到视图树。其次,抑制对 Adobe 视图的第一次 draw() 调用也很重要。我的子类 WebView 的代码如下:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.webkit.WebView;
import android.widget.AbsoluteLayout;
public class FixAdobeWebView extends WebView
View whiteView;
private boolean eatenFirstFlashDraw;
public FixAdobeWebView(Context context, AttributeSet attrs)
super(context, attrs);
whiteView = new WhiteSurfaceView(context);
whiteView.setLayoutParams(new AbsoluteLayout.LayoutParams(800, 480, 0, 0));
addView(whiteView);
private class WhiteSurfaceView extends SurfaceView implements SurfaceHolder.Callback
public WhiteSurfaceView(Context context)
super(context);
getHolder().addCallback(this);
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
Canvas canvas = holder.lockCanvas();
if (canvas != null)
canvas.drawColor(Color.WHITE);
holder.unlockCanvasAndPost(canvas);
@Override
public void surfaceCreated(SurfaceHolder holder)
@Override
public void surfaceDestroyed(SurfaceHolder holder)
//
// Override drawChild to eat the first draw of the FlashPaintSurface
//
@Override
protected boolean drawChild (Canvas canvas, View child, long drawingTime)
if (!eatenFirstFlashDraw && child.getClass().getName().equals("com.adobe.flashplayer.FlashPaintSurface"))
eatenFirstFlashDraw = true;
return true;
return super.drawChild(canvas, child, drawingTime);
布局 XML 应该声明这个类的一个实例,即:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_
android:background="@android:color/white"
>
<org.test.FixAdobeWebView android:id="@+id/webview1"
android:layout_
android:layout_
/>
</LinearLayout>
在我运行 CM6.1 的 Nexus One 上,这非常有效,因为在 Flash SurfaceView 开始绘图之前,WebView 显示为纯白色。您可能需要对其进行一些调整,例如摆脱硬编码的 800x480 尺寸,并在不再需要时销毁白色 SurfaceView。
原始(错误)答案:
看起来 Adobe 应该为此负责。
到目前为止,我发现的最不糟糕的解决方法是:
-
将 WebView 父级的背景设为兼容颜色(即白色)。
最初隐藏 WebView。
等到您获得页面加载事件,然后在一秒延迟后排队运行可显示 WebView。
这意味着您在看到任何东西之前肯定会延迟一秒钟,但它比可怕的黑色闪光 afaik 更不刺耳。
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_
android:background="@android:color/white"
>
<WebView android:id="@+id/webview1"
android:layout_
android:layout_
android:visibility="invisible"
/>
</LinearLayout>
代码:
final Handler handler = new Handler();
...
final WebView mWebView1 = (WebView) findViewById(R.id.webview1);
mWebView1.getSettings().setJavaScriptEnabled(true);
mWebView1.getSettings().setPluginsEnabled(true);
mWebView1.setWebViewClient(new WebViewClient()
@Override
public void onPageFinished(WebView view, String url)
handler.postDelayed(new Runnable()
@Override
public void run()
mWebView1.setVisibility(View.VISIBLE);
, 1000);
);
mWebView1.loadUrl("file:///android_asset/graph_01.swf");
可能有更好的方法,尽管这样可以消除对固定延迟的需求......
我已经有一段时间没有用 Flash 做任何事情了,但我似乎记得 Flash 控件有一种方法可以使用浏览器的 Javascript 引擎(快速 Google 会找到 Flex Ajax Bridge,这似乎很可能)。
您可以做的是,通过上述桥接器,使用 ActionScript 调用执行 alert() 的 Javascript 函数。在您的 Java 代码中,您可以将 mWebView1 连接到实现 onJsAlert()
的 WebChromeClient
。在该函数中,您可以使 WebView 可见。
【讨论】:
刚刚尝试了你的代码,这似乎做了它应该做的事情(我等了一秒钟才看到东西)但是黑色的闪光仍然出现......我也尝试了 10 秒的延迟,但是黑色在 webview 仍然不可见时,flash 会在片刻后出现 诅咒,有时它确实不起作用......似乎正在创建一个SurfaceView,并且在正在创建的表面和决定绘制任何东西的Flash引擎之间发生了黑色闪光。我们需要的是在隐藏 webview 方面更聪明一点...... @Profete162 我没有忘记这个问题,并计划在今天晚些时候或明天重新讨论。希望能给你一些好消息,但没有承诺。 你好 Reuben,我接受了你的回答,并投票赞成给你我承诺的所有赏金。不幸的是,正如我在第一篇文章中所说的那样,这个问题并没有解决。非常感谢您的帮助,即使我对修复感到非常悲观,我也会祈祷。 @Profete162。我已经做到了!我很快就会更新我的答案 v...简而言之,您需要在 Flash 上粘贴另一个 SurfaceView...以上是关于使用带闪光灯的 web 视图时屏幕闪烁的主要内容,如果未能解决你的问题,请参考以下文章