android webview 开发

开发工具:

  • Android Studio Arctic Fox | 2020.3.1 Patch 2

1、创建项目

File => New => New Project => Empty Activity

(1)第一步选择 New Project

page_1.png

(2)第二步选择 Empty Activity

page_2.png

(3)第三步设置项目名称及地址

page_3.png

2、目录结构

(1)设置目录结构

设置项目结构为 Project,该目录下文件路径非常清晰

page_4.png

(2)目录结构说明

使用指引创建空项目,会自动生成标准的项目目录结构

page_5.png
  • .gradle Android Studio 构建系统
  • .idea 编辑器 配置
  • app 应用目录
    • build 打包后的目录文件
    • libs 第三方 jar 包
    • src 源文件
      • main 源文件主目录
        • java 代码目录
          • com.xxx.myapplication2 源代码文件目录
        • res resource 资源
          • layout 页面布局目录
        • AndroidManifest.xml 应用清单
    • .gitignore git 不需要提交的文件列表
    • build.gradle 配置整个 app 应用
    • proguard-rules.pro 编译混淆配置
  • gradle/wrapper 简化 Gradle 本身的安装、部署
  • .gitignore git 不需要提交的文件列表
  • build.gradle 配置整个工程
  • gradle.properties Gradle 文件的全局性的配置
  • gradlew UN*X 的 Gradle 启动脚本
  • gradlew.bat Windows 的 Gradle 启动脚本
  • local.properties SDK的位置配置
  • settings.gradle 配置 gradle

3、设置 Android SDK 版本

android {
  compileSdk 31
  buildToolsVersion '31.0.0'
  compileSdkVersion 31
  defaultConfig {
        applicationId "com.example.myapplication2"
        minSdk 21 // 最小sdk
        targetSdk 31
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
}

4、设置 WebView layout

layout 目录地址:

app => src => main => res => layout => activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:aandroid="http://schemas.android.com/apk/res/android"
    aandroid:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context=".MainActivity">

    <WebView
        android:id="@+id/wv_webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbars="horizontal"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

配置 WebView 组件 id android:id="@+id/wv_webview"

5、配置程序权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
<uses-feature android:name="android.hardware.camera" android:required="true"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>

6、在程序入口初始化 WebView

一般程序入口文件为:

app => src => main => java => com.xxx.myapplication2 => MainActivity.java

onCreate() 里面编写初始化程序:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // 开启 WebView 长截图,在 setContentView() 方法前面设置才有效
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        WebView.enableSlowWholeDocumentDraw();
    }

    setContentView(R.layout.activity_main);

    // 隐藏顶部标题栏
    getSupportActionBar().hide();

    // 去除状态栏
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    // 初始化 WebView
    initWebView();
}

// 销毁 webView
@Override
protected void onDestroy() {
    if (this.webView != null) {
        webView.destroy();
    }
    super.onDestroy();
}

@Override
protected void onResume() {
    /**
      * 设置为横屏
      */
    // if(getRequestedOrientation()!= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
    //     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    // }
    super.onResume();
}

初始化代码:

private WebView webView;
private void init()
{
    webView = (WebView) findViewById(R.id.wv_webview);
    WebSettings settings = webView.getSettings(); // webView 配置项
    settings.setUseWideViewPort(true); // 是否启用对视口元标记的支持
    settings.setJavaScriptEnabled(true); // 是否启用 JavaScript
    
    settings.setDomStorageEnabled(true); // 是否启用本地存储(允许使用 localStorage 等)
    settings.setAllowFileAccess(true); // 是否启用文件访问

    settings.setAppCacheEnabled(true); // 是否应启用应用程序缓存
    settings.setAppCacheMaxSize(1024*1024*8); // 设置应用程序缓存内容的最大大小
    String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath(); // 缓存地址
    settings.setAppCachePath(appCachePath); // 设置缓存地址

    settings.setAllowContentAccess(true); // 是否启用内容 URL 访问
    settings.setJavaScriptCanOpenWindowsAutomatically(true); // 是否允许 JS 弹窗
    settings.setMediaPlaybackRequiresUserGesture(false); // 是否需要用户手势来播放媒体

    settings.setLoadWithOverviewMode(true); // 是否以概览模式加载页面,即按宽度缩小内容以适应屏幕
    settings.setBuiltInZoomControls(true); // 是否应使用其内置的缩放机制

    if(Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
        // Hide the zoom controls for HONEYCOMB+
        settings.setDisplayZoomControls(false); // 是否应显示屏幕缩放控件
    }

    // Enable remote debugging via chrome://inspect
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        WebView.setWebContentsDebuggingEnabled(true); // 是否开启 WebView 调试功能,配合PC端 Chrome DevTools 功能使用
    }

    settings.setAllowFileAccessFromFileURLs(true); // 是否应允许在文件方案 URL 上下文中运行的 JavaScript 访问来自其他文件方案 URL 的内容
    settings.setAllowUniversalAccessFromFileURLs(true); // 是否应允许在文件方案URL上下文中运行的 JavaScript 访问任何来源的内容

    webView.loadUrl("https://www.baidu.com"); // 设置访问地址
    webView.addJavascriptInterface(new JsInterface(this, webView, MainActivity.this),"jsWebView"); // 设置 js 调用接口
    webView.setDrawingCacheEnabled(true); // 启用或禁用图形缓存
    webView.setWebViewClient(new WVViewClient()); // 帮助 WebView 处理各种通知、请求事件
    webView.setWebChromeClient(new WVChromeClient(this, MainActivity.this)); // 处理解析,渲染网页
}

new JsInterface() 代码:

public class JsInterface {
  private Context _context;
  private final WebView _webview;
  private MainActivity _m;
  public  JsInterface(Context context, WebView webView, MainActivity mainActivity)
  {
      _context = context;
      _webview = webView;
      _m = mainActivity;
  }

  // 开放 test 方法给 js,在 web 页面使用 window.test('hello'); 调用。
  @JavascriptInterface
  public void test(String val){
      Log.i("test",val);
      _webview.post(new Runnable() {
          @Override
          public void run() {
              _webview.loadUrl("javascript:cbMessage('message');",null); // java 调用 js 的 cbMessage 方法
          }
      });
  }
}

new WVViewClient() 代码:

public class WVViewClient extends WebViewClient {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        if (handler != null) {
            handler.proceed();//忽略证书的错误继续加载页面内容,不会变成空白页面
        }
    }
}

new WVChromeClient() 代码:

public class WVChromeClient extends WebChromeClient{
  private Context _context;
  private MainActivity _m;
  public WVChromeClient(Context context, MainActivity mainActivity)
  {
      _context = context;
      _m = mainActivity;
  }

   @Override
  public void onProgressChanged(WebView view, int newProgress) {
      super.onProgressChanged(view, newProgress);
      Log.d("MainActivity","newProgress:"+ newProgress );
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容