Android中WebView使用详解

WebView是Android中一个用于展示网页的控件,我们借助于这个控件可以简单的实现在Android应用中展示自己的网页。

一、简单的浏览器展示网页

我们需要获取到WebView控件,然后进行简单的设置即可。下面是一个最简单的例子。

activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <Button
            android:id="@+id/back"
            android:layout_alignParentLeft="true"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:text="返回"/>
        <TextView
            android:id="@+id/web_title"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="40dp" />
        <Button
            android:id="@+id/refresh"
            android:layout_width="60dp"
            android:layout_height="40dp"
            android:layout_alignParentRight="true"
            android:text="刷新"/>
    </RelativeLayout>
    <WebView
        android:id="@+id/show_web"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </WebView>
</LinearLayout>

MainActivity.java文件

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  private Button back;
  private Button refresh;
  private TextView webTitle;
  private WebView webView;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      initView();
      setWeb();
  }

  private void initView() {
      if (getSupportActionBar()!= null){
          getSupportActionBar().hide();
      }
      back = (Button) findViewById(R.id.back);
      back.setOnClickListener(this);
      webTitle = (TextView) findViewById(R.id.web_title);
      refresh = (Button) findViewById(R.id.refresh);
      refresh.setOnClickListener(this);
      webView = (WebView) findViewById(R.id.show_web);

  }

  private void setWeb() {
      //使其支持JavaScript
      webView.getSettings().setJavaScriptEnabled(true);
      //在此WebView里面打开网页,当从一个网页跳转到另一个网页时,还是在此WebView里面显示,而不是打开系统浏览器
      webView.setWebViewClient(new WebViewClient());
      webView.setWebChromeClient(new WebChromeClient(){
          @Override
          public void onReceivedTitle(WebView view, String title) {
              webTitle.setText(title);
          }
      });
      //需要展示的页面的url
      webView.loadUrl("http://www.baidu.com");
  }

  @Override
  public void onClick(View view) {
      switch (view.getId()){
          case R.id.back:
              finish();
              break;
          case R.id.refresh:
              webView.reload();
              break;
          default:
              break;
      }
  }
}

注:我们还需要在AndroidManifest.xml文件中添加网络访问权限

<uses-permission android:name="android.permission.INTERNET"/>
二、WebView实现文件下载

WebView实现下载主要是给WebView添加DownloadListener下载监听,然后根据监听到的下载URL去处理文件下载。

1、新建一个HttpThread.java下载类

/**
* Http下载类
*/
public class HttpThread extends Thread{
  private String mUrl;
  public HttpThread(String url){
      mUrl = url;
  }
  @Override
  public void run() {
      try {
          URL httpUrl = new URL(mUrl);
          //打开连接
          HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
          //打开输入输出流
          conn.setDoInput(true);
          conn.setDoInput(true);
          InputStream in = conn.getInputStream();

          File downloadFile;
          File sdFile;
          FileOutputStream out = null;
          //判断SD卡是否已经挂载
          if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
              downloadFile = Environment.getExternalStorageDirectory();
              sdFile = new File(downloadFile, "test.apk");
              out = new FileOutputStream(sdFile);
          }

          //缓冲流
          byte[] b = new byte[6 * 1024];
          int len;
          while ((len = in.read(b)) != -1){
              if (out != null){
                  out.write(b, 0, len);
              }
          }

          if (out != null){
              out.close();
          }
          if (in != null){
              in.close();
          }
      } catch (MalformedURLException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
}

2、新建内部下载监听类

class myDownload implements DownloadListener{

    @Override
    public void onDownloadStart(String s, String s1, String s2, String s3, long l) {
        new HttpThread(s).start();
    }
}

3、给WebView添加下载监听

webView.setDownloadListener(new myDownload());

注:由于涉及到SD卡的读写操作和网络连接,我们还需要在AndroidManifest.xml文件中添加SD卡读写权限和网络连接权限。

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

上面是我们自己实现了文件的下载,自己处理网络连接和文件写入,其实,我们也可以调用系统的下载。只需要在上面的基础上修改下载监听内部类即可。

class myDownload implements DownloadListener{

   @Override
   public void onDownloadStart(String s, String s1, String s2, String s3, long l) {
       Uri uri = Uri.parse(s);
       Intent intent = new Intent(Intent.ACTION_VIEW, uri);
       startActivity(intent);
   }
}
三、WebView加载出现错误时的处理

方法一:加载本地错误处理的html页面

webView.setWebViewClient(new WebViewClient(){
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        super.onReceivedError(view, errorCode, description, failingUrl);
        view.loadUrl("file:///android_asset/error.html");
    }
});

方法二:加载错误处理布局
首先我们在布局页面中加入错误显示的TextView控件,当出现加载错误时,我们只需要在上面的onReceivedError()方法中显示TextView控件,并将WebView隐藏即可,这部分比较简单,就不放上代码了。

四、WebView的Cookie同步问题

有时候,我们在我们的应用中使用了WebView控件,当我们在应用中登录之后,当转入应用内的WebView页面时,我们希望可以实现用户cookie同步,免去让用户再次登录的麻烦,此时就需要使用cookie同步。

下面只给出通过Handler获得登录之后传过来的cookie信息,并进行同步设置的代码,服务器端代码和客户端网络请求进行登录的代码。

private Handler handler = new Handler(){
   @Override
   public void handleMessage(Message msg) {
       CookieSyncManager.createInstance(MainActivity.this);
       CookieManager manager = CookieManager.getInstance();
       manager.setCookie("http://192.168.31.5:8080/webs", msg.obj.toString());
       CookieSyncManager.getInstance().sync();
     webView.loadUrl("http://192.168.31.5:8080/webs/index.jsp");
   }
};
五、WebView中的JavaScript调用java本地代码

在WebView中的JavaScript可以调用我们声明的本地方法,下面是一个简单的例子。

1、首先创建一个简单的类,以备待会供js调用。

public class WebHost {
    private Context mContext;
    public WebHost(Context context){
        mContext = context;
    }

    @JavascriptInterface
    public void callJs(){
        Toast.makeText(mContext, "call js", Toast.LENGTH_LONG).show();
    }
}

2、设置WebView支持JavaScript并映射本地方法。

//使其支持JavaScript
webView.getSettings().setJavaScriptEnabled(true);
//将java方法映射给js
webView.addJavascriptInterface(new WebHost(this), "js");

3、在JavaScript中调用相关方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h1 align="center">ERROR</h1>
<input type="button" id="btn" value="click" onclick="call()">

<script type="text/javascript">
        function call(){
            document.getElementById("btn").onclick = function(){
                //调用映射的本地方法
                js.callJs();
            }
        }
    </script>
</body>
</html>

注:刚开始写的时候,JavaScript始终无法调用成功,后来才知道,需要注意以下两点:
1、被JavaScript调用的方法必须声明为public
2、必须在被JavaScript调用的方法前面加入注解@JavascriptInterface

注意:WebView中的JavaScript调用java本地方法,在应用混淆打包之后JavaScript调用会失效,所以我们需要配置混淆文件,使其忽略混淆被JavaScript调用的java代码。

具体做法:在proguard-rules.pro文件中加入如下配置

-keep public class com.example.webviewdemo.WebHost{
    public <methods>;
}
六、WebView自定义协议拦截

上面我们通过JavaScript可以调用Java的本地代码,但这存在着严重的注入问题,我们应该尽量避免这种调用,而采用自定义协议的方式,下面是一个简单的例子。

1、在html页面中设置一个可以点击的链接

<a href="http://www.baidu.com?startActivity">Next</a>

此链接点击时会带参数过去。
2、在Activity中检测url的结尾字符串,从而做出不同相应

webView.setWebViewClient(new WebViewClient(){
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.endsWith("?startActivity")){
            Intent intent = new Intent(MainActivity.this, Main2Activity.class);
            startActivity(intent);
            return true;
        }
        return super.shouldOverrideUrlLoading(view, url);
    }
});

通过这样我们便可以实现点击WebView中的链接让Activity进行跳转。
以上便是WebView相关的使用,这些基本覆盖了我们开发者需要到的一半的基础知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值