Webview的使用

一、webview的请求方式

1.1、get方式

//get方式请求
mWebView.loadUrl("url");  //网络路径
mWebView.loadUrl("file:///android_asset/test.html");   //APP本地的Html


//post方式请求,带参数
String postDate = "name=abc&type=1";
mWebView.postUrl(url, postDate.getBytes());

1.2、webview的下载文件

//调用系统浏览器实现下载功能 
webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
                intent.setData(Uri.parse(url));
                startActivity(intent);
            }
        });

1.3、setting属性

WebSettings wSet = mWebView.getSettings();
wSet.setJavaScriptEnabled(true);  //可以与js交互

wSet.setCacheMode(WebSettings.LOAD_NO_CACHE);    //无缓存

wSet.setDomStorageEnabled(true); // 用于解决webview加载的网页不能点击

webSettings.setSupportZoom(true);   //支持屏幕缩放
webSettings.setBuiltInZoomControls(true);

wSet.setUserAgentString(wSet.getUserAgentString() + ";Android");  //添加agent特有表示

1.4、设置webviewClient

mWebView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                return super.shouldOverrideUrlLoading(view, request);
                //重定向(也可以做与js的交互)
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }
            
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                //请求异常,加载本地异常页面
            }
        });

1.5、设置webChromeClient

mWebView.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                //进度条
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                //获取html的title
            }
        });

1.6、webview的前进后退

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (mWebView.canGoBack()) {
        mWebView.goBack();
        //当前显示的页面是内部重定向的时候打开的,当返回时,并不会显示上一个页面的title,显示的还是当前页面的title,这里需要做特殊处理,可以把所有的title添加到一个集合里,
  
        return true;
    }
    if (mWebView.canGoForward()) {
        mWebView.goForward();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

1.8、清除缓存

//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
mWebView.clearCache(true);

//清除当前webview的访问历史记录里
mWebView.clearHistory();

//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据
mWebView.clearFormData();

二、Html与js交互方式

1、监听webviewClient的shouldOverrideUrlLoading()方法

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                return super.shouldOverrideUrlLoading(view, request);
                //重定向(也可以做与js的交互)
                Uri uri = request.getUrl();
                String schemeStart = uri.getScheme().toLowerCase();
                if (schemeStart.equals("android")) {
                    
                }
            }

2、添加javascriptInterface方式

WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new Demo(), "demo");//demo为前端和Html共同约定的

//交互类
public class Demo {

    @JavascriptInterface
    public void getMethod() {

    }
}
js调用原生方法  
demo.getMethod();

(1)原生调用js

  方式一:loadUrl,不能获取js的返回值,会刷新页面

getText是js方法无参
mWebView.loadUrl("javascript:getText()");

一个参数,注意单引号
String params="value";
mWebView.loadUrl("javascript:getText('"+jsonParams+"')");

json参数,注意单引号
JSONObject jsonParams=new JSONObject();
jsonParams.put("key","value");
mWebView.loadUrl("javascript:getText('"+jsonParams.toString()+"')");

   方式二:evaluateJavascript  安卓4.4以后才可以使用,可以获取js返回值

webView.evaluateJavascript("javascript:getText()",
                   new ValueCallback<String>() {
                    @Override
                   public void onReceiveValue(String value) {}
                    });

 

3、jsBridge方式

3.1、引入jar包

compile 'com.github.lzyzsd:jsbridge:1.0.4'
allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

3.2、xml文件

<com.github.lzyzsd.jsbridge.BridgeWebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

3.3、android端初始化

//设置简单没有回调的调用方式
mWebView.setDefaultHandler(new DefaultHandler());
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new BridgeWebViewClient(mWebView));

3.4、js端初始化,注册监听(Android调用js是要再js中注册监听)

// 注册事件监听
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
    callback(WebViewJavascriptBridge)
} else {
    document.addEventListener(
            'WebViewJavascriptBridgeReady'
            , function() {
        callback(WebViewJavascriptBridge)
    },
    false
       );
}

3.5、Html调用android端

//Js端代码
function testClick(){
    window.WebViewJavascriptBridge.callHandler(
            'function_name',
            {'Data':'给native的数据'},
            function(responseData){
          //在native操作后,会传数据responseData给js,js继续自己的操作
      }
    );
}


//Native端代码
mWebView.registerHandler("function_name", new BridgeHandler() {
    @Override
    public void handler(String data, CallBackFunction function) {
        //data是js返回的数据,在native中用
        function.onCallBack("传递数据给js");
    }
});

//function_name是方法名,前后端要一致

3.6、android调用js方法

//Native端
mWebView.callHandler("function_name", "传递给js的数据", new CallBackFunction() {
    @Override
    public void onCallBack(String data) {
        //调用完js后,data是js返回的数据,然后native在这执行自己的逻辑
    }
});

//js端
bridge.registerHandler("function_name", function(data, responseCallback) {
//data是Android带过来的数据
    responseCallback(responseData);//回调返回给Android端
});

3.7、jsBridge的优点

android api4.4之前,谷歌的webview存在安全漏洞,网站js注入,所以调用java方法需要加入@javascriptinterface注解。

3.8、jsBridge原理

     JsBridge是Native代码合Js代码的通信桥梁。思路是:Html5触发  Url scheme---->Native捕获uri scheme---->原生分析,执行---->原生调用Html5。如下图:

详细思路如下:

三、webview的优化

1、webview的创建

    不要在xml中定义webview,而是在需要的时候在创建webview,并且context使用getApplicationContext

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mWebView = new WebView(getApplicationContext());
mWebView.setLayoutParams(params);
mLayout.addView(mWebView);

2、webview的销毁

先把webview从其父控件移除,然后调动destory方法

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ((ViewGroup)mWebView.getParent()).removeView(mWebView);
        mWebView.destroy();
        mWebView=null;
    }

四、Html打开原生app

1、使用scheme

<a href="[scheme]://[host]/[path]?[query]">启动应用程序</a>

2、代码

在app的启动页配置scheme

      <activity
            android:name=".base.SplashActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <!--通过浏览器Url启动app-->
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="scheme" />
            </intent-filter>

        </activity>

在启动页的获取数据

private Uri schemeUriData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_splash);
        context = this;
        if (getIntent() != null) {
            schemeUriData = getIntent().getData();
            Uri uri = Uri.parse(data);
            String path = uri.getPath();
            if (path.endsWith("order")) {//打开订单
            }
        }

    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值