編輯:關於Android編程
Android開發過程中,我們或多或少都會用到webview,使用webview來展示一些經常變動的界面更加方便簡單,也更易於維護。在使用webview來展示網頁的時候,有些時候我們需要通過JS和Android原生控件進行交互,以實現自己需要的效果或功能,本文通過一個demo簡單實現了JS和Android原生控件的交互。
界面上方是EditView和Button,下方是一個webview控件,通過輸入url,然後點擊跳轉按鈕,webview控件會加載該url,本次為了方便學習,我已經寫好了一個html文件放置在了Asset文件中,通過file:///android_asset/test.html來進行加載。然後出現四個新的按鈕,點擊不同的按鈕,會產生不同的效果。
asset文件夾下面的test.html文件<meta charset="UTF-8" /> <meta content="EditPlus?" name="Generator" /> <meta content="" name="Author" /> <meta content="" name="Keywords" /> <meta content="" name="Description" /> <title></title> <script> function jsAlert(){ var r = alert("I am alert"); alert(r); } function jsConFirm(){ var r = confirm("I am conFirm"); alert(r); } function jsPrompt(){ //第一個參數是提示 //第二個參數是默認值 var r = prompt("請輸入姓名:","小明同學"); alert(r); } function jsJava(){ //調用java的方法,頂級對象,java方法 //可以直接訪問JSTest,這是因為JSTest掛載到js的window對象下了 JSTest.showToast("我是被JS執行的Android代碼"); } </script>
代碼很簡單,整個界面只有四個按鈕,以及四個JS寫的方法jsAlert(),jsConFirm(),jsPrompt(),jsJava(),當點擊按鈕觸發這些方法的時候,會進一步觸發我們寫好的java代碼,具體實現請參見java代碼。
具體的java代碼import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; import android.webkit.JavascriptInterface; import android.webkit.JsPromptResult; import android.webkit.JsResult; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.EditText; import android.widget.Toast; public class JSActivity extends AppCompatActivity { //assets下的文件的test.html所在的絕對路徑 private static final String DEFAULT_URL = "file:///android_asset/test.html"; private EditText et_url; private WebView webView; private ProgressDialog progressDialog;//加載界面的菊花 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_js); initView(); initWebView(); } /** * 初始化控件 */ private void initView() { webView = (WebView) findViewById(R.id.webView); et_url = (EditText) findViewById(R.id.et_url); } /** * 初始化webview */ private void initWebView() { //首先設置Webview支持JS代碼 webView.getSettings().setJavaScriptEnabled(true); //Webview自己處理超鏈接(Webview的監聽器非常多,封裝一個特殊的監聽類來處理) webView.setWebViewClient(new WebViewClient() { /** * 當打開超鏈接的時候,回調的方法 * WebView:自己本身webView * url:即將打開的url */ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //自己處理新的url webView.loadUrl(url); //true就是自己處理 return true; } //重寫頁面打開和結束的監聽。添加友好,彈出菊花 /** * 界面打開的回調 */ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } //彈出菊花 progressDialog = new ProgressDialog(JSActivity.this); progressDialog.setTitle("提示"); progressDialog.setMessage("軟軟正在拼命加載……"); progressDialog.show(); } /** * 界面打開完畢的回調 */ @Override public void onPageFinished(WebView view, String url) { //隱藏菊花:不為空,正在顯示。才隱藏 if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } } }); //設置進度條 //WebChromeClient與webViewClient的區別 //webViewClient處理偏界面的操作:打開新界面,界面打開,界面打開結束 //WebChromeClient處理偏js的操作 webView.setWebChromeClient(new WebChromeClient() { /** * 進度改變的回調 * WebView:就是本身 * newProgress:即將要顯示的進度 */ @Override public void onProgressChanged(WebView view, int newProgress) { if (progressDialog != null && progressDialog.isShowing()) progressDialog.setMessage("軟軟正在拼命加載……" + newProgress + "%"); } /** * 重寫alert、confirm和prompt的回調 */ /** * Webview加載html中有alert()執行的時候,回調 * url:當前Webview顯示的url * message:alert的參數值 * JsResult:java將結果回傳到js中 */ @Override public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this); builder.setTitle("提示"); builder.setMessage(message);//這個message就是alert傳遞過來的值 builder.setPositiveButton("確定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //處理確定按鈕了,且通過jsresult傳遞,告訴js點擊的是確定按鈕 result.confirm(); } }); builder.show(); //自己處理 return true; } @Override public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this); builder.setTitle("提示"); builder.setMessage(message);//這個message就是alert傳遞過來的值 builder.setPositiveButton("確定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //處理確定按鈕了,且通過jsresult傳遞,告訴js點擊的是確定按鈕 result.confirm(); } }); builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //處理取消按鈕,且通過jsresult傳遞,告訴js點擊的是取消按鈕 result.cancel(); } }); builder.show(); //自己處理 return true; } /** * defaultValue就是prompt的第二個參數值,輸入框的默認值 * JsPromptResult:向js回傳數據 */ @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) { AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this); builder.setTitle("提示"); builder.setMessage(message);//這個message就是alert傳遞過來的值 //添加一個EditText final EditText editText = new EditText(JSActivity.this); editText.setText(defaultValue);//這個就是prompt 輸入框的默認值 //添加到對話框 builder.setView(editText); builder.setPositiveButton("確定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //獲取edittext的新輸入的值 String newValue = editText.getText().toString().trim(); //處理確定按鈕了,且過jsresult傳遞,告訴js點擊的是確定按鈕(參數就是輸入框新輸入的值,我們需要回傳到js中) result.confirm(newValue); } }); builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //處理取消按鈕,且過jsresult傳遞,告訴js點擊的是取消按鈕 result.cancel(); } }); builder.show(); //自己處理 return true; } }); //java與js回調,自定義方法 //1.java調用js //2.js調用java //首先java暴露接口,供js調用 /** * obj:暴露的要調用的對象 * interfaceName:對象的映射名稱 ,object的對象名,在js中可以直接調用 * 在html的js中:JSTest.showToast(msg) * 可以直接訪問JSTest,這是因為JSTest掛載到js的window對象下了 */ webView.addJavascriptInterface(new Object() { //定義要調用的方法,注意4.2及以後的則多了注釋語句@JavascriptInterface //msg由js調用的時候傳遞 @JavascriptInterface public void showToast(String msg) { Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); } }, "JSTest"); } public void onClick(View view){ String url = et_url.getText().toString().trim(); if(TextUtils.isEmpty(url)){ url = DEFAULT_URL; } webView.loadUrl(url); } @Override public void onBackPressed() { if (webView.canGoBack()) { //返回上一個頁 webView.goBack(); return ; } super.onBackPressed(); } }布局文件activity_js.xml
代碼過程描述的廢話我就不多說了,注釋寫的算是比較仔細了,另外再強調兩點需要注意的地方:
一、不要忘記通過setJavaScriptEnabled(true)設置webview支持JS代碼
二、在使用addJavascriptInterface方法添加掛載對象時,要注意在Android4.2之後需要給對象方法加上@JavascriptInterface注解。
Android UI工具包提供了一些布局管理器,它們使用起來相當容易,而且,大多數的時候,你只需要使用它們最基本的特征來實現UI。執著於基本特征的使用對於創建UI來說,往
線程的運行機制 1. 開啟線程過多,會消耗cpu2. 單核cpu,同一時刻只能處理一個線程,多核cpu同一時刻可以處理多個線程3. 操作系統為每個運行線程安排一
看下效果圖主要看下自定義view 代碼public class ProcessImageView extends ImageView{ private Context
前言:對於ListView,大家絕對都不會陌生,只要是做過Android開發的人,哪有不用ListView的呢?只要是用過ListView的人,哪有不關心對它性能優化的呢