android webview 与 js 交互 总结

来源:互联网 发布:mac上的app如何退订 编辑:程序博客网 时间:2024/06/06 08:37

最近开发用到嵌入网页,总结下,首次写,写的不好望大家批评指正

首先,在页面中写入webview组件,

<WebView
        android:id="@+id/webview"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:text="@string/hello_world"
        android:layerType="software"/>

这里需要注意的是,很多时候,会出现加载网页过程中会出现短暂的黑屏,这是不仅影响美观,更影响整体的和谐,

最直接简便的方法就是设置WebViewlayerType的属性为software

总结下layerType的属性

 

LAYER_TYPE_SOFTWARE
无论硬件加速是否打开,都会有一张Bitmapsoftware layer),并在上面对WebView进行软渲染。
好处:
在进行动画,使用software可以只画一次View树,很省。
什么时候不要用:View树经常更新时不要用。尤其是在硬件加速打开时,每次更新消耗的时间更多。因为渲染完这张Bitmap后还需要再把这张Bitmap渲染到hardware layer上面去。

LAYER_TYPE_HARDWARE
硬件加速关闭时,作用同software

硬件加速打开时会在FBOFramebufferObject)上面做渲染,在进行动画时,View树也只需要画一次。

 

两者区别:
1
、一个是渲染到Bitmap,一个是渲染到FB上。
2
hardware可能会有一些操作不支持。
两者相同:
都是开了一个buffer,把View画到这个buffer上面去。

LAYER_TYPE_NONE
这个就比较简单了,不为这个View树建立单独的layer
PS:GLSurfaceView
WebView默认Layertype都是none


GLSurfaceView:
GLSurfaceView设置为software或者hardware后,发现什么也画不出来了。得出结论:GLSurfaceViewLayer type只能是none

WebView:
以前使用WebView时碰到过一个问题,如果在WebView上面使用AnimationWebView的绘画区域不动。当时的解决方案是在进行动画之前对WebView进行截屏(drawingcache)。按上面的道理试了一下,设置一个hardware或者softwarelayerOK了。

现在又碰到了另外一个问题,打开硬件加速后,在一些机器上面(我的是3.2WebView有时会出现某一块区域白屏的问题。默认的layer typenone,改为hardware也不行,设置为software就解决了。当然关闭硬件加速也好了,可是那样的话程序整体就比较慢了。所以最终方案是整体硬件加速,出问题的WebView设置software

加上这一句,可以让3D的绘制更快一些:getHolder().setType(SurfaceHolder.SURFACE_TYPE_HARDWARE);

hardware acclerator是对整个窗口进行加速,在硬件加速打开时View.isHardwareAcclerator返回true。但每个View可能被渲染到的Canvas是不同的,比如View可能被通过setLayer设置了Layer,这时,Canvas.isHardwareAccelerator返回false
Android
提供了三种硬件加速是否打开的控制级别,分别是Application,Activity,Window,View

这样,会在一定程度上减少白页或者黑页的产生

 

其次,在activity中开启WebViewjs功能,

webView.getSettings().setJavaScriptEnabled(true);

加载页面

webView.loadUrl(url);

webView.setWebViewClient(new WebViewClient() {

                    @Override

                    publicboolean shouldOverrideUrlLoading(WebView view, String url) {

                           view.loadUrl(url);

                           returnsuper.shouldOverrideUrlLoading(view, url);

                    }

                    @Override

                    publicvoid onPageStarted(WebView view, String url, Bitmap favicon) {

                           LoadingUtils.startLoading(context,StringUtil.getResources(

                                         context,R.string.login_loading));

                    }

                    @Override

                    publicvoid onPageFinished(WebView view, String url) {

                           LoadingUtils.stopLoading();

                    }

             });

这里值得注意的是,在加载页面的时候,一方面可以在js页面添加loading框,如果是iosandroid通用页面,则要使用WebViewClient,在WebViewClient中自定义加载框

shouldOverrideUrlLoading是指重新加载页面时候,调用的方法

onPageStarted是指加载页面之前要加载的方法

onPageFinished是指页面加载结束之后调用的方法

 

WebView调用js

WebView调用js的方式是,直接loadUrl,即

webview.loadUrl("javascript:js方法名()");

 

js调用android方法

格式为:window.别名.方法名,即

onClick="window.别名.方法名()"

WebView中设置方法的别名,即

webView.addJavascriptInterface(newDemoJavaScriptInterface(), "别名");

值得注意的是,android4.2以后再js调用android方法时,为了处于安全考虑,增加了输入限制,即必须要在调用的方法名称上添加@JavascriptInterface标志,而且还要使用多线程,不能在主线程中实现。即

@JavascriptInterface

             publicvoid pushNext(final String url) {

                    mHandler.post(newRunnable() {

                           publicvoid run() {

                                  webView.loadUrl("http://www.baidu.com");

                           }

                    });

 

暂时总结到这里

0 0
原创粉丝点击