为了账号安全,请及时绑定邮箱和手机立即绑定

Android WebView相关设置

标签:
Android

最近刚好在用WebView对接一些接口设置,就写下来记录一下吧,希望能帮到遇到同样问题的人。

##一、基本设置 一般WebView不做多余配置,没有交互要求,只是很简单的载入网页的话,基本下面的配置就够用了

[代码]java代码:

?

1

2

3

4

5

6

WebSettings mWebSettings = mWebView.getSettings();

    mWebSettings.setSupportZoom(true);

    mWebSettings.setLoadWithOverviewMode(true);

    mWebSettings.setUseWideViewPort(true);

    mWebSettings.setDefaultTextEncodingName("GBK");

    mWebSettings.setLoadsImagesAutomatically(true);

 

上面可以看到,对于基本的使用,配置是很简单的,没什么太多需要自己注意的,接下来就是一些手机APP上载入网页的时候用得比较多的情况了,下面会一一列出。

##二、JS与APP交互 这种情况一般是比较常见的,就是JS网页调用APP的方法做一些本地事情,然后是APP调用JS的方法反馈一些情况什么的。

而要实现这个最重要的一个设置就是这个 mWebSettings.setJavaScriptEnabled(true); 要使能webview可以调用JS方法

1)APP调用JS方法

[代码]java代码:

?

1

2

3

mWebView.loadUrl("javascript:test()");// 调用js函数无参数

 

mWebView.loadUrl("javascript:test(test)"); //test是js的函数test()的参数

 

2)JS调用APP方法 JS调用APP的方法也比较简单,只要添加JavascriptInterface方法接口即可

[代码]java代码:

?

1

mWebView.addJavascriptInterface(mWebAppInterface,   "AndroidWebAppInterface");

 

然后实现JS需要调用的方法,这里需要注意的就是安卓版本大于17的时候,需要在JS方法上加上注解

@JavascriptInterface

@JavascriptInterface

@JavascriptInterface

重要的事情说三遍

像这样

[代码]java代码:

?

1

2

3

4

5

6

// 如果target 大于等于API 17,则需要加上如下注解

    @JavascriptInterface

    public void showToast(String   toast) {

        LogUtils.d(TAG,   "toast = " + toast);

        Toast.makeText(mContext,   toast, Toast.LENGTH_LONG).show();

    }

 

##三、HTML5数据存储(LocalStorage)

有时候网页需要自己保存一些关键数据,这个时候就需要用到像LocalStorage这些东西了,而安卓WebView默认是无法使用的,也是需要用户自己配置的,感觉好坑啊,IOS的直接加载啥都不用配置就都能用了,安卓直接用啥都不行,感觉被虐惨了。下面是关键配置,最最重要就是这个

mWebSettings.setDomStorageEnabled(true);mWebSettings.setDomStorageEnabled(true);mWebSettings.setDomStorageEnabled(true);

重要的事情说三遍

[代码]java代码:

?

1

2

3

4

5

mWebSettings.setDomStorageEnabled(true);

mWebSettings.setDatabaseEnabled(true);

mWebSettings.setAppCacheEnabled(true);

String appCachePath =   getApplicationContext().getCacheDir().getAbsolutePath();

mWebSettings.setAppCachePath(appCachePath);

 

##四、HTML5定位(获取当前地址)

存储完了,就该是定位了,有时候网页想自己直接获取定位地址,就需要用到定位配置了。当然该有的权限还是得自己加上,比如:

[代码]xml代码:

?

1

2

3

<uses-permission android:name="android.permission.INTERNET">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission></uses-permission></uses-permission>

 

主要的配置就是需要复写WebChromeClient的三个方法

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

@Override

    public void onReceivedIcon(WebView   view, Bitmap icon) {

        super.onReceivedIcon(view,   icon);

    }

 

    @Override

    public void onGeolocationPermissionsHidePrompt()   {

        super.onGeolocationPermissionsHidePrompt();

    }

 

    @Override

    public void onGeolocationPermissionsShowPrompt(final   String origin, final GeolocationPermissions.Callback callback) {

        callback.invoke(origin,   true, false);//注意个函数,第二个参数就是是否同意定位权限,第三个是是否希望内核记住

        super.onGeolocationPermissionsShowPrompt(origin,   callback);

    }

 

