如何学习Android5.0 下 新的 webview 的实现

  在Android中,可以使用Webview控件来浏览网页。通过使用该控件,我们可以自制一个简单的浏览器,运行效果如图1所示。
&图1&运行效果
&  在使用WebView控件时,首先需要在xml布局文件中定义一个WebView控件,定义的方法如下:
1   &WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
&  WebView中提供了很多方法,例如,我们可以使用canGoBack()方法判断是否能够从该网页返回上一个打开的网页;使用getTitle()和getUrl()方法获得当前网页的标题和URL路径;使用loadUrl(String&url)方法加载所要打开的网页等等。如下的代码通过使用loadUrl()方法在WebView控件中打开了百度主页。
1   private WebView mWebV
2   mWebView = (WebView)this.findViewById(R.id.webView);
3   mWebView.loadUrl("/");
&2.WebSettings
&  WebSettings用来设置WebView的属性和状态。WebSettings和WebView存在于同一个生命周期中,可以使用如下的方法获得WebSettings对象。
  WebSettings webSettings = mWebView.getSettings();
&  在创建WebView时,系统会对WebView进行一些默认设置,当我们通过以上的方法得到WebSettings对象后,便可以从WebSettings对象中取出WebView的默认属性和状态了,当然了,我们也可以通过WebSettings对象对WebView的默认属性和状态进行设置。
  WebSettings提供的一些常用的设置WebView的属性和状态的方法如下:
  (1)setAllowFileAccess(boolean&allow);       //设置启用或禁止访问文件数据
  (2)setBuiltInZoomControls(boolean&enabled);   //设置是否支持缩放
  (3)setDefaultFontSize(int&size);&         & //设置默认的字体大小
  (4)setJavaScriptEnabled(boolean&flag);       //设置是否支持JavaScript
  (5)setSupportZoom(boolean&support);       //设置是否支持变焦
3.WebViewClient
  WebViewClient主要用来辅助WebView处理各种通知、请求等事件。我们可以通过WebView的setWebViewClient()方法,为WebView对象指定一个WebViewClient,具体的实现方法如下所示:
