安卓網絡編程——WebView
隨著H5性能的不斷提升,雖然離原生APP還有一段不小的距離,但是WebAPP的體驗比之當時,無疑是提升了不少。
今天介紹一個組件,可以實現將一個WebAPP->APP(俗稱套殼APP? 大霧)
或者簡單的理解——就是一個在AndroidAPP內瀏覽網頁組件(小型的瀏覽器?)
WebView
概述
WebView組件是Android提供用于顯示網頁信息,它內置了WebKit引擎,所以我們可以把WebView當作一個輕量級的瀏覽器使用。
- Webkit是一個開源的瀏覽器引擎,Chrome瀏覽器也是基于它
使用前也需要添加權限
<uses-permission android:name="android.permission.INTERNET"/>
使用WebView加載網頁
基本使用介紹
- 加載網頁
webView.loadUrl("http://uuw.baidu.com");
效果如,效果將會是跳轉到百度(一般會以瀏覽器打開,如果設置了默認的)
加載本地網頁
webVieuloadUrl(file:///android-asset/XXX.html); //這里的格式是固定的,文件位置assets目錄下
- post方式傳送參數
String postData = "clientID = cid & username = name";
webview.postUrl(url, EncodingUtils.getBytes(postData, "base64"));
webview.postUr(String url, byte[] postData) //加載頁面使用Post方式, postData為參數
- 使用loadData方法來加載html數據
//loadData()需要三個參數: HTML TAG ,MIME類型(text/html),網頁編碼方式(utf-8)
wv.loadData(content, "text/html","UTF-8");
效果如 ,顯示編寫的html數據內容
簡單測試
- 布局文件 添加一個WebView
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/webView">
</WebView>
</android.support.constraint.ConstraintLayout>
- 完整代碼
package com.example.a4_17webview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
//加載網頁
//webView.loadUrl("http://www.baidu.com");
//loadData
webView.loadData("<html><body>LOADDATA</body></html>","text/html","utf-8");
}
}
參數設置
基本設置
WebSettings webSettings = webView.getSettings(); //獲取設置
WebSettings.setSavePassword(false);//保存密碼
webSettings.setSaveFormData(false); //保存表單數據
webSettings.setJavaScriptEnabled(true); //WebView默認是不支持
JavaScriptwebSettings.setSupportZoom(false); //縮放
webview.setScrollBarStyle(View.SCROLLBARS INSIDE OVERLAY); //在內容顯示內部顯webView.goBack(); //返回
webView.goForward(); //前進
webView.stoploadingl(); //停止加載
webView.requestFocusl();//如果不設置的話,會出現不能彈出軟鍵盤等問題
//希望點擊鏈接繼續在當前browser中響應,必須覆蓋WebViewClient對象
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
//處理標題,圖標
webView.setWebChromeClient(new WebChromeClient(){
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
}
});
簡單測試
- 完整代碼:
package com.example.a4_17webview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
//loadData
//webView.loadData("<html><body>LOADDATA</body></html>","text/html","utf-8");
/**參數設置**/
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
webView.requestFocus();
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
//希望點擊鏈接繼續在當前browser中響應,必須覆蓋WebViewClient對象
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
//處理標題,圖標
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
}
});
//加載網頁
webView.loadUrl("http://www.baidu.com");
}
}
效果如
點擊任意內容
仍在當前WebView
但是上面的案例有個小問題,點擊返回會直接退出程序,而不是預期的返回上一個頁面。
比如上面演示的,訪問百度后點擊百度的任意內容,進入下一個內容,點返回不會返回百度,而是直接退出程序。
為了解決這個問題,我們進行
回退鍵設置
重寫onKeyDown方法
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
與JS的交互
WebView提供了addJavascriptInterface(Object obj,String interfaceName)這個方法。
但是在API17后Android官方限制javascript代碼只能調用聲明了@JavascriptInterface 注解的Java方法。
該方法將一個Java對象綁定到一個Javascript對象中,這樣初始化webView后,在webView加載的頁面就可以直接通過Javascript:window.demo訪問到綁定的java對象。
- Javascript對象名即interfaceName(demo)
- Javascript作用域為Global
案例
建一個assets包 下面創建一個index.html文件 并書寫html代碼
- index.html
<html>
<head>
<title>hello webview</title>
<script language="JavaScript">
function myfun(){
document.getElementById("imgid").src="https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/image/w%3D500/sign=c290a0a3d9ca7bcb7d7bc72f8e086b3f/cb8065380cd7912327430d14a3345982b2b7802b.jpg";
}
</script>
<body>
<a οnclick="window.demo.clickOnAndroid()">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555663226281&di=ddc3da2be5311ade569ca4bc2c9b5f98&imgtype=0&src=http%3A%2F%2Fimg.evolife.cn%2F2014-12%2F89a506ac5543ca53.jpg" id="imgid" width="300" height="400">
</a>
</body>
</head>
</html>
- 完整代碼
package com.example.a4_17webview;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private WebView webView;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
handler = new Handler();
//loadData
//webView.loadData("<html><body>LOADDATA</body></html>","text/html","utf-8");
/**參數設置**/
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
webView.requestFocus();
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
//希望點擊鏈接繼續在當前browser中響應,必須覆蓋WebViewClient對象
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
//處理標題,圖標
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
}
});
webView.addJavascriptInterface(new MyObject(),"demo");
//加載網頁
//webView.loadUrl("http://www.baidu.com");
//加載寫的index.html
webView.loadUrl("file:///android_asset/index.html");
}
//內部類
public class MyObject{
@JavascriptInterface
public void clickOnAndroid(){
handler.post(new Runnable() {
@Override
public void run() {
webView.loadUrl("javascript:myfun()");
}
});
}
}
//回退鍵
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
- 測試效果
點擊后
智能推薦
安卓網絡請求
遇到的幾個坑 1 需要申請權限: 2 不能在主線程發請求 解決:創建子線程或者設置代碼 code: 或者創建子線程: 參考: https://blog.csdn.net/qq_29477223/article/details/81027716...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
猜你喜歡
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...