关于Hybrid App 配置

内置浏览器

网页视图WebView

如果一个网站已经有现成的网页及业务逻辑,那么使用WebView将其内嵌到app中,省去了app重画页面与http通信的事情,无疑是更经济的做法。WebView就是Android上的一个浏览器内核,可自动展示web页面,并且实现js代码的相互调用。
下面是WebView的常用方法:
getSettings : 获取浏览器的web设置信息。
addJavascriptInterface : 添加本地的js代码接口。
removeJavascriptInterface : 移除本地的js代码接口。在4.0至4.2的Android系统上,Webview自己增加了searchBoxJavaBredge_,可能被黑客利用导致远程代码执行。为阻止该漏洞,需要手工移除接口searchBoxJavaBredge_。代码如下所示:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. wv_web.removeJavascriptInterface("searchBoxJavaBredge_");  
setWebViewClient : 设置浏览器的加载事件。
setWebChromeClient : 设置浏览器的交互事件。
setDownloadListener : 设置文件下载监听器。
loadData : 加载文本数据。第二个参数表示媒体类型,如"text/html";第三个参数表示数据的编码格式,"base64"表示采用base64编码,其余值(包括null)表示url编码。
loadUrl : 加载url。
canGoBack : 判断页面能否返回。
goBack : 返回到上一个页面。


网页设置WebSettings

WebSettings用于操作WebView的web设置信息。其对象由WebView的getSettings方法得到。下面是WebSettings的常用设置方法:
setLoadsImagesAutomatically : 设置是否自动加载图片
setDefaultTextEncodingName : 设置默认的文本编码。如utf-8、gbk等等。
setJavaScriptEnabled : 设置是否支持Javascript
setJavaScriptCanOpenWindowsAutomatically : 设置是否允许js自动打开新窗口(window.open())
以上是基本的设置。
setSupportZoom : 设置是否支持缩放。
setBuiltInZoomControls : 设置是否出现缩放工具。
setUseWideViewPort : 当容器超过页面大小时,是否放大页面大小到容器宽度。
setLoadWithOverviewMode : 当页面超过容器大小时,是否缩小页面尺寸到页面宽度。
setLayoutAlgorithm : 设置自适应屏幕的算法,一般是LayoutAlgorithm.SINGLE_COLUMN。如果不做设置,4.2.2及之前版本自适应时可能会出现表格错乱的情况。
以上是网页与容器适配的设置。
setDomStorageEnabled : 设置是否启用本地存储。
setCacheMode : 设置是否使用缓存。LOAD_CACHE_ELSE_NETWORK表示优先使用缓存,LOAD_NO_CACHE表示不使用缓存,LOAD_CACHE_ONLY表示只使用缓存。
setAppCacheEnabled : 设置是否启用app缓存。
setAppCachePath : 设置app缓存文件的路径。
setAllowFileAccess : 设置是否允许访问文件,例如WebView访问sd卡的文件。不过assets与res文件不受此限制,仍然可以通过“file:///android_asset”和“file:///android_res”访问。
setDatabaseEnabled : 设置是否启用数据库。
以上是与存储有关的设置。


网页事件监听

主要有三个事件监听器,分别是WebViewClient、WebChromeClient和DownloadListener。


浏览器加载事件
WebViewClient主要用于处理。相关类名与方法说明如下:
监听器类名 : WebViewClient
设置监听器的方法 : setWebViewClient
监听器需要重写的方法 : 
onPageStarted : 页面开始加载。一般在此弹出进度对话框ProgressFialog
onPageFinished : 页面加载结束。一般在此关闭进度对话框。
onReceivedError : 收到错误信息。
onReceivedSslError : 收到ssl错误。
shouldOverrideUrlLoading : 重写该方法表明,点击网页里面的链接是在当前的webview里跳转,还是跳转到其它浏览器。如果想在当前的webview跳转,则加上下面这句代码:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. view.loadUrl(url);  


