今天的文章我要來寫寫關於WebView
WebView顧名思義就是一個在手機上顯示指定網頁的元件,而這個元件我記得很早很早就有了
記得當時我剛學Android的時候好像還是Android2還是3左右,那時候的WebView我只記得就是一個字
鳥
沒錯,就是鳥,超鳥的那種XD
我記得最早就只能純顯示網頁,然後頂多拿到載入回調,就沒了( ͡ಠ ʖ̯ ͡ಠ)
而後來遇到的專案其實也鮮少使用到WebView,有需要用到網頁端的話直接Intent跳轉過去就好,完全沒有這個View發揮的餘地
直到後來我在接到跟某個跟支付有關的案子之後,我發現這個WebView在對於那種跟金融有關的設定上特別好用Σ(°ロ°)
也因此,敝人我思前想後一番後,決定來寫寫一篇關於WebView的文章
那這篇文章呢~除了最簡單的WebView設置之外,我還會寫關於WebView如何透過JavaScript來跟網頁內容進行互動(交互)
總之,先來看功能吧!
然後Github
->點我
1. 設置介面
看了動圖也大概知道今天的內容了XD
總之大致就是兩個部分,其一為將WebView設置為外部網頁
其二的部分雖然有點難從動圖分辨出,但其實是讓程式顯示我寫在本地檔案中的網頁
那首先呢,要先能讓Android手機能夠「上網」,就得加入權限
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.WebViewExample" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.app.lib_name" android:value="" /> </activity> </application> </manifest>
然後是介面
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" android:id="@+id/edittext_Input" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <WebView android:id="@+id/webView" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@+id/guideline" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.7" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.35" /> <TextView android:id="@+id/textView_Status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:textStyle="bold" android:textSize="18dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/guideline2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline" /> <Button android:id="@+id/button_MyPage" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="載入本地網頁" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@+id/guideline2" /> <Button android:id="@+id/button_Google" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginEnd="8dp" android:text="載入Google" app:layout_constraintBottom_toTopOf="@+id/button_MyPage" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@+id/guideline2" /> <EditText android:id="@+id/editText_Input" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" android:text="這人沒救了" android:hint="輸入內容" app:layout_constraintBottom_toTopOf="@+id/button_Google" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@+id/guideline2" app:layout_constraintTop_toTopOf="@+id/guideline" /> </androidx.constraintlayout.widget.ConstraintLayout>
OK,基本設定就到這邊,接下來就是稍微有點複雜的部分了
2. 撰寫本地網頁
在實裝WebView之前,我們必須寫一個本地的網頁
檔案位置的話,一般我們都會放在「assets」這隻資料夾內
而assets這個資料夾在預設裡面是沒有的,因此我們要自己創
以前要創assets的話,必須要自己手動新增檔案,後來Android studio有提供在他的列表中了,因此新增起來也是挺方便的
新增的方式如下
在app點右鍵->New->Folder->Assets Folder
點下去之後,這一頁直接點選Finish即可
接下來就會看到assets資料夾囉!
再來,我要在這下面建立Web.html檔案
建立方法為
assets->右鍵->New->Flie
然後輸入「Web.html」即可
最後在裡面輸入以下程式碼
恩...從VSCode貼過來的雖然有彩色,不過沒有凸行...加減看吧XD
至於內容麻...我很懶所以是請AI幫我寫的哈哈,大家就自己加減看吧~
3. 撰寫內容
好,來到重點了。接下來就是關於View的控制方式
照慣例,先貼程式碼
public class MainActivity extends AppCompatActivity { private TextView tvStatus; private boolean isGoogle = true; @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvStatus = findViewById(R.id.textView_Status); EditText edInput = findViewById(R.id.editText_Input); WebView webView = findViewById(R.id.webView); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("https://www.google.com/"); webView.setWebViewClient(new WebViewClient(){ @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); //取得Cookies String cook = CookieManager.getInstance().getCookie(url); if (cook!= null){ String[] cookies = cook.split(";"); for (String cookie:cookies) { Log.d("TAG", "onPageFinished: "+cookie); } } String javascript; if (isGoogle){ javascript = "document.getElementsByName('q')[0].value = '如何脫單';"; }else{ javascript = "document.getElementById('says').innerHTML = '" +edInput.getText()+"';"; } view.evaluateJavascript(javascript, null); } }); webView.setWebChromeClient(new WebChromeClient() { @SuppressLint("SetTextI18n") @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); tvStatus.setText("進度:\n"+newProgress); } }); (findViewById(R.id.button_Google)).setOnClickListener(view -> { isGoogle = true; webView.loadUrl("loadUrl('about:blank')"); webView.clearCache(true); webView.loadUrl("https://www.google.com/"); }); (findViewById(R.id.button_MyPage)).setOnClickListener(view -> { isGoogle = false; webView.loadUrl("loadUrl('about:blank')"); webView.clearCache(true); webView.loadUrl("file:///android_asset/Web.html"); }); } }
WebView的設置大概就是如此,其實說難也不會很複雜
但有幾個重點我想抓出來講,首先是關於setWebViewClient跟setWebChromeClient
這兩個真的是長得有夠像XD,我第一次接觸的時候老是看到眼花
不過基本上是這樣的,setWebViewClient他這邊的回調大概都跟在跑網頁時的過程相關,而setWebChromeClient多跟網頁JS內容有關
因此,像是偵測網頁開跑以及跑完的回調都是在setWebViewClient裡面,而跑進度條就是在setWebChromeClient的onProgressChanged方法內
再來是關於向網頁丟資料的部分。很多時候我們使用WebView時都會希望自動幫使用者填入一些內容,小則像是帳號密碼之類的,比較大的例如token直接在網頁做登入等等
而這部分的資料我找了好一陣子,大部分人提供的方法都是直接把網頁原始碼嵌入到程式碼之中...
也不是不行啦,但是小網頁還可以,大網頁可是一點都不實用啊「(°ヘ°)
後來我發現WebView可以直接對網頁輸入JavaScript內容,因此這部分的內容就是綠色匡起來的部分了
String javascript; if (isGoogle){ javascript = "document.getElementsByName('q')[0].value = '如何脫單';"; }else{ javascript = "document.getElementById('says').innerHTML = '" +edInput.getText()+"';"; } view.evaluateJavascript(javascript, null);
也因此我們如果打開Google瀏覽器後,網頁會自動填入「如何脫單」的理由
P.s...找出這個標籤(Name)比研究如何填入還久囧
再來,網頁麻,經常會需要操作Cookie
因此我這邊也特別補上了取得Cookie的方法,如下
//取得Cookies String cook = CookieManager.getInstance().getCookie(url); if (cook!= null){ String[] cookies = cook.split(";"); for (String cookie:cookies) { Log.d("TAG", "onPageFinished: "+cookie); } }
最後,想要清掉WebView的內容的話,在4.4以前有個clearView的方法
不過在現在的版本中,直接呼叫webView.loadUrl("loadUrl('about:blank')");就可以消除掉WebView的內容囉!
webView.loadUrl("loadUrl('about:blank')");
關於WebView的介紹大概就是到這邊,其他WebView還有非常非常多方法可以使用
可能也是因為是老牌元件吧,這部分的資料還是蠻多的,大家可以花點時間去看看這部分的文章哦!
像是這篇我覺得不錯
->https://blog.csdn.net/fengyuzhengfan/article/details/38326861
這篇雖然一看就知道大概只是翻譯Android文檔而已,不過我覺得還蠻多範例的
不妨也參考一下吧!
最後..
留言列表