1   MyWebViewClient myWebViewClient = new MyWebViewClient();
2   mWebView.setWebViewClient(myWebViewClient);
* Class  :  MyWebViewClient,用于辅助WebView,处理各种通知、请求等事件
* Author  :
博客园-依旧淡然
private class MyWebViewClient extends WebViewClient {
//重写父类方法,让新打开的网页在当前的WebView中显示
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
&  可以看到,在如上的代码中,我们通过在子类MyWebViewClient中重写父类WebViewClient的shouldOverrideUrlLoading()方法,实现了让新打开的网页在当前的WebView中进行显示,而不是调用Android系统自带的浏览器进行访问。
  在WebViewClient中同样提供了很多的方法,比如以下一些:
  (1)doUpdateVisitedHistory(WebView&view,&String&url,&boolean&isReload);        && //更新历史记录
  (2)onFormResubmission(WebView&view,&Message&dontResend,&Message&resend);    & //重新请求网页数据
  (3)onLoadResource(WebView&view,&String&url);                       //加载指定网址提供的资源
  (4)onPageFinished(WebView&view,&String&url);                      & //网页加载完毕
  (5)onPageStarted(WebView&view,&String&url,&Bitmap&favicon);               //网页开始加载
  (6)onReceivedError(WebView&view,&int&errorCode,&String&description,&String&failingUrl);  //报告错误信息
4.WebChromeClient
  WebChromeClient主要用来辅助WebView处理Javascript的对话框、网站图标、网站标题以及网页加载进度等。
  同样地,我们可以通过WebView的setWebChromeClient()方法,为WebView对象指定一个WebChromeClient。
  在WebChromeClient中,当网页的加载进度发生变化时,onProgressChanged(WebView&view,&int&newProgress)方法会被调用;当网页的图标发生改变时,onReceivedIcon(WebView&view,&Bitmap&icon)方法会被调用;当网页的标题发生改变时,onReceivedTitle(WebView&view,&String&title)方法会被调用。利用这些方法,我们便可以很容易的获得网页的加载进度、网页的标题和图标等信息了,正如下面的代码所示:
MyWebChromeClient myWebChromeClient = new MyWebChromeClient();
mWebView.setWebChromeClient(myWebChromeClient);
用于辅助WebView,处理JavaScript的对话框、网站图标、网站标题、加载进度等
博客园-依旧淡然
private class MyWebChromeClient extends WebChromeClient {
//获得网页的加载进度,显示在右上角的TextView控件中
public void onProgressChanged(WebView view, int newProgress) {
if(newProgress & 100) {
String progress = newProgress + "%";
mTextView_progress.setText(progress);
mTextView_progress.setText(" ");
//获得网页的标题,作为应用程序的标题进行显示
public void onReceivedTitle(WebView view, String title) {
MainActivity.this.setTitle(title);
5.WebView与Javascript
  在WebView中不仅可以运行HTML代码,更重要的是,WebView可以与Javascript互相调用。也就是说,在Javascript中可以获取WebView的内容,与此同时,在WebView中也可以调用Javascript里面的方法。
  下面就来说说如何在WebView中调用Javascript里面的方法。
  这里,我使用了百度地图的API接口(一份内嵌了Javascript的HTML文档),在该接口中提供如下的Javascript方法:
/*********************************/
/*********************************/
var city = new BMap.LocalSearch(map,{renderOptions:{map:map,autoViewport:true}});
function findPlace(place)
city.search(place);
&  我们要做的就是在WebView中调用findPlace()方法,完成地点的查找。在WebView中调用Javascript里面的方法是通过代码WebView.loadUrl(&javascript:方法名()&)来实现的。如下的代码,从EditText控件中获得用户想要查找的地名,然后调用了Javascript中的findPlace()方法,进行查找。
* Function
点击事件处理
博客园-依旧淡然
public void onClick(View view) {
switch(view.getId()) {
case R.id.imagebutton_search:
//查找地名
String str = mEditText_input.getText().toString();
String url = "javascript:findPlace('" + str + "')";
mWebView.loadUrl(url);
&  比如,我们对&圆明园&进行查找,可以看到如图2所示的查找结果。&
&图2&查找&圆明园&
阅读(...) 评论()WebView控制调用相应的WEB页面进行展示。安卓源码当碰到页面有下载链接的时候,点击上去是一点反应都没有的。原来是因为WebView默认没有开启文件下载的功能,如果要实现文件下载的功能,需要设置WebView的DownloadListener,通过实现自己的DownloadListener来实现文件的下载。具体操作如下:&1、设置WebView的DownloadListener:&&&& webView.setDownloadListener(new MyWebViewDownLoadListener());&2、实现MyWebViewDownLoadListener这个类,具体可以如下这样:&&&[java]&view plaincopy&private&class&MyWebViewDownLoadListener&implements&DownloadListener{&&&&&&&&&&&&@Override&&&&&&&&&&public&void&onDownloadStart(String&url,&String&userAgent,&String&contentDisposition,&String&mimetype,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&long&contentLength)&{&&&&&&&&&&&&&&&&&&&&&&&&&Log.i("tag",&"url="+url);&&&&&&&&&&&&&&&&&&&&&&&&&Log.i("tag",&"userAgent="+userAgent);&&&&&&&&&&&&&&Log.i("tag",&"contentDisposition="+contentDisposition);&&&&&&&&&&&&&&&&&&&&&&&Log.i("tag",&"mimetype="+mimetype);&&&&&&&&&&&&&&Log.i("tag",&"contentLength="+contentLength);&&&&&&&&&&&&&&Uri&uri&=&Uri.parse(url);&&&&&&&&&&&&&&Intent&intent&=&new&Intent(Intent.ACTION_VIEW,&uri);&&&&&&&&&&&&&&startActivity(intent);&&&&&&&&&&&&&&&&&&&&&}&&&&&&}&&& 这只是调用系统中已经内置的浏览器进行下载,还没有WebView本身进行的文件下载,不过,这也基本上满足我们的应用场景了。&我在项目中的运用&android源码项目要求这样:&1,需要使用WebView加载一个网页;&2,网页中有文件下载的链接,点击后需要下载文件到SDcard;&3,然后自动打开文件;&下面是具体解决办法&第一步,对WebView进行一系列设置。[java]&view plaincopy&WebView&webview=(WebView)layout.findViewById(R.id.webview);&&&&&&&&&&&&&&&&&&webview.getSettings().setJavaScriptEnabled(true);&&&&&&&&&&&&&&&&&&webview.setWebChromeClient(new&MyWebChromeClient());&&&&&&&&&&&&&&&&&&webview.requestFocus();&&&&&&&&&&&&&&&&&&webview.loadUrl(jcrs_sub.get(position).addr);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&webview.setWebViewClient(new&MyWebViewClient());&&&&&&&&&&&&&&&&&&webview.setDownloadListener(new&MyWebViewDownLoadListener());&&&&public&class&MyWebViewClient&extends&WebViewClient&{&&&&&&&&&&&&&&&&&&&&&&&&&&public&boolean&shouldOverviewUrlLoading(WebView&view,&String&url)&{&&&&&&&&&&&&&&L.i("shouldOverviewUrlLoading");&&&&&&&&&&&&&&view.loadUrl(url);&&&&&&&&&&&&&&return&&&&&&&&&&&}&&&&&&&&&&&&public&void&onPageStarted(WebView&view,&String&url,&Bitmap&favicon)&{&&&&&&&&&&&&&&L.i("onPageStarted");&&&&&&&&&&&&&&showProgress();&&&&&&&&&&}&&&&&&&&&&&&public&void&onPageFinished(WebView&view,&String&url)&{&&&&&&&&&&&&&&L.i("onPageFinished");&&&&&&&&&&&&&&closeProgress();&&&&&&&&&&}&&&&&&&&&&&&public&void&onReceivedError(WebView&view,&int&errorCode,&&&&&&&&&&&&&&&&&&String&description,&String&failingUrl)&{&&&&&&&&&&&&&&L.i("onReceivedError");&&&&&&&&&&&&&&closeProgress();&&&&&&&&&&}&&&&&&}&&&&&&&&&&&&public&boolean&onKeyDown(int&keyCode,&KeyEvent&event)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&&&&&&&}&&第二步,起线程开始下载文件。[java]&view plaincopy&private&class&MyWebViewDownLoadListener&implements&DownloadListener&{&&&&&&&&&&&&@Override&&&&&&&&&&public&void&onDownloadStart(String&url,&String&userAgent,&String&contentDisposition,&String&mimetype,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&long&contentLength)&{&&&&&&&&&&&&&&if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){&&&&&&&&&&&&&&&&&&Toast&t=Toast.makeText(mContext,&"需要SD卡。",&Toast.LENGTH_LONG);&&&&&&&&&&&&&&&&&&t.setGravity(Gravity.CENTER,&0,&0);&&&&&&&&&&&&&&&&&&t.show();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&DownloaderTask&task=new&DownloaderTask();&&&&&&&&&&&&&&task.execute(url);&&&&&&&&&&}&&&&&&&&}&&&&&&&&&&private&class&DownloaderTask&extends&AsyncTask&String,&Void,&String&&{&&&&&&&&&&&&&public&DownloaderTask()&{&&&&&&&&&&&}&&&&&&&&&&&&@Override&&&&&&&&&&protected&String&doInBackground(String...&params)&{&&&&&&&&&&&&&&&&&&&&&&&&&&String&url=params[0];&&&&&&&&&&&&&&String&fileName=url.substring(url.lastIndexOf("/")+1);&&&&&&&&&&&&&&fileName=URLDecoder.decode(fileName);&&&&&&&&&&&&&&Log.i("tag",&"fileName="+fileName);&&&&&&&&&&&&&&&&&&&&&&&&&&&&File&directory=Environment.getExternalStorageDirectory();&&&&&&&&&&&&&&File&file=new&File(directory,fileName);&&&&&&&&&&&&&&if(file.exists()){&&&&&&&&&&&&&&&&&&Log.i("tag",&"The&file&has&already&exists.");&&&&&&&&&&&&&&&&&&return&fileN&&&&&&&&&&&&&&}&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&&&HttpClient&client&=&new&DefaultHttpClient();&&&&&&&&&&&&&&&&&&&&HttpGet&get&=&new&HttpGet(url);&&&&&&&&&&&&&&&&&&&&HttpResponse&response&=&client.execute(get);&&&&&&&&&&&&&&&&&&if(HttpStatus.SC_OK==response.getStatusLine().getStatusCode()){&&&&&&&&&&&&&&&&&&&&&&HttpEntity&entity&=&response.getEntity();&&&&&&&&&&&&&&&&&&&&&&InputStream&input&=&entity.getContent();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&writeToSDCard(fileName,input);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&input.close();&&&&&&&&&&&&&&&&&&&&&&return&fileN&&&&&&&&&&&&&&&&&&&&}else{&&&&&&&&&&&&&&&&&&&&&&return&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&catch&(Exception&e)&{&&&&&&&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&&&&&&&&&return&&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&&&&&&@Override&&&&&&&&&&protected&void&onCancelled()&{&&&&&&&&&&&&&&&&&&&&&&&&&&super.onCancelled();&&&&&&&&&&}&&&&&&&&&&&&@Override&&&&&&&&&&protected&void&onPostExecute(String&result)&{&&&&&&&&&&&&&&&&&&&&&&&&&&super.onPostExecute(result);&&&&&&&&&&&&&&closeProgressDialog();&&&&&&&&&&&&&&if(result==null){&&&&&&&&&&&&&&&&&&Toast&t=Toast.makeText(mContext,&"连接错误!请稍后再试!",&Toast.LENGTH_LONG);&&&&&&&&&&&&&&&&&&t.setGravity(Gravity.CENTER,&0,&0);&&&&&&&&&&&&&&&&&&t.show();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&&&Toast&t=Toast.makeText(mContext,&"已保存到SD卡。",&Toast.LENGTH_LONG);&&&&&&&&&&&&&&t.setGravity(Gravity.CENTER,&0,&0);&&&&&&&&&&&&&&t.show();&&&&&&&&&&&&&&File&directory=Environment.getExternalStorageDirectory();&&&&&&&&&&&&&&File&file=new&File(directory,result);&&&&&&&&&&&&&&Log.i("tag",&"Path="+file.getAbsolutePath());&&&&&&&&&&&&&&&&&&&&&&&&&&&&Intent&intent&=&getFileIntent(file);&&&&&&&&&&&&&&&&&&&&&&&&&&&&startActivity(intent);&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&@Override&&&&&&&&&&protected&void&onPreExecute()&{&&&&&&&&&&&&&&&&&&&&&&&&&&super.onPreExecute();&&&&&&&&&&&&&&showProgressDialog();&&&&&&&&&&}&&&&&&&&&&&&@Override&&&&&&&&&&protected&void&onProgressUpdate(Void...&values)&{&&&&&&&&&&&&&&&&&&&&&&&&&&super.onProgressUpdate(values);&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&}&&&第三步,实现一些工具方法。&&&[java]&view plaincopy&&span&style="font-family:Helvetica,&Tahoma,&Arial,&sans-"&private&ProgressDialog&mD&&&&&&private&void&showProgressDialog(){&&&&&&&&&&if(mDialog==null){&&&&&&&&&&&&&&mDialog&=&new&ProgressDialog(mContext);&&&&&&&&&&&&&&&&mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);&&&&&&&&&&&&mDialog.setMessage("正在加载&,请等待...");&&&&&&&&&&&&&&&&mDialog.setIndeterminate(false);&&&&&&&&&&&&mDialog.setCancelable(true);&&&&&&&&&&&&mDialog.setCanceledOnTouchOutside(false);&&&&&&&&&&&&&&mDialog.setOnDismissListener(new&OnDismissListener()&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@Override&&&&&&&&&&&&&&&&&&public&void&onDismiss(DialogInterface&dialog)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&mDialog=&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&});&&&&&&&&&&&&&&mDialog.show();&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&}&&&&&&private&void&closeProgressDialog(){&&&&&&&&&&if(mDialog!=null){&&&&&&&&&&&&&&mDialog.dismiss();&&&&&&&&&&&&&&mDialog=&&&&&&&&&&}&&&&&&}&&&&&&&public&Intent&getFileIntent(File&file){&&&&&&&&&&Uri&uri&=&Uri.fromFile(file);&&&&&&&&&&String&type&=&getMIMEType(file);&&&&&&&&&&Log.i("tag",&"type="+type);&&&&&&&&&&Intent&intent&=&new&Intent("android.intent.action.VIEW");&&&&&&&&&&intent.addCategory("android.intent.category.DEFAULT");&&&&&&&&&&intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);&&&&&&&&&&intent.setDataAndType(uri,&type);&&&&&&&&&&return&&&&&&&&&}&&&&&&&&&&&&&public&void&writeToSDCard(String&fileName,InputStream&input){&&&&&&&&&&&&&&&&&&&&if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){&&&&&&&&&&&&&&File&directory=Environment.getExternalStorageDirectory();&&&&&&&&&&&&&&File&file=new&File(directory,fileName);&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&FileOutputStream&fos&=&new&FileOutputStream(file);&&&&&&&&&&&&&&&&&&byte[]&b&=&new&byte[2048];&&&&&&&&&&&&&&&&&&int&j&=&0;&&&&&&&&&&&&&&&&&&while&((j&=&input.read(b))&!=&-1)&{&&&&&&&&&&&&&&&&&&&&&&fos.write(b,&0,&j);&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&fos.flush();&&&&&&&&&&&&&&&&&&fos.close();&&&&&&&&&&&&&&}&catch&(FileNotFoundException&e)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&&&&&}&catch&(IOException&e)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&&&&&}&&&&&&&&&&}else{&&&&&&&&&&&&&&Log.i("tag",&"NO&SDCard.");&&&&&&&&&&}&&&&&&}&&&&&&&&&&&&private&String&getMIMEType(File&f){&&&&&&&&&&&String&type="";&&&&&&&&&&String&fName=f.getName();&&&&&&&&&&&&&&&&String&end=fName.substring(fName.lastIndexOf(".")+1,fName.length()).toLowerCase();&&&&&&&&&&&&&&&&&&&&&&if(end.equals("pdf")){&&&&&&&&&&&&type&=&"application/pdf";&&&&&&}&&&&&&&&else&if(end.equals("m4a")||end.equals("mp3")||end.equals("mid")||&&&&&&&&&&end.equals("xmf")||end.equals("ogg")||end.equals("wav")){&&&&&&&&&&&&type&=&"audio/*";&&&&&&&&&&&}&&&&&&&&&&else&if(end.equals("3gp")||end.equals("mp4")){&&&&&&&&&&&&type&=&"video/*";&&&&&&&&&&}&&&&&&&&&&else&if(end.equals("jpg")||end.equals("gif")||end.equals("png")||&&&&&&&&&&end.equals("jpeg")||end.equals("bmp")){&&&&&&&&&&&&type&=&"image/*";&&&&&&&&&&}&&&&&&&&&&else&if(end.equals("apk")){&&&&&&&&&&&&&/*&android.permission.INSTALL_PACKAGES&*/&&&&&&&&&&&&&type&=&"application/vnd.android.package-archive";&&&&&&&&&}&&&&&&&&else{&&&&&&&&&&type="*/*";&&&&&&&&}&&&&&&&&return&&&&&&&}&&&&/span&&&[java]&view plaincopy&&span&style="font-family:Helvetica,&Tahoma,&Arial,&sans-"&转自:&a&href="/blog/1338645"&/blog/1338645&/a&&&&/span& &WebView实现文件下载功能由源码搜藏网整理,转载请注明出处/jiaocheng/shoujikaifa/9993.html
最新教程周点击榜
微信扫一扫今天看啥 热点:
Android 利用WebViewJavascriptBridge 实现js和java的交互(一),androidjsbridge
& & & 此文出自:http://blog.csdn.net/sk/article/details/ ,skay 博客
& & 按安卓开发目前现状来说,开发者大部分时间还是花在UI的屏幕适配上,使用原生控件开发成本已不是那么理想,鉴于很多项目和ios基于一致的ui界面,至使安卓UI开发成本花费更大的代价,因此目前结合Html5和原生控件是解决UI适配的一种很好的选择,处于APP性能也会用java和native层进行结合。不管是哪种结合,其实原理都差不多,只要按照它的协议来,是很容易的,今天我们仅对于Html和Java层结合,学习下一个新的开源项目--WebViewJavascriptBridge。
& &一 什么是webViewjavascripBridge?
& & & &WebViewJavascriptBridge是移动UIView和Html交互通信的桥梁,用作者的话来说就是实现java(ios为oc)和js的互相调用的桥梁。替代了WebView的自带的JavascriptInterface的接口,使得我们的开发更加灵活和安全。
&二 为什么要用webViewjavascripBridge?
& & 对于安卓开发有一段时间的人来说,知道安卓4.4以前谷歌的webview存在安全漏洞,网站可以通过js注入就可以随便拿到客户端的重要信息,甚至轻而易举的调用本地代码进行流氓行为,谷歌后来发现有此漏洞后,增加了防御措施,如果要是js调用本地代码,开发者必须在代码申明JavascriptInterface,
& &列如在4.0之前我们要使得webView加载js只需如下代码:
&&mWebView.addJavascriptInterface(new JsToJava(), &myjsfunction&);
& & &4.4之后调用需要在调用方法加入加入@JavascriptInterface注解,如果代码无此申明,那么也就无法使得js生效,也就是说这样就可以避免恶意网页利用js对安卓客户端的窃取和攻击。
& & & 但是即使这样,我们很多时候需要在js记载本地代码的时候,要做一些判断和限制,或者有可能也会做些过滤和对用户友好提示,因此JavascriptInterface也就无法满足我们的需求了,特此有大神就写出了WebViewJavascriptBridge框架。
三 怎么使用webViewjavascripBridge
& & & 1 将jsBridge.jar引入到我们的工程
& & & & &此jar,或者jar源码我们可以到gitHub上下载。
& & & 2 WebView包需使用以上包的webView
& & & & & & & Layout中使用第三方view,
& & & & & & & EG:
& & & & & & &&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
android:orientation=&vertical& &
&!-- button 演示Java调用web --&
android:id=&@+id/button&
android:layout_width=&match_parent&
android:text=&@string/button_name&
android:layout_height=&48dp&
&!-- webview 演示web调用Java --&
&com.github.lzyzsd.jsbridge.BridgeWebView
android:id=&@+id/webView&
android:layout_width=&match_parent&
android:layout_height=&match_parent& &
&/com.github.lzyzsd.jsbridge.BridgeWebView&
&/LinearLayout&
& 3 Java代码
& & &&public class MainActivity extends Activity implements OnClickListener {
private final String TAG = &MainActivity&;
BridgeWebView webV
int RESULT_CODE = 0;
ValueCallback&Uri& mUploadM
static class Location {
static class User {
String testS
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (BridgeWebView) findViewById(R.id.webView);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
webView.setDefaultHandler(new DefaultHandler());
webView.setWebChromeClient(new WebChromeClient() {
@SuppressWarnings(&unused&)
public void openFileChooser(ValueCallback&Uri& uploadMsg, String AcceptType, String capture) {
this.openFileChooser(uploadMsg);
@SuppressWarnings(&unused&)
public void openFileChooser(ValueCallback&Uri& uploadMsg, String AcceptType) {
this.openFileChooser(uploadMsg);
public void openFileChooser(ValueCallback&Uri& uploadMsg) {
mUploadMessage = uploadM
pickFile();
//加载本地网页
//webView.loadUrl(&file:///android_asset/demo.html&);
//加载服务器网页
webView.loadUrl(&&);
//必须和js同名函数,注册具体执行函数,类似java实现类。
webView.registerHandler(&submitFromWeb&, new BridgeHandler() {
public void handler(String data, CallBackFunction function) {
String str =&这是html返回给java的数据:& +
// 例如你可以对原始数据进行处理
makeText(MainActivity.this, str, LENGTH_SHORT).show();
Log.i(TAG, &handler = submitFromWeb, data from web = & + data);
function.onCallBack( str + &,Java经过处理后截取了一部分:&+ str.substring(0,5));
//模拟用户获取本地位置
User user = new User();
Location location = new Location();
location.address = &上海&;
user.location =
user.name = &Bruce&;
webView.callHandler(&functionInJs&, new Gson().toJson(user), new CallBackFunction() {
public void onCallBack(String data) {
makeText(MainActivity.this, &网页在获取你的位置&, LENGTH_SHORT).show();
webView.send(&hello&);
public void pickFile() {
Intent chooserIntent = new Intent(Intent.ACTION_GET_CONTENT);
chooserIntent.setType(&image/*&);
startActivityForResult(chooserIntent, RESULT_CODE);
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == RESULT_CODE) {
if (null == mUploadMessage){
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage =
public void onClick(View v) {
if (button.equals(v)) {
webView.callHandler(&functionInJs&, &data from Java&, new CallBackFunction() {
public void onCallBack(String data) {
// TODO Auto-generated method stub
Log.i(TAG, &reponse data from js & + data);
& & & 通过实例化webView,用法和安卓原生的view没多大区别,设置WebChromClient, 设置加载的html(同样支持网络和本地文件),接着我们需要给web注册和html端约定好的js方法名。代码列举的submitFromweb和js的执行的方法名一致,玩过NDK的JNI调用的朋友也知道必须和c代码之间有个约定,其实js桥和jni有点类似,
通过注册handler来实现回调,Java代码中通过js返回的数据,进行处理后在调用function.onCallback返回给js.这里不做过多解释
//必须和js同名函数,注册具体执行函数,类似java实现类。
webView.registerHandler(&submitFromWeb&, new BridgeHandler() {
public void handler(String data, CallBackFunction function) {
String str =&这是html返回给java的数据:& +
// 例如你可以对原始数据进行处理
makeText(MainActivity.this, str, LENGTH_SHORT).show();
Log.i(TAG, &handler = submitFromWeb, data from web = & + data);
function.onCallBack( str + &,Java经过处理后截取了一部分:&+ str.substring(0,5));
& & &如果是webview刚开始就执行一段Java代码 ,可以通过webView.CallHandler()来实现 。当然我们注册的方法也要和js里面的方法名一致。
& & && webView.callHandler(&functionInJs&, new Gson().toJson(user), new CallBackFunction() {
public void onCallBack(String data) {
makeText(MainActivity.this, &网页在获取你的位置&, LENGTH_SHORT).show();
& 3 Html和js实现
& & & & &html代码如下,效果图
& &&&html&
&meta content=&text/ charset=utf-8& http-equiv=&content-type&&
js调用java
&xmp id=&show&&
&xmp id=&init&&
&input type=&text& id=&text1& value=&用户名(username)& /&
&input type=&text& id=&text2& value=&password& /&
&input type=&button& id=&enter& value=&发消息给Native& onclick=&testClick();&
&input type=&button& id=&enter1& value=&调用Native方法& onclick=&testClick1();&
&input type=&button& id=&enter2& value=&显示html& onclick=&testDiv();& /&
&input type=&file& value=&打开文件&
& && &script&
function testDiv() {
document.getElementById(&show&).innerHTML = document.getElementsByTagName(&html&)[0].innerHTML;
function testClick() {
var str1 = document.getElementById(&text1&).
var str2 = document.getElementById(&text2&).
//发送消息给java代码
var data = &name=& + str1 + &,pass=& + str2;
window.WebViewJavascriptBridge.send(
, function(responseData) {
document.getElementById(&show&).innerHTML = &repsonseData from java, data = & +responseData
function testClick1() {
var str1 = document.getElementById(&text1&).
var str2 = document.getElementById(&text2&).
//调用本地java方法
window.WebViewJavascriptBridge.callHandler(
'submitFromWeb'
, {'param': str1}
, function(responseData) {
document.getElementById(&show&).innerHTML = &send get responseData from java, data = & + responseData
function bridgeLog(logContent) {
document.getElementById(&show&).innerHTML = logC
}//注册事件监听
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
//注册回调函数,初始化函数
connectWebViewJavascriptBridge(function(bridge) {
bridge.init(function(message, responseCallback) {
console.log('JS got a message', message);
var data = {
'Javascript Responds': 'Wee!'
console.log('JS responding with', data);
responseCallback(data);
bridge.registerHandler(&functionInJs&, function(data, responseCallback) {
document.getElementById(&show&).innerHTML = (&data from Java: = & + data);
var responseData = &Javascript Says Right back aka!&;
responseCallback(responseData);
& & & 这段代码不难理解,我们对上面的id为enter的Button注册了一个点击事件,点击后执行以下testClick()方法,依次类推,其他Button注册事件相同,
& & &当点击“发消息给Native”的按钮时,Js通过webWiew的jsBridage.send()发送一条数据给java层(密码和用户名),同时在此用function()来执行应java层回调函数的。此demo中是把java返回的数据插入到&show&的div里面去。
testClick1():此方法中调用callHandler来调用Java代码的submitFromweb同名函数,可以结合上面的Activty的代码理解下,此函数调用我们已在java注册实现好的
//必须和js同名函数,注册具体执行函数,类似java实现类。
webView.registerHandler(&submitFromWeb&, new BridgeHandler() {
public void handler(String data, CallBackFunction function) {
String str =&这是html返回给java的数据:& +
// 例如你可以对原始数据进行处理
makeText(MainActivity.this, str, LENGTH_SHORT).show();
Log.i(TAG, &handler = submitFromWeb, data from web = & + data);
function.onCallBack( str + &,Java经过处理后截取了一部分:&+ str.substring(0,5));
& & &java注册Js函数如上面列子 ,那么在js中注册方法来注册呢,
& & 在js中我们同样可以直接注册一个回调函数,通过&bridge.registerHandler()来注册,接着调用&responseCallback(responseData)来返回数据给java代码的同名函数。f
也可以直接调用init()来指定网页首次加载上面注册java代码。
connectWebViewJavascriptBridge(function(bridge) {
bridge.init(function(message, responseCallback) {
console.log('JS got a message', message);
var data = {
'Javascript Responds': 'Wee!'
console.log('JS responding with', data);
responseCallback(data);
bridge.registerHandler(&functionInJs&, function(data, responseCallback) {
document.getElementById(&show&).innerHTML = (&data from Java: = & + data);
var responseData = &Javascript Says Right back aka!&;
responseCallback(responseData);
& & &通过以上的代码示例,不难发现此框架的优雅和简便,对js和java双方来说,如果html中的js需要调用java代码,而java代码没做任何实现,那么这个js也是无效的,反之java代码注册的回调函数,没在js里去实现,那么Java也无法获取js远程数据,由此可见此,此通信是双方的,必须由双发来约定,这样就避免了安卓之前存在js注入漏洞,也很大的提高了安全性,也可以保证我们的网页数据不被第三方的APP获取,怎么说呢,比如你的项目某一html界面,被安卓浏览器或者其他第三方App恶意加载你们的网站或网页,那么它的java代码调用你的js函数,比如由你的Js事先注册或者实现,不然跟本无法调用。这样就保证了这个html的唯一性,第三方可以加载预览你的网页,但是第三方java不能和你的js交互通信。同样加载第三方的网页时候,我们可以对第三方网页进行一些行为的过滤,进而对用户进行友好提示。
& & 以上代码只是此开源框架一部分功能,还有很多的功能需要我们去挖掘,以后再给大家解剖下此开源项目的内部实现。欢迎阅读
项目开源地址:/lzyzsd/JsBridge
版权声明:本文为博主原创文章,请尊重原创,转载请标明地址。
暂无相关文章
相关搜索:
相关阅读:
相关频道:
Android教程最近更新}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信