Soporte de lienzo HTML5 y vista Web de Android

Necesito dibujar gráficos en mi aplicación. Para eso uso RGraph (http://www.rgraph.net/); Permite dibujar gráficos interactivos con Javascript. Puse mi código javascript en un documento HTML en los activos de la aplicación, y lo llamo desde un fragmento en un ViewPager.

Aquí está el código HTML y javascript:

<meta http-equiv="content-type" content="text/html; charset=utf-8" /> <html> <head> <script src="./libraries/RGraph.common.core.js" ></script> <script src="./libraries/RGraph.common.dynamic.js" ></script> <script src="./libraries/RGraph.common.tooltips.js" ></script> <script src="./libraries/RGraph.common.effects.js" ></script> <script src="./libraries/RGraph.pie.js" ></script> </head> <body background="../transparent.png"> <canvas id="cvs" width="420" height="400">[No canvas support]</canvas> <script> function CreateGradient (obj, color) { return RGraph.RadialGradient(obj, 200, 150, 95, 200, 150, 125, color, color) } function isCanvasSupported(){ var test_canvas = document.createElement("canvas"); var canvascheck=(test_canvas.getContext) ? true : false ; return canvascheck; } window.onload = function () { if(isCanvasSupported) DrawPieChart(); else document.write("hheheheheh"); } function DrawPieChart () { var canvas = document.getElementById('cvs'); var ctx = canvas.getContext('2d'); var pie = new RGraph.Pie('cvs', [2,3,6,7,82]); pie.Set('chart.colors', [ CreateGradient(pie, '#580600'), CreateGradient(pie, '#AEAEAE'), CreateGradient(pie, '#860100'), CreateGradient(pie, '#C7C7C7'), CreateGradient(pie, '#A70000') ]); pie.Set('chart.labels.sticks', true); pie.Set('chart.labels.sticks.length', 5); pie.Set('chart.tooltips', ['Autres', 'Italie', 'Royaume-Uni', 'Espagne', 'France']); pie.Set('chart.labels', ['2%','3%','6%','7%','82%']); pie.Set('chart.radius', 150); pie.Set('chart.shadow', true); pie.Set('chart.shadow.offsetx', 0); pie.Set('chart.shadow.offsety', 0); pie.Set('chart.shadow.blur', 25); pie.Draw(); } </script> </body> </html> 

Y aquí está el código de un fragmento:

 @Override public void onActivityCreated(Bundle savedInstanceState) { mWebView = (WebView)getActivity().findViewById(R.id.group_fragment_one_webView); mWebView.setFocusable(false); mWebView.loadUrl("file:///android_asset/graphs/graph1.html"); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.getSettings().setDefaultZoom(ZoomDensity.FAR); mWebView.getSettings().setDefaultFontSize(24); mWebView.getSettings().setBuiltInZoomControls(false); mWebView.setBackgroundColor(0); mWebView.setHorizontalScrollBarEnabled(false); mWebView.setVerticalScrollBarEnabled(false); mWebView.getSettings().setSupportZoom(false); mWebView.getSettings().setRenderPriority(RenderPriority.HIGH); String TAG = "HTML 5"; WebSettings ws = mWebView.getSettings(); ws.setJavaScriptEnabled(true); ws.setAllowFileAccess(true); if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.ECLAIR) { try { Method m1 = WebSettings.class.getMethod("setDomStorageEnabled", new Class[]{Boolean.TYPE}); m1.invoke(ws, Boolean.TRUE); Method m2 = WebSettings.class.getMethod("setDatabaseEnabled", new Class[]{Boolean.TYPE}); m2.invoke(ws, Boolean.TRUE); Method m3 = WebSettings.class.getMethod("setDatabasePath", new Class[]{String.class}); m3.invoke(ws, "/data/data/" + getActivity().getApplicationContext().getPackageName() + "/databases/"); Method m4 = WebSettings.class.getMethod("setAppCacheMaxSize", new Class[]{Long.TYPE}); m4.invoke(ws, 1024*1024*8); Method m5 = WebSettings.class.getMethod("setAppCachePath", new Class[]{String.class}); m5.invoke(ws, "/data/data/" + getActivity().getApplicationContext().getPackageName() + "/cache/"); Method m6 = WebSettings.class.getMethod("setAppCacheEnabled", new Class[]{Boolean.TYPE}); m6.invoke(ws, Boolean.TRUE); Log.d(TAG, "Enabled HTML5-Features"); } catch (NoSuchMethodException e) { Log.e(TAG, "Reflection fail", e); } catch (InvocationTargetException e) { Log.e(TAG, "Reflection fail", e); } catch (IllegalAccessException e) { Log.e(TAG, "Reflection fail", e); } } mTextView1 = (TextView)getActivity().findViewById(R.id.group_fragment_one_textview1); mTextView1.setText(getActivity().getResources().getString(R.string.group_fragment_one_text1)); Spannable spanSize = new SpannableString(mTextView1.getText()); spanSize.setSpan(new RelativeSizeSpan(2.0f), 0, mTextView1.getText().toString().indexOf("millions"), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); mTextView1.setText(spanSize); Spannable colorSpan = new SpannableString(mTextView1.getText()); colorSpan.setSpan(new ForegroundColorSpan(getActivity().getResources().getColor(R.color.red_ribbon)), 0, mTextView1.getText().toString().indexOf("millions"), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); mTextView1.setText(colorSpan); mTextView1.setTypeface(Utils.getTextFont(getActivity().getApplicationContext())); mTextView2 = (TextView)getActivity().findViewById(R.id.group_fragment_one_textview2); mTextView2.setText(getActivity().getResources().getString(R.string.group_fragment_one_text2)); spanSize = new SpannableString(mTextView2.getText()); spanSize.setSpan(new RelativeSizeSpan(2.0f), 0, mTextView2.getText().toString().indexOf("du chiffre"), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); mTextView2.setText(spanSize); colorSpan = new SpannableString(mTextView2.getText()); colorSpan.setSpan(new ForegroundColorSpan(getActivity().getResources().getColor(R.color.red_ribbon)), 0, mTextView2.getText().toString().indexOf("du chiffre"), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); mTextView2.setText(colorSpan); mTextView2.setTypeface(Utils.getTextFont(getActivity().getApplicationContext())); super.onActivityCreated(savedInstanceState); } 

