Android WebView示例教程

时间:2020-02-23 14:29:24  来源:igfitidea点击:

Android WebView用于在android应用中显示HTML。
我们可以使用android WebView将HTML页面加载到android应用中。

Android WebView

Android WebView组件是一种成熟的浏览器,实现为" View"子类,可将其嵌入到我们的android应用程序中。

Android WebView的重要性

对于受范围限制HTML代码,我们可以实现属于HTML Utility类的静态方法fromMtml()来解析HTML格式的字符串并将其显示在TextView中。

TextView可以呈现简单的格式,例如样式(粗体,斜体等),字体(衬线,无衬线等),颜色,链接等。

但是,当涉及到复杂的格式和更大HTML范围时,TextView无法很好地处理它。
例如,将无法通过TextView浏览Facebook。

在这种情况下,WebView将是更合适的小部件,因为它可以处理范围更广HTML标签。
WebView还可以处理CSS和JavaScript,而Html.fromHtml()只会被忽略。

WebView还可以协助常见的浏览隐喻,例如已访问URL的历史列表,以支持向后和向前导航。

WebView仍然具有自己的缺点,例如,在内存消耗方面,它比TextView使用起来要昂贵得多。
内存增加的原因是因为WebView由WebKit/Blink提供支持,它们是开放源Web渲染引擎,可为诸如Chrome之类的浏览器提供内容。

Android WebView示例

Android WebView组件被插入到XML布局文件中,以用于我们想要显示WebView的布局。
在此示例中,我们将其插入到" activity_main.xml"文件中,如下所示:

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
  xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent"
  android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

  <WebView
      android:id="@+id/webview"
      android:layout_alignParentTop="true"
      android:layout_alignParentLeft="true"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
</RelativeLayout>

Android Studio WebView代码

WebView组件在MainActivity中使用在activity_main.xml中定义的ID进行初始化,如以下代码段所示:

WebView webView = (WebView) findViewById(R.id.webview);

Android WebView loadUrl

一旦获得对WebView的引用,我们就可以对其进行配置并通过HTTP加载URL。
WebView的loadUrl()方法用于将URL加载到WebView中,如下所示:

webView.loadUrl("https://www.theitroad.local");

在开始使用url之前,我们应该看一下两个关键方面:

  • 支持JavaScript:默认情况下,WebView小部件中JavaScript是关闭的。
    因此,包含javascript参考的网页将无法正常运行。
    要启用Java脚本,需要在webview实例上调用以下代码段:
  • 添加权限:要在WebView中获取并加载网址,我们需要在应用程序内添加访问Internet的权限,否则将无法加载网页。
    需要在应用标签上方的AndroidManifest.xml文件中添加以下代码行,如下所示:

下面的MainAcivity类包含到目前为止讨论的所有功能。

getSettings().setJavaScriptEnabled(true);

设置WebViewClient

用户单击网页内的链接时的默认行为是打开系统的默认浏览器应用程序。
这可能会破坏应用程序用户的用户体验。

为了使页面导航保持在WebView以及应用程序内,我们需要创建WebViewClient的子类,并覆盖其shouldOverrideUrlLoading(WebView webView,String url)方法。

这是这样的WebViewClient子类的外观:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
  package="com.theitroad.webview" >

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

  <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >
      <activity
          android:name=".MainActivity"
          android:label="@string/app_name" >
          <intent-filter>
              <action android:name="android.intent.action.MAIN" 

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

</manifest>

当shouldOverrideUrlLoading()方法返回false时,作为参数传递给该方法的URL将被加载到WebView中,而不是浏览器中。

为了区分应用程序和浏览器中加载的URL,需要在shouldOverrideUrlLoading()方法中添加以下代码:

package com.theitroad.webview;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      WebView webView = (WebView) findViewById(R.id.webview);

      WebSettings webSettings = webView.getSettings();
      webSettings.setJavaScriptEnabled(true);

      webView.loadUrl("https://www.theitroad.local");
  }

}