浏览器的交互事件
WebChromeClient主要用于。相关类名与方法说明如下:
监听器类名 : WebChromeClient
设置监听器的方法 : setWebChromeClient
监听器需要重写的方法 : 
onReceivedTitle : 收到页面标题
onProgressChanged : 页面加载进度发生变化
onJsAlert : 弹出js警告框。
onJsConfirm : 弹出js确认框。
onJsPrompt : 弹出js提示框。
onGeolocationPermissionsShowPrompt : 网页请求定位权限。通常重写该方法弹出一个确认对话框,提示用户是否允许网页获得定位权限。下面代码表示允许定位权限:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. callback.invoke(origin, truefalse);  


文件下载事件
DownloadListener主要用于。相关类名与方法说明如下:
监听器类名 : DownloadListener
设置监听器的方法 : setDownloadListener
监听器需要重写的方法 : 
onDownloadStart : 文件开始下载。可在此设置文件下载的方式,以及文件的保存路径。


浏览器的应用场景

1、点击返回键返回上个页面,可监听返回键的按下事件,具体有两种方式,分别是重写onBackPressed函数,以及重写onKeyDown函数。
重写onBackPressed函数
  1. @Override  
  2. public void onBackPressed() {  
  3.     if (wv_web.canGoBack()) {  
  4.         wv_web.goBack();  
  5.         return;  
  6.     } else {  
  7.         finish();  
  8.     }  
  9. }  
重写onKeyDown函数
  1. @Override  
  2. public boolean onKeyDown(int keyCode, KeyEvent event) {  
  3.     if ((keyCode == KeyEvent.KEYCODE_BACK) && wv_web.canGoBack()) {  
  4.         wv_web.goBack();  
  5.         return true;  
  6.     } else {  
  7.         return false;  
  8.     }  
  9. }  


2、显示页面加载进度。可在WebViewClient的onPageStarted方法中弹出进度对话框ProgressFialog,然后在onPageFinished方法中关闭进度对话框。要想动态显示当前页面的加载百分比,可在WebChromeClient的onProgressChanged方法中设置进度对话框的当前进度。


3、显示js的提示对话框。默认情况下,js对话框也能正常显示和操作,只是对话框标题默认为“网址为"***"的网页显示”,这个标题信息不够友好,所以我们需要重写WebChromeClient的三个js方法onJsAlert、onJsConfirm和onJsPrompt,在内部构造一个AlertDialog实例,分别设置标题、信息,以及肯定按钮和否定按钮。同时监听肯定按钮的点击事件,调用JsResult的confirm方法;监听否定按钮的点击事件,调用JsResult的cancel方法。


4、允许js调用本地java代码。先声明一个本地java代码的操作类,然后调用WebView的addJavascriptInterface方法,关联本地java对象与对象名称。代码示例如下:
声明一个本地java代码的操作类:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class MyJavaScript {  
  2.     @JavascriptInterface  
  3.     public String toString() {  
  4.         return "injectedObject";  
  5.     }  
  6. }  
在WebView中注册该java代码的对象,并演示javascript的调用过程:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. wv_web.getSettings().setJavaScriptEnabled(true);  
  2. wv_web.addJavascriptInterface(new MyJavaScript(), "injectedObject");  
  3. wv_web.loadData("<!DOCTYPE html><title></title>""text/html"null);  
  4. wv_web.loadUrl("javascript:alert(injectedObject.toString())");  


Android代码与html的js代码相互调用

Android代码调用js代码

下面是android的代码
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. wv_local.getSettings().setJavaScriptEnabled(true);  
  2. wv_local.setWebChromeClient(new WebChromeClient());  
  3. wv_local.loadUrl("file:///android_asset/sample.html");  
  4. wv_local.loadUrl("javascript:showMsg()"); //showMsg方法是sample.html里面的js方法  

下面是js的代码
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <script type="text/javascript">  
  2.    function showMsg(){  
  3.       alert("hello world!");  
  4.    }  
  5. </script>  

js代码调用Android代码

下面是android的代码
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. wv_local.getSettings().setJavaScriptEnabled(true);  
  2. wv_local.addJavascriptInterface(new Contact(), "contact");  
  3. wv_local.loadUrl("file:///android_asset/sample.html");  
  4.   
  5. private final class Contact {  
  6.     @JavascriptInterface  
  7.     public void showMsg(String msg) {  
  8.         AlertDialog.Builder builder = new AlertDialog.Builder(LocalActivity.this);  
  9.         builder.setMessage(msg).create().show();  
  10.     }  
  11. }  

下面是js的代码
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <script type="text/javascript">  
  2.    function showMsgInAndroid(){  
  3.       contact.showMsg("hello world 3");  
  4.    }  
  5. </script>  
  6. <button id="btntest" onclick="javascript:showMsgInAndroid()">调用android方法</button>  


Android与js互调获得返回值

js调用Android方法,可直接获取调用的返回值,难点在于Android调用js方法的返回值。因为WebView加载网页是异步的,所以loadUrl方法调用js无法直接获得返回值。多数情况只能在js代码中回调Android方法,从而间接获取Android调用js的返回值。不过从Android4.4.2开始,我们可通过调用WebView的evaluateJavascript方法来直接得到js返回值,下面是Android的示例代码:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. wv_local.evaluateJavascript("getMsg()"new ValueCallback<String>() {  
  2.     @Override  
  3.     public void onReceiveValue(String value) {  
  4.         AlertDialog.Builder builder = new AlertDialog.Builder(LocalActivity.this);  
  5.         builder.setMessage(UnicodeToString(value)).create().show();  
  6.     }  
  7. });  
  8.   
  9. public static String UnicodeToString(String str) {  
  10.     if (str != null && str.trim().length() > 0) {  
  11.         String un = str.trim();  
  12.         StringBuffer sb = new StringBuffer();  
  13.         int idx = un.indexOf("\\u");  
  14.         while (idx >= 0) {  
  15.             if (idx > 0) {  
  16.                 sb.append(un.substring(0, idx));  
  17.             }  
  18.   
  19.             String hex = un.substring(idx + 2, idx + 2 + 4);  
  20.             sb.append((char) Integer.parseInt(hex, 16));  
  21.             un = un.substring(idx + 2 + 4);  
  22.             idx = un.indexOf("\\u");  
  23.         }  
  24.         sb.append(un);  
  25.         return sb.toString();  
  26.     }  
  27.     return "";  
  28. }  

下面是js的代码
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <script type="text/javascript">  
  2.    function getMsg(){  
  3.       return "来自网页的消息: hello world!";  
  4.    }  
  5. </script>  


注意事项

下面是android与js相互调用的几个注意点:
1、WebView要调用setWebChromeClient方法设置js的解释客户端,来解决js中alert不弹出的问题,因为js页面的渲染需要WebChromeClient去实现。
2、如果js调用android代码时,logcat报错“Uncaught TypeError: Object [object Object] has no method”,那是因为Android4.2以上版本默认不开放js调用本地方法的权限,得给开放js调用的方法加上“@JavascriptInterface注释”,该注释允许js代码访问android的方法。
3、evaluateJavascript是Android4.4.2之后才引入的新方法,如果是4.4.2之前的Android版本,需要注意做兼容处理。
4、js获取Android方法返回值中的中文是正常,但Android获取js方法返回值的中文却是“\u”打头的字符串,所以Android要先将js返回的字符串做转义处理,即调用上面的UnicodeToString方法,转义后的字符串才是正常的汉字。
5、如果android与js存在嵌套调用(即A调用B,B内部又去调用A),那么在Android4.4.2之后务必要保证两个调用在同一个线程中,不然运行时会报错“java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread.”。具体的解决方法,是调用WebView对象的post方法,在post的Runnable任务中再去调用js方法,示例代码如下:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. private final class Contact {  
  2.     //网页的js调用android的showcontacts方法,然后showcontacts内部又去调用js的show<span style="font-family: Arial, Helvetica, sans-serif;">方法</span>  
  3.     @JavascriptInterface  
  4.     public void showcontacts() {  
  5.         wv_local.post(new Runnable() {  
  6.             @Override  
  7.             public void run() {  
  8.                 wv_local.loadUrl("javascript:show()");  
  9.             }  
  10.         });  
  11.     }  
  12. }  


HTML5框架

PhoneGap