Funciona bien en el emulador y en el navegador Eclipse … Pero cuando quiero verlo en un smartphone tengo un error con Canvas. A veces el gráfico se muestra correctamente, a veces aparece "No hay soporte de lienzo". En ViewPager, sólo el fragmento n, el fragmento n-1 y n + 1 son instanciados simultáneamente. Otros fragmentos se instancian cuando el usuario se desplaza sobre otro fragmento. Así que cada vez que el usuario se desplaza, se carga un HTML. Y algunas veces el lienzo es compatible, a veces no …

Traté de obtener el apoyo de lienzo en javascript, pero siempre vuelve que el lienzo es compatible, mientras que no es cierto …

Alguna idea ?

Intente cargar la vista web en el método onResume ():

 @Override public void onResume(){ mWebView.loadUrl("file:///android_asset/graphs/graph1.html"); super.onResume(); } 
  • Android WebView: sólo carga HTML, no carga JS o CSS (en algunos dispositivos)
  • ShouldInterceptRequest en Android 4.4 KitKat
  • Android crea documento pdf desde webview con varias páginas
  • Webview no cambia el tamaño cuando aparece el teclado
  • Reemplazo de Android Mapview para utilizar un servicio WMS
  • Jellybean / ICS Método de publicación HTTP Android + WebView.RestoreState
  • CookieSyncManager está ahora obsoleto, ¿qué puedo usar en su lugar?
  • ¿Cómo obtener bordes y tamaños precisos en la vista Web de Android KitKat (Android Chrome) en Nexus 7?
  • Agregar una vista de pie de página nativa a la vista web
  • Cómo obtener el url de la página actual desde la vista web en android
  • Android - Añadir GestureDetector a la vista web
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.