webView的使用(很多坑)


測試環境:Android Studio & Android 9 API 28

完成功能:MainActivity跳轉至WebViewActivity,顯示目標靜態HTML

具體步驟:

  • 新建一個 模塊/工程

  • 主活動布局 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">
    
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="跳轉webView"/>
    
    </LinearLayout>
    
  • 修改 MainActivity

    package com.example.webviewtest;  //包名自行更改
    
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.os.Build;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.webkit.WebResourceRequest;
    import android.webkit.WebResourceResponse;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Button;
    import android.widget.Toast;
    
    import java.io.IOException;
    
    import static android.view.View.SCROLLBARS_OUTSIDE_OVERLAY;
    
    public class MainActivity extends AppCompatActivity {
    
        private Button btn;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);//加載activity_main布局
    
            btn=(Button)findViewById(R.id.btn); //獲取button
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {  //設置button觸發事件
                    Intent intent=new Intent(MainActivity.this,WebViewActivity.class);
                    String url="http://www.baidu.com";  //設置目標網頁地址
                    intent.putExtra("url",url);
                    startActivity(intent); //intent跳轉WebViewActivity
                    finish();  //跳轉后退出原活動
                }
            });
        }
    }
    
  • 添加WebView布局 webview_layout.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">
    
        <WebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </WebView>
    
    </LinearLayout>
    
  • 添加 WebViewActivity

    package com.example.webviewtest;
    
    import android.graphics.Bitmap;
    import android.os.Build;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.webkit.WebResourceRequest;
    import android.webkit.WebResourceResponse;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Toast;
    
    import java.io.IOException;
    
    import static android.view.View.SCROLLBARS_OUTSIDE_OVERLAY;
    
    public class WebViewActivity extends AppCompatActivity {
    
        private WebView webView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.webview);
            webView = findViewById(R.id.webView);
            webView.loadUrl(getIntent().getStringExtra("url"));//提取目標url
            
            webView.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    view.loadUrl(url);//使用當前WebView處理跳轉
                    return true;//true表示此事件在此處被處理,不需要再廣播
                }
        }
    }
    
  • 修改 AndroidManifest.xml :

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.webviewtest"><uses-permission android:name="android.permission.INTERNET" />  //打開網絡權限,若不設置則斷網    <application
            android:usesCleartextTraffic="true"  //使用明文傳輸,若不設置則無法用http訪問網絡
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.AppCompat.NoActionBar">  //刪除標題欄
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".WebViewActivity"></activity>  //注冊WebViewActivity活動
        </application>
    
    </manifest>
    
  • 運行結果:


    如果訪問百度之類的網站,上面已經夠了,但如果是訪問你自己的服務器,比如tomcat,還要繼續下面的操作,否則會出現網絡中斷、樣式加載失敗、圖片無法加載等問題。

  • 添加xml文件夾

  • 在xml文件夾新建 network_security_config.xml

    想了解原因的可以移步 https://blog.csdn.net/lz8362/article/details/78289930

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <base-config cleartextTrafficPermitted="true">
            <trust-anchors>
                <certificates src="system" />
            </trust-anchors>
        </base-config>
    </network-security-config>
    
  • 修改 AndroidManifest.xml

     android:usesCleartextTraffic="true"
    

    替換

    android:networkSecurityConfig="@xml/network_security_config"
    
  • 修改 WebViewActivity ,在 Oncreate() 里添加

            WebSettings webSettings = webView.getSettings();
            webSettings.setBlockNetworkImage(false); // 解決圖片不顯示
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);  //允許混合內容模式
            }
    

這樣應該就能顯示了,但是加載的速度不盡人意,下面進行一些優化

1. 添加緩存,修改WebViewActivity,Oncreate()里繼續添加

webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//加載緩存

想詳細了解的可以參考 https://www.jianshu.com/p/6575304281a1 添加緩存后能很明顯提高第一次之后啟動的加載速度

2. 將 js、css 放到 app 本地加載

按照原來的寫法,引入的css和js要么是個http外鏈,要么是很長很長的樣式表,可能一個30k的網頁有20k的樣式代碼。

不管是哪種,在訪問或解析數據都消耗了大量時間,如果把固定的樣式放在本地加載,速度會有質的飛躍

如果你的html文件恰好都是同一種樣式,比如說bootstrap等等,那就更適合用這種方法了 _

  • 首先,在工程里添加assets文件夾,用於存放樣式文件img

  • 把你的樣式文件放入assets文件夾里,比如說 passage.css,修改你的html樣式為外鏈,比如:

<link rel="stylesheet" href="passage.css" type="text/css" />
  • 修改WebViewActivity,重寫Oncreate()里setWebViewClient()的shouldInterceptRequest()方法,你可以在setWebViewClient方法體內按 Ctrl+o 找到它
webView.setWebViewClient(new WebViewClient() { //在app內部打開網頁
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                WebResourceResponse response = null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    response = super.shouldInterceptRequest(view, request);
                    if (request.getUrl().toString().contains("passage.css")) {  //監聽請求地址,如果請求的是 樣式文件passage.css
                        try {  //重寫response,修改請求頭,按utf-8編碼,加載本地樣式
                            response = new WebResourceResponse("text/css", "UTF-8", getAssets().open("passage.css"));
                        } catch (IOException e) {                                 //getAssets().open(String file):按字符串在assets資源文件夾里查找文件
                            e.printStackTrace();
                        }
                    }
                }
                return response;
            }
}
  • 如果是 js 文件,還要在Oncreate()里添加:
webSettings.setJavaScriptEnabled(true);

默認WebView還有一個滾動條,可以進行隱藏,更有原生體驗效果

  • Oncreate()里添加
webView.setHorizontalScrollBarEnabled(false);
webView.setVerticalScrollBarEnabled(false);

看看效果,很不錯吧 _

轉載請注明博文來源,有什么問題歡迎在評論欄留言。 ——Kevin_Lu 2020-03-02


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM