android webview 開發(fā)

開發(fā)工具:

  • Android Studio Arctic Fox | 2020.3.1 Patch 2

1涝焙、創(chuàng)建項目

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

(1)第一步選擇 New Project

page_1.png

(2)第二步選擇 Empty Activity

page_2.png

(3)第三步設置項目名稱及地址

page_3.png

2挖诸、目錄結(jié)構(gòu)

(1)設置目錄結(jié)構(gòu)

設置項目結(jié)構(gòu)為 Project纱新,該目錄下文件路徑非常清晰

page_4.png

(2)目錄結(jié)構(gòu)說明

使用指引創(chuàng)建空項目,會自動生成標準的項目目錄結(jié)構(gòu)

page_5.png
  • .gradle Android Studio 構(gòu)建系統(tǒng)
  • .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墩瞳、配置程序權(quán)限

<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();

    // 去除狀態(tài)欄
    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); // 設置應用程序緩存內(nèi)容的最大大小
    String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath(); // 緩存地址
    settings.setAppCachePath(appCachePath); // 設置緩存地址

    settings.setAllowContentAccess(true); // 是否啟用內(nèi)容 URL 訪問
    settings.setJavaScriptCanOpenWindowsAutomatically(true); // 是否允許 JS 彈窗
    settings.setMediaPlaybackRequiresUserGesture(false); // 是否需要用戶手勢來播放媒體

    settings.setLoadWithOverviewMode(true); // 是否以概覽模式加載頁面喉酌,即按寬度縮小內(nèi)容以適應屏幕
    settings.setBuiltInZoomControls(true); // 是否應使用其內(nèi)置的縮放機制

    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 調(diào)試功能热凹,配合PC端 Chrome DevTools 功能使用
    }

    settings.setAllowFileAccessFromFileURLs(true); // 是否應允許在文件方案 URL 上下文中運行的 JavaScript 訪問來自其他文件方案 URL 的內(nèi)容
    settings.setAllowUniversalAccessFromFileURLs(true); // 是否應允許在文件方案URL上下文中運行的 JavaScript 訪問任何來源的內(nèi)容

    webView.loadUrl("https://www.baidu.com"); // 設置訪問地址
    webView.addJavascriptInterface(new JsInterface(this, webView, MainActivity.this),"jsWebView"); // 設置 js 調(diào)用接口
    webView.setDrawingCacheEnabled(true); // 啟用或禁用圖形緩存
    webView.setWebViewClient(new WVViewClient()); // 幫助 WebView 處理各種通知、請求事件
    webView.setWebChromeClient(new WVChromeClient(this, MainActivity.this)); // 處理解析泪电,渲染網(wǎng)頁
}

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'); 調(diào)用。
  @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 調(diào)用 js 的 cbMessage 方法
          }
      });
  }
}

new WVViewClient() 代碼:

public class WVViewClient extends WebViewClient {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        if (handler != null) {
            handler.proceed();//忽略證書的錯誤繼續(xù)加載頁面內(nèi)容歪架,不會變成空白頁面
        }
    }
}

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 );
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末股冗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子和蚪,更是在濱河造成了極大的恐慌,老刑警劉巖烹棉,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攒霹,死亡現(xiàn)場離奇詭異,居然都是意外死亡浆洗,警方通過查閱死者的電腦和手機催束,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伏社,“玉大人抠刺,你說我怎么就攤上這事≌” “怎么了速妖?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長聪黎。 經(jīng)常有香客問我罕容,道長,這世上最難降的妖魔是什么稿饰? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任锦秒,我火速辦了婚禮,結(jié)果婚禮上喉镰,老公的妹妹穿的比我還像新娘旅择。我一直安慰自己,他們只是感情好侣姆,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布生真。 她就那樣靜靜地躺著脖咐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪汇歹。 梳的紋絲不亂的頭發(fā)上屁擅,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音产弹,去河邊找鬼派歌。 笑死,一個胖子當著我的面吹牛痰哨,可吹牛的內(nèi)容都是我干的胶果。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼斤斧,長吁一口氣:“原來是場噩夢啊……” “哼早抠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撬讽,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤蕊连,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后游昼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甘苍,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年烘豌,在試婚紗的時候發(fā)現(xiàn)自己被綠了载庭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡廊佩,死狀恐怖囚聚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情标锄,我是刑警寧澤顽铸,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站鸯绿,受9級特大地震影響跋破,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瓶蝴,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一毒返、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舷手,春花似錦拧簸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贾富。三九已至,卻和暖如春牺六,著一層夾襖步出監(jiān)牢的瞬間颤枪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工淑际, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留畏纲,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓春缕,卻偏偏與公主長得像盗胀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子锄贼,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容