基本加上上面的配置基本就OK了,没啥大问题。

##五、遇到的其它坑

1)多窗口的问题

html中的_bank标签就是新建窗口,在处理多窗口的时候需要配置下面的设置,不然可能点击没有反应

[代码]java代码:

?

1

2

mWebSettings.setSupportMultipleWindows(true);

    mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);

 

然后可以复写一下WebChromeClientonCreateWindow方法

[代码]java代码:

?

1

2

3

4

5

6

7

8

    @Override

public boolean onCreateWindow(WebView view, boolean isDialog,

                              boolean   isUserGesture, Message resultMsg) {

    WebView.WebViewTransport   transport = (WebView.WebViewTransport) resultMsg.obj;

    transport.setWebView(mWebView);

    resultMsg.sendToTarget();

    return true;

}

 

2)多页面在同一个WebView中打开,就是不新建activity或者调用系统浏览器打开,需要复写WebViewClientshouldOverrideUrlLoading方法.

[代码]java代码:

?

1

2

3

4

5

    @Override

public boolean shouldOverrideUrlLoading(WebView view,   String url) {

    view.loadUrl(url);

    return true;

}

 

3)WebView进行Http数据请求 这个相对也不复杂,主要是https坑比较大,加载数据基本用下面的就可以了

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

private void getWebData() {

        new Thread()   {

            @Override

            public   void run() {

                OkHttpClient   okHttpClient =   HttpClientSslHelper.getSslOkHttpClient(getApplicationContext(),   AppApiContact.bServerDebug);//new OkHttpClient();

                okHttpClient.setConnectTimeout(15,   TimeUnit.SECONDS);

                Request   request = new Request.Builder()

                        .url(mWebUrl)

                        .build();

                try   {

                    Response   response = okHttpClient.newCall(request).execute();

                    final   String data = response.body().string();

                    LogUtils.d(TAG,   "data = " + data);

                    runOnUiThread(new   Runnable() {

                        @Override

                        public   void run() {

                            if   (StringHelper.notEmpty(data) && !isDestroy) {//页面销毁之后不做处理

    //                            mWebView.loadData(data, "text/html; charset=UTF-8", null);

                                mWebView.loadDataWithBaseURL(null,   data, "text/html", "UTF-8", null);

                            }

                        }

                    });

                }   catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }.start();

    }

 

4)WebView进行HTTPS加密加载(这个坑貌似我还没解决,用的上面的第三种方法绕过去了)

5)JS调用安卓接口传输JSON格式数据 这个真是个大坑,以前一直没啥问题,直接传字符串数据结构就过来了,安卓也能直接解析,但是最近遇到安卓这边接受到数据死活不对,总是undefined值,也就是传输出问题了,后来反复排查才发现,需要对JSON数据字符串进行转义传输,不然就解析不到,也是无语了,例子如下

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

"

    {

        "title":"test   title"

    }

    "

 

    以前传这种字符串过来是可以正常解析的,也不知道发什么神经,突然不行了,必须做转义之后传这种才可以解析

 

    "

    {

        \"title\":\"test   title\"

    }

    "

目前好像就遇到这些,等再遇到了再来更新吧,下面给出全部的配置

[代码]java代码:

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

