Banyak APP sekarang memiliki halaman HTML5 yang tertanam di dalamnya, seperti halaman yang sering berubah. Beberapa halaman memerlukan Java asli untuk berinteraksi dengan js di HTML5.
1. Tentang cookie HTML5Banyak parameter seperti informasi pengguna dapat digunakan di halaman web. Anda dapat memasukkan informasi ini ke dalam cookie terlebih dahulu. Anda dapat menggunakan metode berikut:
public static void addCookies(Konteks konteks, WebView webView, String url) { String url=https://www.xxxx.com/xx/xx/ String protokol = ; String otoritas = ; ; protokol = urlObj.getProtocol(); otoritas = urlObj.getAuthority(); } catch (Pengecualian e) { e.printStackTrace(); webView.getSettings().getUserAgentString(); webView.getSettings().setUserAgentString(Constant.PROJECT_NAME + / + ParamHandler.getVersion(konteks) + ( + ua + ; HFWSH)); !TextUtils.isEmpty(protokol) && !TextUtils.isEmpty(authority)) { if (protocol.equals(https) && authority.indexOf(liepin.com) > -1) { CookieSyncManager.createInstance(context); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie (benar); coba { Daftar<String> data = getCookiesString(); (!ListUtils.isEmpty(data)) { untuk (Nilai string : data) { cookieManager.setCookie(url, value); } cookieManager.setCookie(url, client_id= + Constant.CLIENT_ID + ;path=/;domain=. XXXX.com); cookieManager.setCookie(url, appVersion= + Konstan .VERSION + ;path=/;domain=.XXXX.com); CookieSyncManager.getInstance().sync(); } catch (Pengecualian e) { LogUtils.e(Pengecualian: + e.getMessage()); Daftar publik<String> getCookiesString() { Data ArrayList = new ArrayList(); this.clearExpired(); Nilai koleksi = this.mCookies.values(); () ) { SwiftCookie c = (SwiftCookie)var3.next(); data.add(c.toCookieString() } mengembalikan data; }Tambahkan cookie sebelum mWebView.loadUrl(Url), dan halaman web bisa mendapatkan nilai parameter yang sesuai melalui cookie.
2. Mengenai masalah keamanan jsjs memiliki kerentanan sebelum versi 4.2
Melalui JavaScript, Anda dapat mengakses apa pun di kartu SD perangkat saat ini, bahkan informasi kontak, pesan teks, dll. Oke, mari kita lihat bagaimana kesalahan ini terjadi.
1. WebView menambahkan objek JavaScript, dan aplikasi saat ini memiliki izin untuk membaca dan menulis SDCard, yaitu: android.permission.WRITE_EXTERNAL_STORAGE
2. Di JS, Anda dapat melintasi objek jendela untuk menemukan objek dengan metode getClass, lalu mendapatkan objek Runtime melalui mekanisme refleksi, lalu memanggil metode statis untuk menjalankan beberapa perintah, seperti perintah untuk mengakses file.
3. Kemudian dapatkan string dari aliran input yang dikembalikan setelah menjalankan perintah, dan Anda bisa mendapatkan informasi nama file. Kemudian Anda dapat melakukan apapun yang Anda inginkan, itu sangat berbahaya. Kode inti JS adalah sebagai berikut:
fungsi mengeksekusi(cmdArgs) { for (var obj di jendela) { if (getClass di jendela[obj]) { alert(obj); return window[obj].getClass().forName(java.lang.Runtime) .getMethod( getRuntime,null).invoke(null,null).exec(cmdArgs); Larutan: 1. Sistem Android 4.2 atau lebih tinggiDi Android 4.2 dan yang lebih baru, Google telah melakukan koreksi dengan mendeklarasikan @JavascriptInterface pada metode jarak jauh Java, seperti yang ditunjukkan pada kode berikut:
kelas JsObject { @JavascriptInterface public String toString() { kembalikan objek yang disuntikkan; } } webView.addJavascriptInterface(JsObject baru(), objek yang disuntikkan webView.loadData(, teks/html, null); toString())); 2. Sistem di bawah Android 4.2Masalah ini memang lebih sulit untuk diselesaikan, namun bukan berarti tidak mungkin.
Pertama-tama, kita pasti tidak bisa lagi memanggil metode addJavascriptInterface. Mengenai masalah ini, yang paling penting adalah mengetahui aksi event JS. Kita tahu bahwa ada jenis interaksi berikut antara JS dan Java, seperti prompt, alert, dll.
Tindakan tersebut akan sesuai dengan metode yang sesuai di kelas WebChromeClient. Untuk prompt, metode yang sesuai adalah metode onJsPrompt. Deklarasi metode ini adalah sebagai berikut:
boolean publik onJsPrompt (tampilan WebView, URL string, pesan string, String defaultValue, hasil JsPromptResult)
Melalui metode ini, JS dapat meneruskan informasi (teks) ke Java, dan Java juga dapat meneruskan informasi (teks) ke JS. Bisakah kita menemukan solusi untuk ide ini?
Setelah beberapa percobaan dan analisis, kami menemukan solusi yang lebih layak. Silakan lihat poin-poin berikut:
[1] Biarkan JS memanggil metode Javascript. Dalam metode ini, metode prompt dipanggil, dan informasi di JS diteruskan melalui prompt. Informasi ini harus berupa teks bermakna yang kami gabungkan, yang dapat mencakup: pengidentifikasi spesifik, nama metode , parameter, dll.
Dalam metode onJsPrompt, kami mengurai teks yang diteruskan untuk mendapatkan nama metode, parameter, dll., lalu memanggil metode yang ditentukan melalui mekanisme refleksi untuk memanggil metode objek Java.
[2] Mengenai nilai kembalian, Anda dapat mengembalikannya melalui prompt, sehingga hasil pemrosesan metode di Java dapat dikembalikan ke Js.
[3] Kita perlu membuat skrip JS secara dinamis yang mendeklarasikan metode Javascript, memuatnya melalui loadUrl, dan mendaftarkannya di halaman html. Kode spesifiknya adalah sebagai berikut:
javascript:(function JsAddJavascriptInterface_(){ if (typeof(window.jsInterface)!='undefinisi') { console.log('window.jsInterface_js_interface_name ada!!');} else { window.jsInterface = { onButtonClick:function( arg0) { kembali prompt('Aplikasi Saya:'+JSON.stringify({obj:'jsInterface',func:'onButtonClick',args:[arg0]}) }, onImageClick:function(arg0,arg1,arg2) { prompt('Aplikasi Saya:'+JSON.stringify({obj:'jsInterface',func:'onImageClick',args:[arg0,arg1,arg2]}));menjelaskan:
1. jsInterface pada kode di atas adalah nama objek yang akan didaftarkan. Ini mendaftarkan dua metode, onButtonClick(arg0) dan onImageClick(arg0, arg1, arg2).
2. Prompt adalah string yang kita sepakati, yang berisi pengidentifikasi spesifik MyApp:, diikuti oleh string string JSON, yang mencakup nama metode, parameter, nama objek, dll.
3. Saat JS memanggil onButtonClick atau onImageClick, JS akan memanggil kembali metode onJsPrompt di lapisan Java. Kami kemudian menguraikan nama metode, parameter, nama objek, dan kemudian memanggil metode tersebut secara reflektif.
4. window.jsInterface artinya objek Js dideklarasikan pada window. Bentuk metode yang dideklarasikan adalah: nama metode: fungsi (parameter 1, parameter 2)
3. Interaksi antara java dan js di html51), Metode 1:
mWebView.getSettings().setJavaScriptEnabled(true);mWebView.addJavascriptInterface(ini, xxx);
Kemudian implementasikan metode berikut di kelas saat ini:
@JavascriptInterface public void callbackFromH5(String terakhir j) { //TODO }Nama callbackFromH5 harus sama dengan nama metode js di halaman web
Java memanggil metode js:
mWebView.loadUrl(String.format(javascript:java2js(0)));//Ini adalah JS untuk memanggil webview di sisi Java
Nama metode js harus konsisten dengan halaman web
2) Metode kedua:
metode jsbridge (https://github.com/lzyzsd/JsBridge)
Android JsBridge adalah alat bantu yang digunakan untuk membangun jembatan komunikasi (panggilan) antara kode java asli dan kode javascript aplikasi Android.
1 Perkenalkan jsBridge.jar ke dalam proyek kita
Studio Android:
repositori { // ... maven { url https://jitpack.io } } dependensi { kompilasi 'com.github.lzyzsd:jsbridge:1.0.4' }2. Berkas tata letak
<?xml versi=1.0 pengkodean=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 mendemonstrasikan web panggilan Java --> <Button android:id=@+id/button android:layout_width=match_parent android:text=@string/button_name android:layout_height=dp /> <!-- tampilan web mendemonstrasikan panggilan web Java --> <com.github.lzyzsd.jsbridge.BridgeWebView android:id=@+id/ tampilan web android:layout_width=match_parent android:layout_height=match_parent > </com.github.lzyzsd.jsbridge.BridgeWebView> </LinearLayout>
3. kode java
//Muat halaman web server webView.loadUrl(https://www.baidu.com); //Harus memiliki nama yang sama dengan fungsi js. webView.registerHandler(submitFromWeb, new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { String str =html data dikembalikan ke java: + data; makeText(MainActivity.this, str, LENGTH_SHORT).show() ; Log.i(TAG, handler = submitFromWeb, data dari web = + data); , setelah pemrosesan Java: + str.substring(,)); //Simulasikan pengguna untuk mendapatkan lokasi lokal Pengguna pengguna = Pengguna baru(); pengguna.lokasi = lokasi; nama pengguna = Bruce webView.callHandler(functionInJs, new Gson().toJson(user), new CallBackFunction() { @Override public void onCallBack(String data) { makeText(MainActivity.this, halaman web mendapatkan informasi Anda, LENGTH_SHORT).show(); webView.callHandler(functionInJs, data dari Java, new CallBackFunction() { @Override public void onCallBack(String data) { // TODO Metode yang dibuat secara otomatis stub Log.i(TAG, data respons dari js + data); } }) ;js panggilan
var str1 = document.getElementById(text1).value; var str2 = document.getElementById(text2).value; //Panggil metode java lokal window.WebViewJavascriptBridge.callHandler( 'submitFromWeb' , {'param': str} , function ( responData) { document.getElementById(show).innerHTML = kirim dapatkan responData dari java, data = + responData } ); //Daftarkan acara mendengarkan document.addEventListener( 'WebViewJavascriptBridgeReady' , function() { callback(WebViewJavascriptBridge) }, false } //Daftarkan fungsi panggilan balik dan panggil fungsi inisialisasi connectWebViewJavascriptBridge(function(bridge) { saat menghubungkan untuk pertama kali bridge.init(function(message, respondCallback) { console.log('JS mendapat pesan', message); var data = { 'Javascript Menanggapi': 'Wee!' }; console.log('JS merespons dengan', data); responCallback(data }); innerHTML = (data dari Java: = + data); var respondData = Javascript Says Right back alias!; })4. Tentang optimasi webView
1. Atur mode cache WebView
private void initWebView() { mWebView.getSettings().setJavaScriptEnabled(true); mWebView.getSettings().setRenderPriority(RenderPriority.HIGH); mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); //Setel mode cache// Aktifkan API penyimpanan DOM Fungsi mWebView.getSettings().setDomStorageEnabled(true); //Aktifkan fungsi API penyimpanan database mWebView.getSettings().setDatabaseEnabled(true); // String cacheDirPath = getCacheDir().getAbsolutePath()+Constant.APP_DB_DIRNAME; Log.i(TAG, cacheDirPath=+cacheDirPath); //Setel jalur cache database mWebView.getSettings().setDatabasePath(cacheDirPath); mWebView.getSettings().setAppCachePath(cacheDirPath); //Aktifkan fungsi Cache Aplikasi mWebView.getSettings().setAppCacheEnabled(true);2. Hapus cache
/** * Hapus cache WebView*/ public void clearWebViewCache(){ //Hapus database cache Webview coba { deleteDatabase(webview.db); } //File cache WebView File appCacheDir = File baru(getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME); Log.e(TAG, jalur appCacheDir=+appCacheDir.getAbsolutePath()); File webviewCacheDir = File baru(getCacheDir().getAbsolutePath()+/webviewCache()); ); //Hapus tampilan web Direktori cache if(webviewCacheDir.exists()){ deleteFile(webviewCacheDir); //Hapus direktori cache cache tampilan web if(appCacheDir.exists()){ deleteFile(appCacheDir);3. Saat menggunakan WebView untuk memuat halaman web, beberapa file sumber daya tetap seperti js/css/images dan sumber daya lainnya akan berukuran relatif besar. Jika dimuat langsung dari jaringan, halaman akan dimuat lebih lambat dan mengonsumsi lebih banyak lalu lintas. Jadi file-file ini harus ditempatkan di aset dan dikemas dengan aplikasi.
Untuk mengatasi masalah ini, gunakan fungsi mustInterceptRequest(WebView view, String url) yang disediakan oleh API 11 (HONEYCOMB) untuk memuat sumber daya lokal.
API 21 tidak lagi menggunakan metode ini dan membebani mustInterceptRequest baru secara berlebihan. Parameter yang diperlukan menggantikan url dengan permintaan.
Misalnya, ada gambar xxxxx.png. Gambar ini telah ditempatkan di aset. Sekarang setelah HTML eksternal dimuat, gambar di aset harus langsung dikeluarkan dan dimuat tanpa mendapatkannya kembali dari jaringan. Tentu saja Anda dapat mengubah link gambar dalam html menjadi file:///android_asset/xxxx.png,
Namun html ini tidak bisa dibagikan di Android, ios, dan WAP.
webView.setWebViewClient(WebViewClient baru() { @Override public WebResourceResponse mustInterceptRequest(tampilan WebView, String url) { Respons WebResourceResponse = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){ respon = super.shouldInterceptRequest(lihat ,url); jika (url.berisi(xxxxx.png)){ coba { respon = new WebResourceResponse(image/png,UTF-8,getAssets().open(xxxxx.png)); } catch (IOException e) { e.printStackTrace(); , url); mengembalikan respons; } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override publik WebResourceResponse mustInterceptRequest(tampilan WebView, permintaan WebResourceRequest) { Respons WebResourceResponse = null; respons = super.shouldInterceptRequest(lihat, permintaan jika (url.contains(xxxxx.png)){ coba { respons = new WebResourceResponse(gambar/png,UTF); -,getAssets().open(xxxx.png)); } catch (IOException e) { e.printStackTrace();Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.