android - porque - La pantalla parpadea al usar una vista web con flash
samsung s5 no enciende pantalla (1)
Editar: Hice una demostración de la demo, por lo que puede entender lo que quiero decir: http://cl.ly/3g0s1p030j243y0p3m2F
Para mi aplicación, quiero una especie de "Super Power Point", o una nota clave (el equipo comercial presentará el producto a sus clientes) utilizando toda la bondad de Android, gestos, etc. en una tableta de Android. Como Honeycomb aún no está listo y porque lo necesitamos antes de marzo, elegimos una tableta aleatoria de Froyo (Archos 101), pero mi problema es para cada tableta / teléfono que probé.
Hice una aplicación muy buena, pero para algunas animaciones durante la presentación, el cliente quería usar animaciones flash. Como no podía codificar animaciones (tipo de pequeñas películas / gráficos animados) fácilmente en Android y la falta de tiempo, parecía una buena idea.
Entonces, después de buscar en la web, utilicé webview y este código:
WebView mWebView1 = (WebView) findViewById(R.id.webview1);
mWebView1.getSettings().setJavaScriptEnabled(true);
mWebView1.getSettings().setPluginsEnabled(true);
mWebView1.loadUrl("file:///android_asset/graph_01.swf");
Esto funciona bastante bien, pero en cada dispositivo que probé (Archos 101, Nexus One, Nexus S, Galaxy S, Xperia, Deseo, HTC Hero, y realmente más) cada actividad con una vista web parpadea, unos pocos milisegundos de pantalla en negro, luego la animación finalmente aparece.
PD: Mi diseño es bastante simple también:
<?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>
Por favor, ayúdenme, no me puedo imaginar que soy el único en enfrentar este problema.
Muchas gracias por cualquier ayuda. Tienes todo mi código y la demo apk.
ESTA RESPUESTA AGREGADA MÁS TARDE:
Entonces, el problema es que Adobe Flash Player crea un SurfaceView
dentro de WebView
y hay una demora entre la aparición de SurfaceView
y el motor de Flash que se molesta en dibujar algo. En ese pequeño espacio, SurfaceView aparece totalmente negro.
La solución que he encontrado es subclasificar WebView y agregar un SurfaceView personalizado al árbol de vistas. En segundo lugar, también es importante suprimir la primera llamada a draw () a la vista de Adobe. El código para mi WebView subclase es el siguiente:
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);
}
}
El diseño XML debe declarar una instancia de esta clase, es decir:
<?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>
En mi Nexus One que ejecuta CM6.1, esto funciona perfectamente porque WebView aparece como blanco fijo hasta que Flash SurfaceView comienza a dibujar. Es probable que necesite adaptarlo un poco, por ejemplo, deshacerse de las dimensiones codificadas de 800x480, y también destruir el SurfaceView blanco una vez que ya no sea necesario.
RESPUESTA ORIGINAL (INCORRECTA):
Parece que Adobe tiene la culpa de este.
La solución menos horrible que he encontrado hasta ahora es:
- Haga que el fondo del elemento principal de WebView sea de un color compatible (es decir, blanco).
- Ocultar el WebView inicialmente.
- Espere hasta que obtenga el evento de carga de página, y luego ponga en cola un ejecutable para mostrar WebView después de un segundo de retraso.
Significa que tienes un retraso garantizado de un segundo antes de que puedas ver algo, pero es menos discordante que ese horrible flash negro afaik.
Diseño:
<?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>
Código:
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");
Sin embargo, podría haber una manera mejor de eliminar la necesidad de un retraso fijo ...
Ha pasado un tiempo desde que hice algo con Flash, pero parece recordar que hay una manera para que el control de Flash use el motor de Javascript del navegador (un Google rápido enciende el Flex Ajax Bridge, lo que parece probable).
Lo que podría hacer es, con el puente mencionado anteriormente, usar ActionScript para llamar a una función de Javascript que hace una alerta (). En su código Java, conectaría su mWebView1 a un WebChromeClient
que implementa en onJsAlert()
. En esa función, harías que WebView sea visible.