編輯:關於Android編程
webView是android中用於展示簡單的網頁或者加載一些html格式的很好的選擇,它提供了很多的操作上的封裝但同時又不失去靈活性,因為他提供了webViewClient和webChromeClient這兩個可自定義的類來進行對頁面動作的不同產生不同的表現的行為。在hybrid app開發模式中,webView可用於和web網頁交互的能力也是一個很突出的亮點,很多時候都會需要用到這樣的技術。所以接下來會通過講解webView,webViewCient,webChromeClient之間互相的關系和作用,然後綜合所講內容來展示一個webView與web的javascript進行交互的場景。首先了解可定義webView頁面表現行為的類。讀者可先看webView的部分在回來看前面的部分,會比較好理解。
此類可以作用與當webView的頁面內容發生改變的時候或者需要提交表單數據的時候又或者發生錯誤的時候,進行對url或者內容的攔截處理,來進一步定義我們的操作內容。在WebViewClient中,有以下幾個要點是比較重要的。
默認情況下,如果webView沒有設置webViewClient的話,有新的請求加載的時候是由當前的activityManager進行處理請求的,但如果我們想在webView加載url的時候先攔截下來,自己處理的話,就需要給webView設置攔截器,即設置一個webViewClient並重寫shouldOveeriedUrlLoading方法。該方法原型如下:
public boolean shouldOverrideUrlLoading(WebView view, String url)
webViewClient可以通過onPageStarted和onPageFinished來判斷當前webView中某個頁面是否開始加載或者是否加載完畢。方法原型如下:
public void onPageStarted(WebView view, String url, Bitmap favicon)
public void onPageFinished(WebView view, String url)啟動view表示調用了此方法的webView,url是當前正在加載的鏈接。favicon是與當前頁面有關的一個標志,用於判斷當前的頁面是否加載過。
webViewCLient允許你攔截資源請求並獲取返回的內容,方法原型如下:
public WebResourceResponse shouldInterceptRequest如果此方法返回的是Null,則webView會像往常一樣去加載url的內容,否則的話就會用獲取的數據來初始化內容。需要注意的是此方法不在主線程運行。
webView中定義了很多常量用於描述url加載失敗的原因,通過重寫onReceiverError方法就可以獲取失敗的代碼和失敗信息。方法原型如下:
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
如果webView的縮放模式發生改變的時候,所請求的資源也需要發送變化,那麼就需要監聽webView的縮放比例了。可以通過webVewClient的onScaleChanged方法來進行攔截。
public void onScaleChanged(WebView view, float oldScale, float newScale)其中oldScale表示原來的縮放比例,newScale表示新的縮放比例。這裡要注意的是,對於高分辨率的手機,縮放比例默認是1.5X,普通的是1x,低分辨率的是0.75x。
這個類可用於設計跟webView的ui相關的操作,比如請求進度的更新,或者js的彈窗或者標題的展現以及圖標.....此類中最近常用的到的方法如下:
webChromeClient可以獲取當前請求的url的進度情況,很經常用於展示在標題欄裡面展示當前的進度信息。方法原型如下:
public void onProgressChanged(WebView view, int newProgress)
webChromeClient提供了兩個方法,可用於獲取當前請求的Url的網站標題和圖標,這樣如果又需要的話,可以自己在標題欄設置相應的標題內容和圖標信息,方法原型如下:
public void onReceivedTitle(WebView view, String title)
public void onReceivedIcon(WebView view, Bitmap icon)
webChromeClient可以在客戶端彈出js對話框的時候進行回調,以確認是由客戶端對對話框進行處理還是交給webView進行處理。方法原型如下:
public boolean onJsAlert(WebView view, String url, String message, JsResult result)
public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result)
當前頁面需要請求客戶端資源的時候,會需要一些權限,因此webChromeClient提供了請求權限的處理方法,方法原型如下:
public void onPermissionRequest(PermissionRequest request)
當webView含有視屏播放的時候,如果還沒顯示視頻,會展示一個圖標的。如果沒有指定,將返回默認的圖標,可以通過以下方法返回指定圖標。
public Bitmap getDefaultVideoPoster()
WebView是Android提供的一個用於展示網頁內容的控件,如果你想實現一個簡單的浏覽器或者展示一些在線內容的話,就需要用到它。在webView中,展現網頁內容用到的是webkit渲染引擎,並且實現了很多基本的功能,比如會記錄你的浏覽歷史,這樣你可以進行回退或者前進查找網頁。還有查找文字、縮放網頁比例等。既然我們用到webView去加載網頁內容,所以就需要網絡權限,記得,要加上網絡權限。
默認情況下,webView是沒有實現任何浏覽器插件功能的,如果你僅僅是展現網頁內容,那麼webView是個很好的選擇,但如果網頁內容需要和用戶交互的話,你必須讓webView響應javaScript的動作。如果你沒有實現webView的這些交互功能,建議使用Uri意圖調用系統的浏覽器處理網頁內容請求比較合適。調用方法如下:
Uri uri=Uri.parse("htttp://baidu.com");
startActivity(new Intent(Intent.ACTION_VIEW,Uri));
要使用webView,可以在XML布局添加WbeView標簽,並在onCreate方法中獲取進行基本的交互設置。也可以自己new一個,然後調用setContentView方法將整個acitivty都被webView覆蓋,如下:
WebView webView=new WebView();
setContentView(webView);
使用webView加載網頁可以使用loadUrl方法,如下:
webView.loadUrl("Http://baidu.com“);
或者你可以加載html格式的資源,可以是靜態資源文件也可以是字符串內容。比如:
String html="
content;webView.loadData(html,"text/html",null);
前面的部分講到了webViewClient和webChromeClient,這兩個方法可以定義很多webView基於不同的事件的不同相應,因此,一般情況下,如果不是僅僅展示html內容的話,都需要重寫這兩個對象來定義相應的實現。通常webChromeClient用於在webView的ui發生變化的時候的被調用,比如根據請求的網頁獲取當前的進度,在標題欄進行展示。webViewClient則用於處理webView中內容發生變化的時候,比如發送了錯誤或者進行了表單提交等。一般來說,如果想要webView進行URL請求處理,都需要重寫shouldOverriedUrlLoading方法,這樣,就可以攔截Url請求讓webView自己處理,否則的話,會讓應用拋出給系統調用,即喚起系統浏覽器進行處理。
如果想要和頁面進行交互,那麼就必須允許webView與javaScript交互,由於webView默認是禁止的,所以需要我們自己設置。一般首先使用過調用webView.getSettings.setJavaScriptEnable方法進行設置。如果你還需要和網頁進行數據交互,還需自行寫一個java對象注入當前的頁面中,這樣javascript可以調用這個注入的對象來和應用交互。
下面給出一個官方的例子:
getWindow().requestFeature(Window.FEATURE_PROGRESS); * * webview.getSettings().setJavaScriptEnabled(true); * * final Activity activity = this; * webview.setWebChromeClient(new WebChromeClient() { * public void onProgressChanged(WebView view, int progress) { * // Activities and WebViews measure progress with different scales. * // The progress meter will automatically disappear when we reach 100% * activity.setProgress(progress * 1000); * } * }); * webview.setWebViewClient(new WebViewClient() { * public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { * Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show(); * } * }); * * webview.loadUrl("http://developer.android.com/")
至於如何和網頁進行交互,是本文的重點,會在後面通過一個例子來講解。
前面講到過webView是可以進行方法縮小的,但是默認是不允許此動作的,所以要進行設置,如下:
webView.getSettings.setBuiltInZoomEnable(true);
這樣設置之後,就會出現方法縮小的按鈕,或者你可以用手勢對頁面進行放大縮小。
因為webView是用來浏覽網頁數據的,因此會涉及很多安全性問題,所以對於網頁的cookie和緩存,每個應用都有自己的緩存文件,並且這些文件是不可以共享的。
由於機器的配置發生改變會導致activit進行重新加載資源,而這些也會導致webView重新加載頁面,所以如果你不想發送,webView重新加載頁面的現象,就需要在AndroidMenifest.xml中配置condigurationChange的相關屬性。
由於android設備的屏幕差別很大,根據不同的分辨率有不同的像素密度,所以進行屏幕適配是必須的。對於webView來說,也是如此。android簡單的把所有的設備分為三個等級,分別為高分辨率,普通分辨率和低分辨率手機,webView默認的展示內容的尺寸是普通分辨率。如果是高分辨率,webView將會放大1.5倍,如果是低分辨率則會縮小到0.75倍。這樣就保證了在不同的手機上可以展示相同的內容。同時,根據分辨率的不同還可以設置目標css樣式來達到不同的效果。
如何判斷當前設備的分辨率呢,可以通過在js中調用window.devicePixelRatio這個屬性來判斷,如果返回的是1.5表示是高分辨率,1表示是普通的,0.75表示是低分辨率。
如果要支持html5播放視頻,請記得打開硬件加速器,打開方法是在AndroidMenifest.xml標簽中設置。當加載視屏或者網頁的時候希望全屏現實的話,則需要重寫webChromeClient中的onShowCustomView和onHideCustomView方法,記住這兩個方法缺一不可,否則無法實現全屏。如果在適配加載過程中,需要顯示自定義視圖,可以重寫getVideoLoadingProgressView方法。
最後請記住,使用webView的時候不要用wrap_content屬性,必須使用確切的數值或者match_[arent來指定寬高,否則的話會到值wbView發生奇奇怪怪的顯示現象。在webView中提供的很多方法都是委托webViewProvider實現的,在這裡不講webViewProvider是因為,它的方法基本和webView中的意思連同名字都是一樣的,所以沒有講的必要,但是我們要知道這一點,即webView本身只是一個展示網頁內容的控件,雖然他可以定制,但是卻需要很多支持。下面將webView中比較重要的方法:
public int getVisibleTitleHeight()
public SslCertificate getCertificate()
public void setHttpAuthUsernamePassword(String host, String realm, String username, String password)
public void loadUrl(String url)
注意如果使用此方法加載了頁面之後,點擊頁面的內容需要跳轉到其他頁面的話,系統默認是調用浏覽器處理,如果你希望webView去加載,就應該重寫webViewClient的shouldOvrriedLoadUrl方法。
public void postUrl(String url, byte[] postData)
此方法會用於進行post方式訪問連接,如果當前的url不是網絡請求的話,就會調用loadUrl去加載數據,否則的話會攜帶postData數據去請求連接。
public void loadData(String data, String mimeType, String encoding)
public void goBack()
如果沒有上一個網頁,則會一直停留在當前頁面。可通過canGoBack方法判斷是否可以返回上一個頁面。
public boolean pageUp(boolean top)
public boolean pageDown(boolean bottom)傳值true,當前webView的內容就會滾動帶頁面頂部或者底部。
public String getOriginalUrl()
public String getUrl()前者用於獲取原始的鏈接地址,後者用於獲取當前頁面的訪問地址。
public void addJavascriptInterface(Object object, String name)
class JsObject { * {@literal @}JavascriptInterface * public String toString() { return "injectedObject"; } * } * webView.addJavascriptInterface(new JsObject(), "injectedObject"); * webView.loadData("
public void removeJavascriptInterface(String name)同時為了可以相應js操作,需要調用:
public WebSettings getSettings()以及:
下面的方法是在WebSetting裡面的
public abstract void setJavaScriptEnabled(boolean flag)下面講解一個通過webView來與網頁的javascript交互的例子綜合使用上述所講內容:
首先需要在APP中定義一個類,此類應該定義一些可被js調用的方法。如下
class JavaScriptInterface { @JavascriptInterface public void setParams(String busType, String entName, String startTimeOne, String startTimeTwo, String taskStatus) { activity.busType = busType; activity.entName = entName; activity.startTimeOne = startTimeOne; activity.startTimeTwo = startTimeTwo; activity.taskStatus = taskStatus; } }類的名字是自己取得,沒有限制,可被調用的方法必須加上@javascriptInterface注解,這樣才能將這個方法注解到webView對象中。此類筆者是作為activity的內部類來使用的,所以setParams並不是什麼強制的方法,這個完全是看你自己定義,我這裡只是提供一個接口給js,這樣js就可以把相應的查詢操作產生的參數設置到APP端 了。
接下來看xml布局文件:
然後看activity代碼:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_PROGRESS); setContentView(R.layout.activity_main); handler = new Handler(); webView = (WebView) findViewById(R.id.webView); webView.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { MainActivity.this.setProgress(newProgress * 1000); } } ); webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setUseWideViewPort(true); //設置自適應 webView.getSettings().setLoadWithOverviewMode(true); webView.getSettings().setBuiltInZoomControls(true);//設置可縮放 webView.getSettings().setPluginState(WebSettings.PluginState.ON);//設置插件狀態從而播放視頻 webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); webView.getSettings().setSavePassword(true); webView.getSettings().setSaveFormData(true); webView.getSettings().setJavaScriptEnabled(true); webView.requestFocus(); webView.addJavascriptInterface(new JavaScriptInterface(), "webViewInterface");//注意這句話,和後面的js代碼關聯 webView.loadUrl("http://192.168.191.1:8080/sdfer/");//這是筆者的調試地址,讀者自行修改 }
<script type="text/javascript"> function putParams() { if(window.webViewInterface!=null) { var busType=$("#bustype").val(); busType=busType==null?"":busType; var entName=$("#entname").val(); entName=entName==null?"":entName; var startTimeOne=$("#startTimeOne").val(); startTimeOne=startTimeOne==null?"":startTimeOne; var startTimeTwo=$("#startTimeTwo").val(); startTimeTwo=startTimeTwo==null?"":startTimeTwo; var taskStatus=$("#taskstatus").val(); taskStatus=taskStatus==null?"":taskStatus; window.webViewInterface.setParams(busType,entName,startTimeOne,startTimeTwo,taskStatus);//重點在這裡 } } </script>
我們看看
window.webViewInterface.setParams(busType,entName,startTimeOne,startTimeTwo,taskStatus);
webViewInterface就是我們調用addJavascriptInterface給的名稱,這個方法是我們自定義的提供給js調用的方法。以上就實現了js端調用客戶端的方法的過程。
那麼如何在客戶端調用js方法呢?
比如,我們在javascript中定義一個方法,如下:
function invokeFromAPP(msg){ alert("來自客戶端的信息:"+msg); }
在客戶端的代碼中,對webView執行操作,如下:
webView.loadUrl("javascript:invokeFromAPP('" + msg + "')");
AlertDialog的簡單使用 AlertDialog的使用是依賴於Activity的。它不同於Toast,Toast是不依賴於Activity的,Toast只起到一
這個對於很多剛轉到Android Studio上的來說,確實是一個問題。可能你在設置裡面找了很久都沒找到這個選項。 直接上圖吧,按下圖就可以找到設置的地兒了,然後直接設置
研究增量更新的熱情被激發了,通過幾天的資料查找和學習,搞懂增量更新之余,也順便練習了下NDK開發。效果圖預覽開發環境Android Studio 2.2.1 For W
JNI靜態(static)加載OpenCV本文地址: http://blog.csdn.net/caroline_wendy步驟:1. 准備OpenCV-Android庫