android - Screen blinking when using a webview with flash -


edit: made demo apk, can understand mean: http://cl.ly/3g0s1p030j243y0p3m2f

for application, want kind of "super power point", or keynote (the commercial team present product customers) using android goodness, gestures, etc... on android tablet. honeycomb not yet ready , because need before march, choose random froyo tablet (archos 101), issue every tablet/phone tried.

i made great application, animations during presentation, customer wanted use flash animations. because couldn't code animations (sort of little movies/ animated graphics) in android , lack of time, seemed idea.

so, after search on web, used webview , code:

    webview mwebview1 = (webview) findviewbyid(r.id.webview1);     mwebview1.getsettings().setjavascriptenabled(true);     mwebview1.getsettings().setpluginsenabled(true);     mwebview1.loadurl("file:///android_asset/graph_01.swf"); 

this work pretty well, on every device tried (archos 101, nexus one, nexus s, galaxy s, xperia, desire, htc hero, , more) every activity webview blink, few milliseconds of black screen, animation appear.

ps: layout 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 me, cannot imagine 1 face issue.

thank lot help. have code , demo apk.

this answer added later:

so problem adobe's flash player creates surfaceview inside webview , there delay between surfaceview appearing , flash engine bothering draw anything. in small gap surfaceview appears totally black.

the solution i've found subclass webview , add customized surfaceview view tree. secondly important suppress first draw() call adobe view. code subclassed webview 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 eat first draw of 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);     } } 

the layout xml should declare instance of 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> 

on nexus 1 running cm6.1 works in webview appears solid white until flash surfaceview starts drawing. need adapt bit, e.g. rid of hardcoded 800x480 dimensions, , destroy white surfaceview once it's no longer needed.

original (wrong) answer:

looks adobe blame one.

the least awful workaround i've found far :

  1. make background of webview's parent compatible colour (i.e. white).
  2. hide webview initially.
  3. wait until page loaded event, , queue runnable show webview after 1 second delay.

it means guaranteed 1 second delay before can see anything, it's less jarring horrible black flash afaik.

layout:

<?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> 

code:

    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 better way though remove need fixed delay...

it's been while since did flash seem recall there way flash control use browser's javascript engine (a quick google turns flex ajax bridge seems likely).

what is, aforementioned bridge, use actionscript call javascript function alert(). in java code you'd hook mwebview1 webchromeclient implements onjsalert(). in function you'd make webview visible.


Comments

Popular posts from this blog

linux - Mailx and Gmail nss config dir -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -