<WebView android:id="@+id/webView1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="10dp" />同时,因为要房访问网络,所以manifest中必须要加uses-permission:
webview = (WebView) findViewById(R.id.webView1);webview.loadUrl("http://www.baidu.com/");//webview.reload();// reload page这个时候发现一个问题,启动应用后,自动的打开了系统内置的浏览器,解决这个问题需要为webview设置 WebViewClient,并重写方法:
webview.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } });若自己定义了一个页面加载进度的progressbar,需要展示给用户的时候,可以通过如下方式获取webview内页面的加载进度:webview.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { //get the newProgress and refresh progress bar } });每个页面,都有一个标题,比如www.baidu.com这个页面的title即“百度一下,你就知道”,那么如何知道当前webview正在加载的页面的title呢:webview.setWebChromeClient(new WebChromeClient(){ @Override public void onReceivedTitle(WebView view, String title) { titleview.setText(title);//a textview } });二、通过webview控件下载文件public class HttpThread extends Thread { private String mUrl; public HttpThread(String mUrl) { this.mUrl = mUrl; }@Override public void run() { URL url; try { url = new URL(mUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); InputStream in = conn.getInputStream();File downloadFile; File sdFile; FileOutputStream out = null; if(Environment.getExternalStorageState().equals(Environment.MEDIA_UNMOUNTED)){ downloadFile = Environment.getExternalStorageDirectory(); sdFile = new File(downloadFile, "test.file"); out = new FileOutputStream(sdFile); }//buffer 4k byte[] buffer = new byte[1024 * 4]; int len = 0; while((len = in.read(buffer)) != -1){ if(out != null) out.write(buffer, 0, len); }//close resource if(out != null) out.close();if(in != null){ in.close(); }} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }随后要实现一个DownloadListener接口,这个接口实现方法OnDownloadStart(),当用户点击一个可以下载的链接时,该回调方法被调用同时传进来该链接的URL,随后即可以对该URL塞入HttpThread进行下载操作://创建DownloadListener (webkit包)class MyDownloadListenter implements DownloadListener{ @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { System.out.println("url ==== >" + url); new HttpThread(url).start(); }}//给webview加入监听webview.setDownloadListener(new MyDownloadListenter());方法二:class MyDownloadListenter implements DownloadListener{ @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { System.out.println("url ==== >" + url); //new HttpThread(url).start();Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); }}三、错误处理webview.setWebViewClient(new WebViewClient(){@Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { switch(errorCode) { case HttpStatus.SC_NOT_FOUND: view.loadUrl("file:///android_assets/error_handle.html"); break; } } });其实,当出错的时候,我们可以选择隐藏掉webview,而显示native的错误处理控件,这个时候只需要在onReceivedError里面显示出错误处理的native控件同时隐藏掉webview即可。public class HttpCookie extends Thread { private Handler mHandler; public HttpCookie(Handler mHandler) { this.mHandler = mHandler; }@Override public void run() { HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("");//this place should add the login addressList<NameValuePair> list = new ArrayList<NameValuePair>(); list.add(new BasicNameValuePair("name", "jason")); list.add(new BasicNameValuePair("pwd", "123456"));try { post.setEntity(new UrlEncodedFormEntity(list)); HttpResponse reponse = client.execute(post); if(reponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ AbstractHttpClient absClient = (AbstractHttpClient) client; List<Cookie> cookies = absClient.getCookieStore().getCookies();for(Cookie cookie:cookies){ if(cookie != null){ //TODO //this place would get the cookies } } }} catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }由于这是一个子线程,所以需要在主线程中创建并执行。if(cookie != null){ //TODO //this place would get the cookies Message msg = new Message(); msg.obj = cookie; if(mHandler != null){ mHandler.sendMessage(msg); return; }}随后在主线程中(webview加载登陆界面前),在handler中将会获取到cookie信息,下面将对该cookie进行保存和同步: private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg){CookieSyncManager.createInstance(MainActivity.this); CookieManager cookieMgr = CookieManager.getInstance(); cookieMgr.setAcceptCookie(true); cookieMgr.setCookie("", msg.obj.toString());// this place should add the login host address(not the login index address) CookieSyncManager.getInstance().sync();webview.loadUrl("");// login index address }; };这个时候发现webview加载的login index页面中可以自动的登陆了并显示登陆后的界面。 <html> <script language="javascript"> /* This function is invoked by the webview*/ function do() { alert("1"); } </script> <body> <a onClick="window.demo.clickOnAndroid()"><div style="width:80px; margin:0px auto; padding:10px; text-align:center; border:2px solid #111111;" > <img id="droid" src="xx.png"/><br> Click me! </div></a> </body></html>2. js调用webviewpackage com.test.webview;class DemoJavaScriptInterface { DemoJavaScriptInterface() { } /** * This is not called on the UI thread. Post a runnable to invoke * loadUrl on the UI thread. */ public void clickOnAndroid() { mHandler.post(new Runnable() { public void run() { //TODO } }); } }首先给webview设置:
从效果图中可以明显看出本示例的布局:
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><Buttonandroid:id="@+id/btn"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="加载URL"/> <WebViewandroid:id="@+id/webview"android:layout_width="match_parent"android:layout_height="match_parent"/> </LinearLayout>对应的处理代码如下
public class MyActivity extends Activity { private WebView mWebView;private Button mBtn;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main); mWebView = (WebView)findViewById(R.id.webview);mBtn = (Button)findViewById(R.id.btn); mBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mWebView.loadUrl("http://www.baidu.com");}});} } 代码很简单,就是在点击按钮的时候加载网址,但需要注意的是:网址必须完整即以http://或者ftp://等协议开头,不能省略!不然将加载不出来,这是因为webview是没有自动补全协议功能的,所以如果我们不加,它将识别不出来网址类型,也就加载不出来了。 
如果我们想实现像示例一样在webview中打开网址需要怎么做呢?
我们需要设置WebViewClient:
修改后的代码为:
public class MyActivity extends Activity { private WebView mWebView;private Button mBtn;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main); mWebView = (WebView)findViewById(R.id.webview);mBtn = (Button)findViewById(R.id.btn); mWebView.setWebViewClient(new WebViewClient()); mBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mWebView.loadUrl("http://www.baidu.com");}});} } 在上面的基础上,我们添加了下面一段代码:<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><h1>欢迎光临启舰的blog</h1> </head> <body> </body> </html>即大标题显示一段文字
public class MyActivity extends Activity { private WebView mWebView;private Button mBtn;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main); mWebView = (WebView)findViewById(R.id.webview);mBtn = (Button)findViewById(R.id.btn); mBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mWebView.loadUrl("file:///android_asset/web.html");}});} } 从这里可以看到与加载在线URL有两点不同: 
所以对于加载URL的总结就是:
1、如果是在线网址记得添加网络访问权限
2、在线网址中,如果要使用webview打开,记得设置WebViewClient
3、打开本地html文件时,是不需要设置WebViewClient,对应的asstes目录的url为:file:///android_asset/xxxxx
3、WebView基本设置
如果我们需要设置WebView的属性,是通过WebView.getSettings()获取设置WebView的WebSettings对象,然后调用WebSettings中的方法来实现的。
WebSettings的方法及说明如下:(这里先列出来所有的方法及解释,大家可以先忽略,看后面的举例中所使用的几个常用方法即可,用到哪个函数的时候再回来查查就可以了)
/*** 是否支持缩放,配合方法setBuiltInZoomControls使用,默认true*/ setSupportZoom(boolean support)/*** 是否需要用户手势来播放Media,默认true*/ setMediaPlaybackRequiresUserGesture(boolean require)/*** 是否使用WebView内置的缩放组件,由浮动在窗口上的缩放控制和手势缩放控制组成,默认false*/ setBuiltInZoomControls(boolean enabled)/*** 是否显示窗口悬浮的缩放控制,默认true*/ setDisplayZoomControls(boolean enabled)/*** 是否允许访问WebView内部文件,默认true*/ setAllowFileAccess(boolean allow)/*** 是否允许获取WebView的内容URL ,可以让WebView访问ContentPrivider存储的内容。 默认true*/ setAllowContentAccess(boolean allow)/*** 是否启动概述模式浏览界面,当页面宽度超过WebView显示宽度时,缩小页面适应WebView。默认false*/ setLoadWithOverviewMode(boolean overview)/*** 是否保存表单数据,默认false*/ setSaveFormData(boolean save)/*** 设置页面文字缩放百分比,默认100%*/ setTextZoom(int textZoom)/*** 是否支持ViewPort的meta tag属性,如果页面有ViewPort meta tag 指定的宽度,则使用meta tag指定的值,否则默认使用宽屏的视图窗口*/ setUseWideViewPort(boolean use) /*** 是否支持多窗口,如果设置为true ,WebChromeClient#onCreateWindow方法必须被主程序实现,默认false*/ setSupportMultipleWindows(boolean support)/*** 指定WebView的页面布局显示形式,调用该方法会引起页面重绘。默认LayoutAlgorithm#NARROW_COLUMNS*/ setLayoutAlgorithm(LayoutAlgorithm l)/*** 设置标准的字体族,默认”sans-serif”。font-family 规定元素的字体系列。* font-family 可以把多个字体名称作为一个“回退”系统来保存。如果浏览器不支持第一个字体,* 则会尝试下一个。也就是说,font-family 属性的值是用于某个元素的字体族名称或/及类族名称的一个* 优先表。浏览器会使用它可识别的第一个值。*/ setStandardFontFamily(String font)/*** 设置混合字体族。默认”monospace”*/ setFixedFontFamily(String font)/*** 设置SansSerif字体族。默认”sans-serif”*/ setSansSerifFontFamily(String font)/*** 设置SerifFont字体族,默认”sans-serif”*/ setSerifFontFamily(String font)/*** 设置CursiveFont字体族,默认”cursive”*/ setCursiveFontFamily(String font)/*** 设置FantasyFont字体族,默认”fantasy”*/ setFantasyFontFamily(String font)/*** 设置最小字体,默认8. 取值区间[1-72],超过范围,使用其上限值。*/ setMinimumFontSize(int size)/*** 设置最小逻辑字体,默认8. 取值区间[1-72],超过范围,使用其上限值。*/ setMinimumLogicalFontSize(int size)/*** 设置默认字体大小,默认16,取值区间[1-72],超过范围,使用其上限值。*/ setDefaultFontSize(int size)/*** 设置默认填充字体大小,默认16,取值区间[1-72],超过范围,使用其上限值。*/ setDefaultFixedFontSize(int size)/*** 设置是否加载图片资源,注意:方法控制所有的资源图片显示,包括嵌入的本地图片资源。* 使用方法setBlockNetworkImage则只限制网络资源图片的显示。值设置为true后,* webview会自动加载网络图片。默认true*/ setLoadsImagesAutomatically(boolean flag)/*** 是否加载网络图片资源。注意如果getLoadsImagesAutomatically返回false,则该方法没有效果。* 如果使用setBlockNetworkLoads设置为false,该方法设置为false,也不会显示网络图片。* 当值从true改为false时。WebView会自动加载网络图片。*/ setBlockNetworkImage(boolean flag)/*** 设置是否加载网络资源。注意如果值从true切换为false后,WebView不会自动加载,* 除非调用WebView#reload().如果没有android.Manifest.permission#INTERNET权限,* 值设为false,则会抛出java.lang.SecurityException异常。* 默认值:有android.Manifest.permission#INTERNET权限时为false,其他为true。*/ setBlockNetworkLoads(boolean flag)/*** 设置是否允许执行JS。*/ setJavaScriptEnabled(boolean flag)/*** 是否允许Js访问任何来源的内容。包括访问file scheme的URLs。考虑到安全性,* 限制Js访问范围默认禁用。注意:该方法只影响file scheme类型的资源,其他类型资源如图片类型的,* 不会受到影响。ICE_CREAM_SANDWICH_MR1版本以及以下默认为true,JELLY_BEAN版本* 以上默认为false*/ setAllowUniversalAccessFromFileURLs(boolean flag) /*** 是否允许Js访问其他file scheme的URLs。包括访问file scheme的资源。考虑到安全性,* 限制Js访问范围默认禁用。注意:该方法只影响file scheme类型的资源,其他类型资源如图片类型的,* 不会受到影响。如果getAllowUniversalAccessFromFileURLs为true,则该方法被忽略。* ICE_CREAM_SANDWICH_MR1版本以及以下默认为true,JELLY_BEAN版本以上默认为false*/ setAllowFileAccessFromFileURLs(boolean flag)/*** 设置存储定位数据库的位置,考虑到位置权限和持久化Cache缓存,Application需要拥有指定路径的* write权限*/ setGeolocationDatabasePath(String databasePath)/*** 是否允许Cache,默认false。考虑需要存储缓存,应该为缓存指定存储路径setAppCachePath*/ setAppCacheEnabled(boolean flag)/*** 设置Cache API缓存路径。为了保证可以访问Cache,Application需要拥有指定路径的write权限。* 该方法应该只调用一次,多次调用自动忽略。*/ setAppCachePath(String appCachePath)/*** 是否允许数据库存储。默认false。查看setDatabasePath API 如何正确设置数据库存储。* 该设置拥有全局特性,同一进程所有WebView实例共用同一配置。注意:保证在同一进程的任一WebView* 加载页面之前修改该属性,因为在这之后设置WebView可能会忽略该配置*/ setDatabaseEnabled(boolean flag)/*** 是否存储页面DOM结构,默认false。*/ setDomStorageEnabled(boolean flag)/*** 是否允许定位,默认true。注意:为了保证定位可以使用,要保证以下几点:* Application 需要有android.Manifest.permission#ACCESS_COARSE_LOCATION的权限* Application 需要实现WebChromeClient#onGeolocationPermissionsShowPrompt的回调,* 接收Js定位请求访问地理位置的通知*/ setGeolocationEnabled(boolean flag)/*** 是否允许JS自动打开窗口。默认false*/ setJavaScriptCanOpenWindowsAutomatically(boolean flag)/*** 设置页面的编码格式,默认UTF-8*/ setDefaultTextEncodingName(String encoding)/*** 设置WebView代理,默认使用默认值*/ setUserAgentString(String ua)/*** 通知WebView是否需要设置一个节点获取焦点当* WebView#requestFocus(int,android.graphics.Rect)被调用的时候,默认true*/ setNeedInitialFocus(boolean flag)/*** 基于WebView导航的类型使用缓存:正常页面加载会加载缓存并按需判断内容是否需要重新验证。* 如果是页面返回,页面内容不会重新加载,直接从缓存中恢复。setCacheMode允许客户端根据指定的模式来* 使用缓存。* LOAD_DEFAULT 默认加载方式* LOAD_CACHE_ELSE_NETWORK 按网络情况使用缓存* LOAD_NO_CACHE 不使用缓存* LOAD_CACHE_ONLY 只使用缓存*/ setCacheMode(int mode)/*** 设置加载不安全资源的WebView加载行为。KITKAT版本以及以下默认为MIXED_CONTENT_ALWAYS_ALLOW方* 式,LOLLIPOP默认MIXED_CONTENT_NEVER_ALLOW。强烈建议:使用MIXED_CONTENT_NEVER_ALLOW*/ setMixedContentMode(int mode)下面我们就举个例子来看下用法
public class MyActivity extends Activity { private WebView mWebView;private Button mBtn; @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.webview);mBtn = (Button) findViewById(R.id.btn); WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);} } 示例2:设置缓存WebSettings webSettings = mWebView .getSettings(); webSettings.setUseWideViewPort(true);//设置此属性,可任意比例缩放 webSettings.setLoadWithOverviewMode(true);效果图如下:

示例4:使页面支持缩放:
WebSettings webSettings = mWebView.getSettings(); //开启javascript支持 webSettings.setJavaScriptEnabled(true); // 设置可以支持缩放 webSettings.setSupportZoom(true); // 设置出现缩放工具 webSettings.setBuiltInZoomControls(true);示例5:.如果webView中需要用户手动输入用户名、密码或其他,则webview必须设置支持获取手势焦点

在原来html上面添加了一个按钮,当点击按钮时调用Android的Toast函数弹出一个toast消息。
先看Android代码:
public class MyActivity extends Activity { private WebView mWebView;private Button mBtn; @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);mWebView.addJavascriptInterface(this, "android");mWebView.loadUrl("file:///android_asset/web.html");} public void toastMessage(String message) {Toast.makeText(getApplicationContext(), "通过Natvie传递的Toast:"+message, Toast.LENGTH_LONG).show();} } 这里最主要是的下面这句:<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><h1>欢迎光临启舰的blog</h1><input type="button" value="js调native" onclick="ok()"> </head> <body> <script type="text/javascript"> function ok() {android.toastMessage("哈哈,i m webview msg"); } </script> </body> </html> 在这个html中,我添加了一个button按钮,当点击时调用ok函数:function ok() {android.toastMessage("哈哈,i m webview msg"); } 它的意义就是调用android对象里的toastMessage方法,这个android就是我们利用mWebView.addJavascriptInterface(this, “android”)注入到WebView的android,它所对应的对象就将MyActivity;所以在JS中,我们就可以通过android这个别名来调用MyActivity对象中的任何public方法。 public class MyActivity extends Activity { private WebView mWebView;private Button mBtn; @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.webview);mBtn = (Button) findViewById(R.id.btn); WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);mWebView.addJavascriptInterface(new JSBridge(), "android");mWebView.loadUrl("file:///android_asset/web.html");} public class JSBridge{public void toastMessage(String message) {Toast.makeText(getApplicationContext(), "通过Natvie传递的Toast:"+message, Toast.LENGTH_LONG).show();}} } 在这段代码中,在通过addJavascriptInterface注入时:
大家可以自己尝试下;
然后对应的html代码:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><h1>欢迎光临启舰的blog</h1><input type="button" value="js调native" onclick="ok()"> </head> <body> <script type="text/javascript"> function ok() {android.toastMessage("哈哈,i m webview msg");} </script> </body> </html> 由于在注入时的对象别名和所调用的函数名都没有变,所以HTML中的JS代码是无需更改的。效果图与上节一样,就不再帖出了。 public class JSBridge {@JavascriptInterfacepublic void toastMessage(String message) {Toast.makeText(getApplicationContext(), "通过Natvie传递的Toast:" + message, Toast.LENGTH_LONG).show();} } 这也就是很多同学在高target上,addJavascriptInterface()函数无效的主要原因。
在点击“加载URL”按钮时,调用webview中的JavaScript求和函数,将结果显示在标题中。
先看html代码:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><h1 id="h">欢迎光临启舰的blog</h1><input type="button" value="js调native" onclick="ok()"> </head> <body> <script type="text/javascript"> function sum(i,m) {document.getElementById("h").innerHTML= (i+m); } </script> </body> </html> 在这里,我们写了一个求和函数sum(i,m) public class MyActivity extends Activity { private WebView mWebView;private Button mBtn; @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.webview);mBtn = (Button) findViewById(R.id.btn); WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);mWebView.loadUrl("file:///android_asset/web.html"); mBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mWebView.loadUrl("javascript:sum(3,8)");}});} } 在点击按钮时调用JS函数:webView.addJavascriptInterface(this, "android"); mWebView.loadUrl("javascript:sum(3,8)");注意,这里通过addJavascriptInterface将MyActiviy所对应的对象注入到WebView中了。
function sum(i,m){var result = i+m;document.getElementById("h").innerHTML= result;android.onSumResult(result) } 3)..Java在回调方法中获取js函数返回值public void onSumResult(int result) {Log.i(LOGTAG, "onSumResult result=" + result); } 先看下效果图:
下面我们就完整地看一下代码:
JS代码:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><h1 id="h">欢迎光临启舰的blog</h1><input type="button" value="js调native" onclick="ok()"> </head> <body> <script type="text/javascript"> function sum(i,m){var result = i+m;document.getElementById("h").innerHTML= result;android.onSumResult(result); } </script> </body> </html> 在function sum(i,m)中,先通过result得到结果,最后通过android.onSumResult(result);将结果传给Native public class MyActivity extends Activity { private WebView mWebView;private Button mBtn; @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main); mWebView = (WebView) findViewById(R.id.webview);mBtn = (Button) findViewById(R.id.btn); WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);mWebView.addJavascriptInterface(this, "android");mWebView.loadUrl("file:///android_asset/web.html"); mBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mWebView.loadUrl("javascript:sum(3,8)"); }});} public void onSumResult(int result) {Toast.makeText(this,"received result:"+result,Toast.LENGTH_SHORT).show();} } 这里主要做了两件事: public void onSumResult(int result) {Toast.makeText(this,"received result:"+result,Toast.LENGTH_SHORT).show(); } 3、JAVA中如何得到JS中的返回值(Android4.4之后)function getGreetings() {return 1; } java代码时用evaluateJavascript方法调用:private void testEvaluateJavascript(WebView webView) {webView.evaluateJavascript("getGreetings()", new ValueCallback() {@Overridepublic void onReceiveValue(String value) { Log.i(LOGTAG, "onReceiveValue value=" + value);}}); } 从上面的用法中很明显看到,通过evaluateJavascript调用JS中的方法,可以向其中添加结果回调,来接收JS的return值。 git clone https://github.com/skylot/jadx.git cd jadx ./gradlew dist其实这里只是做了两个动作:
git clone https://github.com/skylot/jadx.git cd jadx gradlew.bat dist在windows电脑中,步骤与mac是一样的,只是最后一步中,已经不再是./gradlew所对应的shell脚本了,而是windows平台上的bat脚本。

在编译成功后,在jadx目录下,会生成一个build目录,其中包含jadx目录和一个jadx-xxx-dev.zip的打包文件。在build/jadx目录下,就是源码编译出的jadx工具及所用jar包。jadx-xxx-dev.zip解压后的内容与build/jadx内容一样,只是将其打包了一下而已,方便移值,可见作者有多用心。build目录结构如下图所示:

2)、开始反编译
等完毕后,可以开始了,我就介绍个最简单最常用的用法
(1)、把apk改成zip
(2)、解压zip获取class.dex文件
(3)、将class.dex文件放到jadx目录下
cd build/jadx/ bin/jadx -d out classes.dex # 反编译后放入out文件夹下(如果out不存在它会自动创建) #or bin/jadx-gui classes.dex # 会反编译,并且使用gui打开目录结构图如下:

在使用jadx-gui反编译时,左下角会显示当前反编译的进度:

在反编译完成后,在左侧就可以看到目录结构和对应的代码,目录结构中显示的a,b,c,d这些字母是由于在生成apk时使用proguard混淆造成的,proguard混淆的类名是没办法反编译出对应的原类名的,这也是反编译代码中比较蛋疼的地方,下面给大家演示下结果:(还可以通过点击搜索按钮,搜索其中的代码)

有关jadx-gui工具的更多用法,只有靠大家自己去研究啦,到这里我们的源码就已经反编译出来了。
反编译工具和微信的Classes文件,会在源码中给出大家,源码下载地址:Android WebView使用
原文地址:http://blog.csdn.net/lsyz0021/article/details/51473279
以上就是本文的全部内容,希望对大家的学习有所帮助。