以下说明文字来自百度百科的PhoneGap词条:
“PhoneGap是一个用基于HTML,CSS和JavaScript的,创建移动跨平台移动应用程序的快速开发平台。它使开发者能够利用iPhone、Android、Palm、Symbian、WP7、WP8、Bada和Blackberry智能手机的核心功能——包括地理定位,加速器,联系人,声音和振动等,此外PhoneGap拥有丰富的插件,可以调用。
它需要特定平台提供的附加软件,例如iPhone的iPhone SDK,Android的Android SDK等,也可以和DW5.5及以上版本配套开发。使用PhoneGap只比为每个平台分别建立应用程序好一点点,因为虽然基本代码是一样的,但是你仍然需要为每个平台分别编译应用程序。”
对于Android开发来说,PhoneGap其实就是在assets下面新建了www目录,然后入口Activity通过嵌入WebView来加载www下的html页面,接下来就是在各个html之间互相跳转,从而实现Android原生app界面交互的效果。


Cordova

虽然PhoneGap号称跨平台,但是html5+js也只能完成网站那样的网页操作,却无法直接操作手机设备的功能。因此PhoneGap引入了Cordova,Cordova提供了一组与设备相关的API,通过这组API,app能够以JavaScript访问原生的设备功能,如摄像头、麦克风等。Cordova还提供了一组统一的JavaScript类库,以及为这些类库所用的设备相关的原生后台代码。Cordova是驱动PhoneGap的核心引擎,有人说它们的关系类似于Webkit和Google Chrome的关系。


WeX5

WeX5是国内基于Phonegap的一个HTML5开发框架,它有自己的开发工具“WeX5 studio”,其实就是个定制版的Eclipse。在这个IDE上,可以通过拖曳控件来画html页面,这个倒是很像ios的开发工具Xcode。另外,WeX5的Cordova插件还集成了国内常用的几个工具包,与PhoneGap相比,WeX5更适合于国内的开发者。


代码示例

