使用带有 flash 的 webview 时屏幕闪烁 [英] Screen blinking when using a webview with flash

查看:38
本文介绍了使用带有 flash 的 webview 时屏幕闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一个演示 apk,所以你可以理解我的意思:http://cl.ly/3g0s1p030j243y0p3m2F

I made a demo apk, so you can understand what I mean: http://cl.ly/3g0s1p030j243y0p3m2F

对于我的应用程序,我想要在 Android 平板电脑上使用所有 Android 优点、手势等的超级 Power Point"或主题演讲(商业团队将向他们的客户展示产品).由于 Honeycomb 还没有准备好,而且我们在 3 月之前需要它,我们随机选择了一些 Froyo 平板电脑(爱可视 101),但我的问题是针对我尝试过的每款平板电脑/手机.

For my application, I want a kind of "Super Power Point", or a keynote (the commercial team will present the product to their customers) using all the Android goodness, gestures, etc... on an Android tablet. As Honeycomb is not yet ready and because we need it before march, we choose some random Froyo Tablet (Archos 101), but my issue is for every tablet/phone I tried.

我制作了一个非常棒的应用程序,但是对于演示过程中的一些动画,客户想要使用 Flash 动画.因为我无法在 Android 中轻松编写动画(类似小电影/动画图形)并且时间不够,所以这似乎是一个好主意.

I made a really great application, but for some animations during the presentation, the customer wanted to use flash animations. Because I couldn't code animations (sort of little movies/ animated graphics) that easily in Android and the lack of time, that seemed to be a good idea.

所以,在网上搜索之后,我使用了 webview 和这段代码:

So, after some search on the Web, I used webview and this code:

    WebView mWebView1 = (WebView) findViewById(R.id.webview1);
    mWebView1.getSettings().setJavaScriptEnabled(true);
    mWebView1.getSettings().setPluginsEnabled(true);
    mWebView1.loadUrl("file:///android_asset/graph_01.swf");

这项工作非常好,但在我尝试过的每台设备(爱可视 101、Nexus One、Nexus S、Galaxy S、Xperia、Desire、HTC Hero 等等)上,每个活动都有一个 webview 闪烁,几毫秒的黑色屏幕,然后动画终于出现了.

This work pretty well, but on every device I tried (Archos 101, Nexus One, Nexus S, Galaxy S, Xperia, Desire, HTC Hero, and really more) every activity with a webview blink, a few milliseconds of black screen, then the animation finally appear.

PS:我的布局也很简单:

PS: My layout is quite simple too:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<WebView android:id="@+id/webview1" android:layout_height="fill_parent"
            android:layout_width="fill_parent"></WebView>
</LinearLayout>

请帮助我,我无法想象我是唯一一个遇到这个问题的人.

Please help me, I cannot imagine I am the only one to face this issue.

非常感谢您的帮助.你有我所有的代码和演示 apk.

Thank a lot for any help. You have all my code and the demo apk.

推荐答案

此答案稍后添加:

所以问题是 Adob​​e 的 Flash Player 在 WebView 内创建了一个 SurfaceView 并且在 SurfaceView 出现和 Flash 之间存在延迟引擎懒得画任何东西.在那个小间隙中,SurfaceView 看起来完全是黑色的.

So the problem is that Adobe's Flash Player creates a SurfaceView inside the WebView and there is a delay between the SurfaceView appearing and the Flash engine bothering to draw anything. In that small gap the SurfaceView appears totally black.

我找到的解决方案是子类化 WebView 并将自定义 SurfaceView 添加到视图树.其次,抑制对 Adob​​e 视图的第一次 draw() 调用也很重要.我的子类 WebView 的代码如下:

The solution I've found is to subclass WebView and add a customized SurfaceView to the view tree. Secondly it is also important to suppress the first draw() call to the Adobe view. The code for my subclassed WebView is as follows:

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 应声明此类的一个实例,即:

The layout XML should declare an instance of this class, i.e. :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/white"
    >
<org.test.FixAdobeWebView android:id="@+id/webview1" 
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    />
</LinearLayout>

在我运行 CM6.1 的 Nexus One 上,这非常有效,因为 WebView 显示为纯白色,直到 Flash SurfaceView 开始绘制.您可能需要稍微调整一下,例如摆脱硬编码的 800x480 尺寸,并在不再需要时销毁白色 SurfaceView.

On my Nexus One running CM6.1 this works perfectly in that the WebView appears as solid white until the Flash SurfaceView starts drawing. You will probably need to adapt it a bit, e.g. get rid of the hardcoded 800x480 dimensions, and also destroy the white SurfaceView once it's no longer needed.

原始(错误)答案:

ORIGINAL (WRONG) ANSWER:

看起来 Adob​​e 应该为此负责.

Looks like Adobe are to blame for this one.

到目前为止,我发现的最糟糕的解决方法是:

The least awful workaround I've found so far is to :

  1. 将 WebView 的父背景设为兼容的颜色(即白色).
  2. 最初隐藏 WebView.
  3. 等到您获得页面加载事件,然后将可运行对象排队以在一秒延迟后显示 WebView.

这意味着你在看到任何东西之前有保证的一秒延迟,但它没有那个可怕的黑色闪光 afaik 那么刺耳.

It means you get a guaranteed one second delay before you can see anything, but it's less jarring than that horrible black flash afaik.

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/white"
    >
<WebView android:id="@+id/webview1" 
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    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");        

也许有更好的方法可以消除对固定延迟的需要......

There might be a better way though that would remove the need for a fixed delay...

我已经有一段时间没有使用 Flash 做任何事情了,但我似乎记得有一种方法可以让 Flash 控件使用浏览器的 Javascript 引擎(谷歌快速打开了 Flex Ajax Bridge 似乎很有可能).

It's been a while since I did anything with Flash but I seem to recall there is a way for the Flash control to use the browser's Javascript engine (a quick Google turns up the Flex Ajax Bridge which seems likely).

您可以做的是,使用上述网桥,使用 ActionScript 调用执行 alert() 的 Javascript 函数.在您的 Java 代码中,您将 mWebView1 连接到一个 WebChromeClient 上,它实现了 onJsAlert().在该函数中,您可以使 WebView 可见.

What you could do is, with the aforementioned bridge, use ActionScript to call a Javascript function which does an alert(). In your Java code you'd hook your mWebView1 up to a WebChromeClient which implements onJsAlert(). In that function you'd make the WebView visible.

这篇关于使用带有 flash 的 webview 时屏幕闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