private void setUpViewComponent() {

        WebSettings   mWebSettings = mWebView.getSettings();

        mWebSettings.setSupportZoom(true);

        mWebSettings.setLoadWithOverviewMode(true);

        mWebSettings.setUseWideViewPort(true);

        mWebSettings.setJavaScriptEnabled(true);

        mWebSettings.setDefaultTextEncodingName("GBK");

        mWebSettings.setSupportMultipleWindows(true);

        mWebSettings.setLoadsImagesAutomatically(true);

        mWebSettings.setDomStorageEnabled(true);

        mWebSettings.setDatabaseEnabled(true);

        mWebSettings.setAppCacheEnabled(true);

        String   appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();

        mWebSettings.setAppCachePath(appCachePath);

        mWebSettings.setAllowFileAccess(true);

        if (AppApplication.getSdkVersion()   >= 11) {

            mWebSettings.setDisplayZoomControls(false);

        } else {

            setZoomControlGone(mWebView);   //Android 3.0(11) 以下使用以下方法

        }

        mSwipeContainer.setOnRefreshListener(this);

        mWebAppInterface   = new WebAppInterface(this);

        setWebViewListener();

    }

 

    private void setZoomControlGone(View   view) {

        Class   classType;

        Field   field;

        try {

            classType   = WebView.class;

            field   = classType.getDeclaredField("mZoomButtonsController");

            field.setAccessible(true);

            ZoomButtonsController   mZoomButtonsController = new ZoomButtonsController(

                    view);

            mZoomButtonsController.getZoomControls().setVisibility(View.GONE);

            try   {

                field.set(view,   mZoomButtonsController);

            }   catch (IllegalArgumentException e) {

                e.printStackTrace();

            }   catch (IllegalAccessException e) {

                e.printStackTrace();

            }

        } catch   (SecurityException e) {

            e.printStackTrace();

        } catch   (NoSuchFieldException e) {

            e.printStackTrace();

        } catch   (Exception ee) {

            ee.printStackTrace();

        }

    }

 

    private void setWebViewListener()   {

        mWebView.addJavascriptInterface(mWebAppInterface,   "AndroidWebAppInterface");

        WebViewClient   webClient = new CustWebViewClient();

        mWebView.setWebViewClient(webClient);

        mWebView.setWebChromeClient(new   WebChromeClient() {

            @Override

            public   boolean onJsAlert(WebView view, String url, String message, JsResult result)   {

                return   super.onJsAlert(view, url, message, result);

            }

 

            @Override

            public   boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture,   Message resultMsg) {

                return   super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);

            }

        });

 

        mWebView.setOnLongClickListener(new   View.OnLongClickListener() {

            @Override

            public   boolean onLongClick(View arg0) {

                return   true;

            }

        });

    }

 

    private class CustomWebViewClient   extends WebViewClient {

        public CustomWebViewClient()   {

            super();

        }

 

        public boolean   shouldOverrideUrlLoading(WebView view, String url) { // 重写此方法表明点击网页里面的链接还是在当前的Web view里跳转,不跳到浏览器那边

            LogUtils.d(TAG,   "url --" + url);

            view.loadUrl(url);

            return   true;

        }

 

        @Override

        public void   onLoadResource(WebView view, String url) {

 

        }

 

        @Override

        public void   onPageFinished(WebView view, String url) {

            mSwipeContainer.setRefreshing(false);

        }

 

        @Override

        public void   onPageStarted(WebView view, String url, Bitmap favicon) {

            mSwipeContainer.setRefreshing(true);

        }

    }

     

    private void getWebData() {

        new Thread()   {

            @Override

            public   void run() {

                OkHttpClient   okHttpClient =   HttpClientSslHelper.getSslOkHttpClient(getApplicationContext(),   AppApiContact.bServerDebug);//new OkHttpClient();

                okHttpClient.setConnectTimeout(15,   TimeUnit.SECONDS);

                Request   request = new Request.Builder()

                        .url(mWebUrl)

                        .build();

                try   {

                    Response   response = okHttpClient.newCall(request).execute();

                    final   String data = response.body().string();

                    LogUtils.d(TAG,   "data = " + data);

                    runOnUiThread(new   Runnable() {

                        @Override

                        public   void run() {

                            if   (StringHelper.notEmpty(data) && !isDestroy) {//页面销毁之后不做处理

    //                            mWebView.loadData(data, "text/html; charset=UTF-8", null);

                                mWebView.loadDataWithBaseURL(null,   data, "text/html", "UTF-8", null);

                            }

                        }

                    });

                }   catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }.start();

原文链接:http://www.apkbus.com/blog-705730-61061.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消