下面是WebView使用的代码例子:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. import android.annotation.SuppressLint;  
  2. import android.app.Activity;  
  3. import android.app.AlertDialog;  
  4. import android.app.ProgressDialog;  
  5. import android.content.Context;  
  6. import android.content.DialogInterface;  
  7. import android.graphics.Bitmap;  
  8. import android.os.Bundle;  
  9. import android.util.Log;  
  10. import android.view.KeyEvent;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.view.View.OnLongClickListener;  
  14. import android.view.inputmethod.InputMethodManager;  
  15. import android.webkit.DownloadListener;  
  16. import android.webkit.GeolocationPermissions.Callback;  
  17. import android.webkit.JavascriptInterface;  
  18. import android.webkit.JsResult;  
  19. import android.webkit.WebChromeClient;  
  20. import android.webkit.WebSettings;  
  21. import android.webkit.WebSettings.LayoutAlgorithm;  
  22. import android.webkit.WebView;  
  23. import android.webkit.WebViewClient;  
  24. import android.widget.Button;  
  25. import android.widget.EditText;  
  26. import android.widget.Toast;  
  27.   
  28. public class WebActivity extends Activity   
  29.     implements OnClickListener, OnLongClickListener {  
  30.       
  31.     private final static String TAG = "WebActivity";  
  32.     private Context mContext;  
  33.     private EditText et_web_url;  
  34.     private Button btn_web_go;  
  35.     private WebView wv_web;  
  36.     private ProgressDialog m_pd;  
  37.   
  38.     @Override  
  39.     protected void onCreate(Bundle savedInstanceState) {  
  40.         super.onCreate(savedInstanceState);  
  41.         setContentView(R.layout.activity_web);  
  42.   
  43.         mContext = this;  
  44.         et_web_url = (EditText) findViewById(R.id.et_web_url);  
  45.         et_web_url.setOnLongClickListener(this);  
  46.         et_web_url.setText("222.77.181.14/news/zapb.aspx");  
  47.         wv_web = (WebView) findViewById(R.id.wv_web);  
  48.         btn_web_go = (Button) findViewById(R.id.btn_web_go);  
  49.         btn_web_go.setOnClickListener(this);  
  50.           
  51.         initWebViewSettings();  
  52.     }  
  53.       
  54.     @SuppressLint("SetJavaScriptEnabled")  
  55.     private void initWebViewSettings() {  
  56.         WebSettings settings = wv_web.getSettings();  
  57.         //设置是否自动加载图片  
  58.         settings.setLoadsImagesAutomatically(true);  
  59.         //设置默认的文本编码  
  60.         settings.setDefaultTextEncodingName("utf-8");  
  61.           
  62.         //设置是否支持Javascript  
  63.         settings.setJavaScriptEnabled(true);  
  64.         //设置是否允许js自动打开新窗口(window.open())  
  65.         settings.setJavaScriptCanOpenWindowsAutomatically(false);  
  66.           
  67.         // 设置是否支持缩放   
  68.         settings.setSupportZoom(true);  
  69.         // 设置是否出现缩放工具   
  70.         settings.setBuiltInZoomControls(true);  
  71.         //当容器超过页面大小时,是否放大页面大小到容器宽度  
  72.         settings.setUseWideViewPort(true);  
  73.         //当页面超过容器大小时,是否缩小页面尺寸到页面宽度  
  74.         settings.setLoadWithOverviewMode(true);  
  75.         //设置自适应屏幕。4.2.2及之前版本自适应时可能会出现表格错乱的情况  
  76.         settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);  
  77.   
  78.         //设置是否启用本地存储  
  79.         settings.setDomStorageEnabled(true);  
  80.         //优先使用缓存  
  81.         //settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  
  82.         //设置是否使用缓存  
  83.         settings.setCacheMode(WebSettings.LOAD_NO_CACHE);  
  84.         //设置是否启用app缓存  
  85.         settings.setAppCacheEnabled(true);  
  86.         //设置app缓存文件的路径  
  87.         settings.setAppCachePath("");  
  88.         //设置是否允许访问文件,如WebView访问sd卡的文件。不过assets与res文件不受此限制,仍然可以通过“file:///android_asset”和“file:///android_res”访问  
  89.         settings.setAllowFileAccess(true);  
  90.         //设置是否启用数据库  
  91.         settings.setDatabaseEnabled(true);  
  92.     }  
  93.   
  94.     @Override  
  95.     public void onClick(View v) {  
  96.         if (v.getId() == R.id.btn_web_go) {  
  97.             InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);  
  98.             imm.hideSoftInputFromWindow(et_web_url.getWindowToken(), 0);  
  99.             String url = "http://" + et_web_url.getText().toString();  
  100.             Log.d(TAG, "url="+url);  
  101.             //禁止执行远程代码。在4.0至4.2的Android系统上,Webview自己增加了searchBoxJavaBredge_,可能让黑客利用导致远程代码执行  
  102.             wv_web.removeJavascriptInterface("searchBoxJavaBredge_");  
  103.             wv_web.addJavascriptInterface(new MyJavaScript(), "injectedObject");  
  104.               
  105.             //加载远程URL  
  106.             wv_web.loadUrl(url);  
  107.             //加载本地网页  
  108.             //wv_web.loadUrl("file:///android_asset/example.html");  
  109.             wv_web.setWebViewClient(mWebViewClient);  
  110.             wv_web.setWebChromeClient(mWebChrome);  
  111.             wv_web.setDownloadListener(mDownloadListener);  
  112.         }  
  113.     }  
  114.   
  115.     @Override  
  116.     public boolean onLongClick(View v) {  
  117.         if (v.getId() == R.id.et_web_url) {  
  118.             et_web_url.setText("");  
  119.         }  
  120.         return true;  
  121.     }  
  122.       
  123.     @Override  
  124.     public void onBackPressed() {  
  125.         if (wv_web.canGoBack()) {  
  126.             wv_web.goBack();  
  127.             return;  
  128.         } else {  
  129.             finish();  
  130.         }  
  131.     }  
  132.   
  133. //  @Override  
  134. //  public boolean onKeyDown(int keyCode, KeyEvent event) {  
  135. //      if ((keyCode == KeyEvent.KEYCODE_BACK) && wv_web.canGoBack()) {  
  136. //          wv_web.goBack();  
  137. //          return true;  
  138. //      } else {  
  139. //          return false;  
  140. //      }  
  141. //  }  
  142.   
  143.     private WebViewClient mWebViewClient = new WebViewClient() {  
  144.   
  145.         @Override  
  146.         public void onReceivedSslError(WebView view,  
  147.                 android.webkit.SslErrorHandler handler,  
  148.                 android.net.http.SslError error) {  
  149.             handler.proceed();  
  150.         };  
  151.   
  152.         @Override  
  153.         public void onPageStarted(WebView view, String url, Bitmap favicon) {  
  154.             super.onPageStarted(view, url, favicon);  
  155.             Log.d(TAG, "onPageStarted:" + url);  
  156.             if (m_pd == null || m_pd.isShowing() == false) {  
  157.                 m_pd = new ProgressDialog(mContext);  
  158.                 m_pd.setTitle("稍等");  
  159.                 m_pd.setMessage("页面加载中……");  
  160.                 m_pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  161.                 m_pd.show();  
  162.             }  
  163.         }  
  164.   
  165.         @Override  
  166.         public void onPageFinished(WebView view, String url) {  
  167.             super.onPageFinished(view, url);  
  168.             Log.d(TAG, "onPageFinished:" + url);  
  169.             if (m_pd != null && m_pd.isShowing() == true) {  
  170.                 m_pd.dismiss();  
  171.             }  
  172.         }  
  173.   
  174.         @Override  
  175.         public void onReceivedError(WebView view, int errorCode,  
  176.                 String description, String failingUrl) {  
  177.             super.onReceivedError(view, errorCode, description, failingUrl);  
  178.             Log.d(TAG, "onReceivedError: url=" + failingUrl+", errorCode="+errorCode+", description="+description);  
  179.             if (m_pd != null && m_pd.isShowing() == true) {  
  180.                 m_pd.dismiss();  
  181.             }  
  182.             Toast.makeText(mContext, "页面加载失败,请稍候再试",Toast.LENGTH_LONG).show();  
  183.         }  
  184.   
  185.         @Override  
  186.         public boolean shouldOverrideUrlLoading(WebView view, String url) {  
  187.             view.loadUrl(url);  
  188.             return true;  
  189.         }  
  190.   
  191.     };  
  192.   
  193.     private WebChromeClient mWebChrome = new WebChromeClient() {  
  194.         private String mTitle = "";  
  195.   
  196.         @Override  
  197.         public void onReceivedTitle(WebView view, String title) {  
  198.             mTitle = title;  
  199.         }  
  200.           
  201.         @Override  
  202.         public void onProgressChanged(WebView view, int progress) {  
  203.             if (m_pd != null && m_pd.isShowing() == true) {  
  204.                 m_pd.setProgress(progress);  
  205.             }  
  206.         }  
  207.   
  208.         @Override  
  209.         public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {  
  210.             AlertDialog.Builder builder = new AlertDialog.Builder(mContext)  
  211.                     .setTitle(mTitle)  
  212.                     .setMessage(message)  
  213.                     .setPositiveButton("确定",  
  214.                             new DialogInterface.OnClickListener() {  
  215.                                 @Override  
  216.                                 public void onClick(DialogInterface dialog, int which) {  
  217.                                     result.confirm();  
  218.                                 }  
  219.                             })  
  220.                     //onJsAlert一般无需设置setNeutralButton,onJsConfirm才可能需要设置  
  221.                     .setNeutralButton("取消",  
  222.                             new DialogInterface.OnClickListener() {  
  223.                                 @Override  
  224.                                 public void onClick(DialogInterface dialog, int which) {  
  225.                                     result.cancel();  
  226.                                 }  
  227.                             });  
  228.             builder.setCancelable(true).create().show();  
  229.             return true;  
  230.         }  
  231.   
  232.         @Override  
  233.         public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {  
  234.             callback.invoke(origin, truefalse);  
  235.             super.onGeolocationPermissionsShowPrompt(origin, callback);  
  236.         }  
  237.     };  
  238.   
  239.     private DownloadListener mDownloadListener = new DownloadListener() {  
  240.         @Override  
  241.         public void onDownloadStart(String url, String userAgent, String contentDisposition,  
  242.                 String mimetype, long contentLength) {  
  243.             //此处操作文件下载  
  244.         }  
  245.     };  
  246.   
  247.     class MyJavaScript {  
  248.         @JavascriptInterface  
  249.         public String toString() {  
  250.             return "injectedObject";  
  251.         }  
  252.     }  
  253.   
  254. }  



点击下载本文用到的网页加载与JS调用的工程代码



点此查看Android开发笔记的完整目录
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值