注意:返回true并不表示该网址已在浏览器应用中打开。
实际上,该网址完全不会打开。
要将网址加载到浏览器中,需要触发意图。
以下子类包含我们添加的所有配置。

private class MyWebViewClient extends WebViewClient {
  @Override
  public boolean shouldOverrideUrlLoading(WebView webView, String url) {
      return false;
  }
}

构造函数将Activity作为参数在浏览器中激发意图。

在MainActivity中实例化此子类之前,让我们看一下另一个重要功能。

带后退按钮的导航WebView

如果我们在到目前为止开发的应用程序中单击"后退"按钮,即使我们已经浏览了WebView本身中的几个页面,也会看到该应用程序返回到主屏幕。
要查看按"后退"按钮的浏览历史记录,我们需要修改"后退"按钮的功能,如下面的代码片段所示:

if(url.indexOf("theitroad.local") > -1 ) return false;
      return true;

onKeyDown()方法已被实现为先覆盖的实现,该实现首先检查WebView是否可以返回。
如果用户已经导航离开WebView内加载的第一页,则WebView可以返回。

WebView像正常浏览器一样维护浏览历史记录。
如果没有历史记录,则将导致后退按钮的默认行为,即退出应用程序。

以下是包含上述功能的MainActivity的代码。

package com.theitroad.webview;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class WebViewClientImpl extends WebViewClient {

  private Activity activity = null;

  public WebViewClientImpl(Activity activity) {
      this.activity = activity;
  }

  @Override
  public boolean shouldOverrideUrlLoading(WebView webView, String url) {
      if(url.indexOf("theitroad.local") > -1 ) return false;

      Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
      activity.startActivity(intent);
      return true;
  }

}

下图显示了我们的项目产生的输出,您可以看到WebView已加载了预分配的url。

在WebView中加载内容的替代方法

到目前为止,我们仅使用loadUrl()方法将内容加载到WebView中。
在简要介绍loadUrl()的用法之后,我们将在这里看到加载内容的其他方式。

loadUrl()适用于:

  • https://和https://URL
  • file://指向本地文件系统的URL
  • file:///android_asset /指向您的应用程序资产之一的URL
  • content://指向发布内容的ContentProvider的URL
    可用于流媒体

代替loadUrl(),我们可以使用loadData(),通过它可以在方法中显示代码片段或者整个HTML代码。
有两种形式的loadData()。
简单的一种允许我们以字符串形式提供内容,MIME类型和编码。
通常,MIME类型将是text/html,编码将是普通HTML的UTF-8,如下所示:

@Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
      if ((keyCode == KeyEvent.KEYCODE_BACK) && this.webView.canGoBack()) {
          this.webView.goBack();
          return true;
      }

      return super.onKeyDown(keyCode, event);
  }

下面是在MainActivity中添加上述代码段后的输出,如下所示:

package com.theitroad.webview;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class MainActivity extends Activity {

  private WebView webView = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      this.webView = (WebView) findViewById(R.id.webview);

      WebSettings webSettings = webView.getSettings();
      webSettings.setJavaScriptEnabled(true);

      WebViewClientImpl webViewClient = new WebViewClientImpl(this);
      webView.setWebViewClient(webViewClient);

      webView.loadUrl("https://www.theitroad.local");
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
      if ((keyCode == KeyEvent.KEYCODE_BACK) && this.webView.canGoBack()) {
          this.webView.goBack();
          return true;
      }

      return super.onKeyDown(keyCode, event);
  }

}

还有一个loadDataWithBaseURL()方法。
除其他参数外,这需要解析HTML中的相对URL时要使用的基本URL。
任何相对URL(例如<img src =" images/sample.png">)都将被解释为相对于提供给loadDataWithBaseURL()的基本URL。

historyUrl参数是要写入WebView内部导航历史记录的URL,该历史记录是针对载入WebViewHTML的。
以下代码片段显示了其原型:

webView.loadData("<html><body>Hello, world!</body></html>",
                "text/html", "UTF-8");