国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android WebView使用方法詳解 附j(luò)s交互調(diào)用方法

2019-12-12 06:21:11
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

目前很多Android app都內(nèi)置了可以顯示web頁(yè)面的界面,會(huì)發(fā)現(xiàn)這個(gè)界面一般都是由一個(gè)叫做WebView的組件渲染出來(lái)的,學(xué)習(xí)該組件可以為你的app開(kāi)發(fā)提升擴(kuò)展性。

先說(shuō)下WebView的一些優(yōu)點(diǎn):

--可以直接顯示和渲染web頁(yè)面,直接顯示網(wǎng)頁(yè)
--webview可以直接用html文件(網(wǎng)絡(luò)上或本地assets中)作布局
--和JavaScript交互調(diào)用
 

一、基本使用

首先layout中即為一個(gè)基本的簡(jiǎn)單控件:

<WebView android:id="@+id/webView1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="10dp" />

同時(shí),因?yàn)橐吭L問(wèn)網(wǎng)絡(luò),所以manifest中必須要加uses-permission:

<uses-permission android:name="android.permission.INTERNET"/>
在activity中即可獲得webview的引用,同時(shí)load一個(gè)網(wǎng)址:

webview = (WebView) findViewById(R.id.webView1);webview.loadUrl("http://www.baidu.com/");//webview.reload();// reload page

這個(gè)時(shí)候發(fā)現(xiàn)一個(gè)問(wèn)題,啟動(dòng)應(yīng)用后,自動(dòng)的打開(kāi)了系統(tǒng)內(nèi)置的瀏覽器,解決這個(gè)問(wèn)題需要為webview設(shè)置 WebViewClient,并重寫方法:

webview.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } });

若自己定義了一個(gè)頁(yè)面加載進(jìn)度的progressbar,需要展示給用戶的時(shí)候,可以通過(guò)如下方式獲取webview內(nèi)頁(yè)面的加載進(jìn)度:

webview.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { //get the newProgress and refresh progress bar } });

每個(gè)頁(yè)面,都有一個(gè)標(biāo)題,比如www.baidu.com這個(gè)頁(yè)面的title即“百度一下,你就知道”,那么如何知道當(dāng)前webview正在加載的頁(yè)面的title呢:

webview.setWebChromeClient(new WebChromeClient(){ @Override public void onReceivedTitle(WebView view, String title) { titleview.setText(title);//a textview } });

二、通過(guò)webview控件下載文件

通常webview渲染的界面中含有可以下載文件的鏈接,點(diǎn)擊該鏈接后,應(yīng)該開(kāi)始執(zhí)行下載的操作并保存文件到本地中。webview來(lái)下載頁(yè)面中的文件通常有兩種方式:

1. 自己通過(guò)一個(gè)線程寫java io的代碼來(lái)下載和保存文件(可控性好)

2. 調(diào)用系統(tǒng)download的模塊(代碼簡(jiǎn)單)

 方法一:

首先要寫一個(gè)下載并保存文件的線程類

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(); } } }

隨后要實(shí)現(xiàn)一個(gè)DownloadListener接口,這個(gè)接口實(shí)現(xiàn)方法OnDownloadStart(),當(dāng)用戶點(diǎn)擊一個(gè)可以下載的鏈接時(shí),該回調(diào)方法被調(diào)用同時(shí)傳進(jìn)來(lái)該鏈接的URL,隨后即可以對(duì)該URL塞入HttpThread進(jìn)行下載操作:

//創(chuàng)建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加入監(jiān)聽(tīng)webview.setDownloadListener(new MyDownloadListenter());

方法二:

直接發(fā)送一個(gè)action_view的intent即可:

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); }  }

三、錯(cuò)誤處理

當(dāng)我們使用瀏覽器的時(shí)候,通常因?yàn)榧虞d的頁(yè)面的服務(wù)器的各種原因?qū)е赂鞣N出錯(cuò)的情況,最平常的比如404錯(cuò)誤,通常情況下瀏覽器會(huì)提示一個(gè)錯(cuò)誤提示頁(yè)面。事實(shí)上這個(gè)錯(cuò)誤提示頁(yè)面是瀏覽器在加載了本地的一個(gè)頁(yè)面,用來(lái)提示用戶目前已經(jīng)出錯(cuò)了。

但是當(dāng)我們的app里面使用webview控件的時(shí)候遇到了諸如404這類的錯(cuò)誤的時(shí)候,若也顯示瀏覽器里面的那種錯(cuò)誤提示頁(yè)面就顯得很丑陋了,那么這個(gè)時(shí)候我們的app就需要加載一個(gè)本地的錯(cuò)誤提示頁(yè)面,即webview如何加載一個(gè)本地的頁(yè)面。

1. 首先我們需要些一個(gè)html文件,比如error_handle.html,這個(gè)文件里面就是當(dāng)出錯(cuò)的時(shí)候需要展示給用戶看的一個(gè)錯(cuò)誤提示頁(yè)面,盡量做的精美一些。然后將該文件放置到代碼根目錄的assets文件夾下。

2. 隨后我們需要復(fù)寫WebViewClient的onRecievedError方法,該方法傳回了錯(cuò)誤碼,根據(jù)錯(cuò)誤類型可以進(jìn)行不同的錯(cuò)誤分類處理

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; } } });

其實(shí),當(dāng)出錯(cuò)的時(shí)候,我們可以選擇隱藏掉webview,而顯示native的錯(cuò)誤處理控件,這個(gè)時(shí)候只需要在onReceivedError里面顯示出錯(cuò)誤處理的native控件同時(shí)隱藏掉webview即可。

四、webview同步cookies

cookies是服務(wù)器用來(lái)保存每個(gè)客戶的常用信息的,下次客戶進(jìn)入一個(gè)諸如登陸的頁(yè)面時(shí)服務(wù)器會(huì)檢測(cè)cookie信息,如果通過(guò)則直接進(jìn)入登陸后的頁(yè)面。

在webview中,如果之前已經(jīng)登陸過(guò)了,那么下次再進(jìn)入同樣的登陸界面時(shí),若需要再次登陸的話,一定會(huì)很惱人,所以這里提供一個(gè)webview同步cookies的方法。 

1.首先,我們假設(shè)某個(gè)網(wǎng)站的登陸界面需要提供兩個(gè)參數(shù),一個(gè)是name,一個(gè)是pwd,那么要是對(duì)這個(gè)頁(yè)面進(jìn)行登陸,那么必須給與這兩個(gè)信息。我們假設(shè)服務(wù)器已經(jīng)注冊(cè)了name為jason,pwd為123456這個(gè)賬號(hào)。

2.下面,寫一個(gè)Thread用來(lái)將name和pwd自動(dòng)的登入,在服務(wù)器返回的response中獲得cookie信息,稍后對(duì)這個(gè)cookie進(jìn)行保存,這里先給出這個(gè)Thread的代碼:

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 address  List<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(); } } }

由于這是一個(gè)子線程,所以需要在主線程中創(chuàng)建并執(zhí)行。

同時(shí),因?yàn)槠鋵?shí)子線程,那么里面必須含有一個(gè)handler的元素,用來(lái)當(dāng)成功獲取cookie后通知主線程進(jìn)行同步和保存。初始化這個(gè)子線程的時(shí)候需要將主線程上的handler給傳過(guò)來(lái),隨后在以上代碼的TODO中發(fā)送消息,讓主線程記錄cookie,發(fā)送的這個(gè)消息需要將cookie信息包含進(jìn)去:

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中將會(huì)獲取到cookie信息,下面將對(duì)該cookie進(jìn)行保存和同步:

 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 }; };

這個(gè)時(shí)候發(fā)現(xiàn)webview加載的login index頁(yè)面中可以自動(dòng)的登陸了并顯示登陸后的界面。 

五、 WebView與JavaScript的交互

1. webview調(diào)用js

mWebView.loadUrl("javascript:do()");
以上是webview在調(diào)用js中的一個(gè)叫做do的方法,該js所在的html文件大致如下:

<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調(diào)用webview

我們假設(shè)下列的本地類是要給js調(diào)用的:

package 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設(shè)置:

mWebview.setJavaScriptEnabled(true);
隨后將本地的類(被js調(diào)用的)映射出去:

mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
“demo”這個(gè)名字就是公布出去給JS調(diào)用的,那么js久可以直接用下列代碼調(diào)用本地的DemoJavaScriptInterface類中的方法了:

<body onload="javascript:demo.clickOnAndroid()"> 
    ...
</body> 

六、WebView與JavaScript相互調(diào)用混淆問(wèn)題

若webview中的js調(diào)用了本地的方法,正常情況下發(fā)布的debug包js調(diào)用的時(shí)候是沒(méi)有問(wèn)題的,但是通常發(fā)布商業(yè)版本的apk都是要經(jīng)過(guò)混淆的步驟,這個(gè)時(shí)候會(huì)發(fā)現(xiàn)之前調(diào)用正常的js卻無(wú)法正常調(diào)用本地方法了。

這是因?yàn)榛煜臅r(shí)候已經(jīng)把本地的代碼的引用給打亂了,導(dǎo)致js中的代碼找不到本地的方法的地址。

解決這個(gè)問(wèn)題很簡(jiǎn)單,即在proguard.cfg文件中加上一些代碼,聲明本地中被js調(diào)用的代碼不被混淆。下面舉例說(shuō)明:

第五節(jié)中被js調(diào)用的那個(gè)類DemoJavaScriptInterface的包名為com.test.webview,那么就要在proguard.cfg文件中加入:

-keep public class com.test.webview.DemoJavaScriptInterface{
    public <methods>;
}
若是內(nèi)部類,則大致寫成如下形式:

-keep public class com.test.webview.DemoJavaScriptInterface$InnerClass{
    public <methods>;
}
若android版本比較新,可能還需要添加上下列代碼:

-keepattributes *Annotation* 
-keepattributes *JavascriptInterface*

另一種講解:

一、基本用法
1、加載在線URL
void loadUrl(String url) 
這個(gè)函數(shù)主要加載url所對(duì)應(yīng)的網(wǎng)頁(yè)地址,或者用于調(diào)用網(wǎng)頁(yè)中的指定的JS方法(調(diào)用js方法的用法,后面會(huì)講),但有一點(diǎn)必須注意的是:loadUrl()必須在主線程中執(zhí)行!!!否則就會(huì)報(bào)錯(cuò)!!!。
注意:加載在線網(wǎng)頁(yè)地址是會(huì)用到聯(lián)網(wǎng)permission權(quán)限的,所以需要在AndroidManifest.xml中寫入下面代碼申請(qǐng)權(quán)限:
<uses-permission android:name="android.permission.INTERNET" /> 
本示例效果為:

從效果圖中可以明顯看出本示例的布局:
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"  >  <Button  android:id="@+id/btn"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:text="加載URL"/>   <WebView  android:id="@+id/webview"  android:layout_width="match_parent"  android:layout_height="match_parent"/> </LinearLayout> 

對(duì)應(yīng)的處理代碼如下

public class MyActivity extends Activity {   private WebView mWebView;  private Button mBtn;  @Override  public 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() {  @Override  public void onClick(View v) {  mWebView.loadUrl("http://www.baidu.com");  }  });  } } 

代碼很簡(jiǎn)單,就是在點(diǎn)擊按鈕的時(shí)候加載網(wǎng)址,但需要注意的是:網(wǎng)址必須完整即以http://或者ftp://等協(xié)議開(kāi)頭,不能省略!不然將加載不出來(lái),這是因?yàn)閣ebview是沒(méi)有自動(dòng)補(bǔ)全協(xié)議功能的,所以如果我們不加,它將識(shí)別不出來(lái)網(wǎng)址類型,也就加載不出來(lái)了。
但如果我們運(yùn)行上面的代碼,效果卻是利用瀏覽器來(lái)打開(kāi)網(wǎng)址,卻不是使用webview打開(kāi)網(wǎng)址:

如果我們想實(shí)現(xiàn)像示例一樣在webview中打開(kāi)網(wǎng)址需要怎么做呢?
我們需要設(shè)置WebViewClient:
修改后的代碼為:

public class MyActivity extends Activity {   private WebView mWebView;  private Button mBtn;  @Override  public 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() {  @Override  public void onClick(View v) {  mWebView.loadUrl("http://www.baidu.com");  }  });  } } 

在上面的基礎(chǔ)上,我們添加了下面一段代碼:
mWebView.setWebViewClient(new WebViewClient()); 
在這里我們利用mWebView.setWebViewClient()函數(shù)僅僅設(shè)置了一個(gè)WebViewClient實(shí)例,就可以實(shí)現(xiàn)在WebView中打開(kāi)鏈接了,至于原因我們下篇會(huì)講到,這里就先忽略了,大家只需要知道要在WebView中打開(kāi)鏈接,就必須要設(shè)置WebViewClient;
最終的效果圖就與開(kāi)篇時(shí)一樣的了,這里就不再帖效果圖了,下面我們來(lái)看看如何加載本地html網(wǎng)頁(yè)。

2、加載本地URL
一般而言,我們會(huì)將本地html文件放在assets文件夾下,比如:

web.html的內(nèi)容為:

<!DOCTYPE html> <html lang="en"> <head>  <meta charset="UTF-8">  <title>Title</title>  <h1>歡迎光臨啟艦的blog</h1> </head> <body> </body> </html> 

即大標(biāo)題顯示一段文字
我們同樣在上面的示例的基礎(chǔ)上加以改造,在點(diǎn)擊按鈕的時(shí)候加載本地web.html文件

public class MyActivity extends Activity {   private WebView mWebView;  private Button mBtn;  @Override  public 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() {  @Override  public void onClick(View v) {  mWebView.loadUrl("file:///android_asset/web.html");  }  });  } } 

從這里可以看到與加載在線URL有兩點(diǎn)不同:
1)、URL類型不一樣
在加載本地URL時(shí),是以“file:///”開(kāi)頭的,而assets目錄所對(duì)應(yīng)的路徑名為anroid_asset,寫成其它的將識(shí)別不了,這是assets目錄的以file開(kāi)頭的url形式的固定訪問(wèn)形式。
2)、不需要設(shè)置WebViewClient
這里很明顯沒(méi)有設(shè)置WebViewClient函數(shù),但仍然是在webview中打開(kāi)的本地文件。具體原因下篇文章講到WebViewClient時(shí)我們會(huì)具體解釋。
本例效果圖如下:

所以對(duì)于加載URL的總結(jié)就是:
1、如果是在線網(wǎng)址記得添加網(wǎng)絡(luò)訪問(wèn)權(quán)限
2、在線網(wǎng)址中,如果要使用webview打開(kāi),記得設(shè)置WebViewClient
3、打開(kāi)本地html文件時(shí),是不需要設(shè)置WebViewClient,對(duì)應(yīng)的asstes目錄的url為:file:///android_asset/xxxxx
3、WebView基本設(shè)置
如果我們需要設(shè)置WebView的屬性,是通過(guò)WebView.getSettings()獲取設(shè)置WebView的WebSettings對(duì)象,然后調(diào)用WebSettings中的方法來(lái)實(shí)現(xiàn)的。
WebSettings的方法及說(shuō)明如下:(這里先列出來(lái)所有的方法及解釋,大家可以先忽略,看后面的舉例中所使用的幾個(gè)常用方法即可,用到哪個(gè)函數(shù)的時(shí)候再回來(lái)查查就可以了)

/**  * 是否支持縮放,配合方法setBuiltInZoomControls使用,默認(rèn)true  */ setSupportZoom(boolean support)  /**  * 是否需要用戶手勢(shì)來(lái)播放Media,默認(rèn)true  */ setMediaPlaybackRequiresUserGesture(boolean require)  /**  * 是否使用WebView內(nèi)置的縮放組件,由浮動(dòng)在窗口上的縮放控制和手勢(shì)縮放控制組成,默認(rèn)false  */ setBuiltInZoomControls(boolean enabled)  /**  * 是否顯示窗口懸浮的縮放控制,默認(rèn)true  */ setDisplayZoomControls(boolean enabled)  /**  * 是否允許訪問(wèn)WebView內(nèi)部文件,默認(rèn)true  */ setAllowFileAccess(boolean allow)  /**  * 是否允許獲取WebView的內(nèi)容URL ,可以讓W(xué)ebView訪問(wèn)ContentPrivider存儲(chǔ)的內(nèi)容。 默認(rèn)true  */ setAllowContentAccess(boolean allow)  /**  * 是否啟動(dòng)概述模式瀏覽界面,當(dāng)頁(yè)面寬度超過(guò)WebView顯示寬度時(shí),縮小頁(yè)面適應(yīng)WebView。默認(rèn)false  */ setLoadWithOverviewMode(boolean overview)  /**  * 是否保存表單數(shù)據(jù),默認(rèn)false  */ setSaveFormData(boolean save)  /**  * 設(shè)置頁(yè)面文字縮放百分比,默認(rèn)100%  */ setTextZoom(int textZoom)  /**  * 是否支持ViewPort的meta tag屬性,如果頁(yè)面有ViewPort meta tag 指定的寬度,則使用meta tag指定的值,否則默認(rèn)使用寬屏的視圖窗口  */ setUseWideViewPort(boolean use)   /**  * 是否支持多窗口,如果設(shè)置為true ,WebChromeClient#onCreateWindow方法必須被主程序?qū)崿F(xiàn),默認(rèn)false  */ setSupportMultipleWindows(boolean support)  /**  * 指定WebView的頁(yè)面布局顯示形式,調(diào)用該方法會(huì)引起頁(yè)面重繪。默認(rèn)LayoutAlgorithm#NARROW_COLUMNS  */ setLayoutAlgorithm(LayoutAlgorithm l)  /**  * 設(shè)置標(biāo)準(zhǔn)的字體族,默認(rèn)”sans-serif”。font-family 規(guī)定元素的字體系列。  * font-family 可以把多個(gè)字體名稱作為一個(gè)“回退”系統(tǒng)來(lái)保存。如果瀏覽器不支持第一個(gè)字體,  * 則會(huì)嘗試下一個(gè)。也就是說(shuō),font-family 屬性的值是用于某個(gè)元素的字體族名稱或/及類族名稱的一個(gè)  * 優(yōu)先表。瀏覽器會(huì)使用它可識(shí)別的第一個(gè)值。  */ setStandardFontFamily(String font)  /**  * 設(shè)置混合字體族。默認(rèn)”monospace”  */ setFixedFontFamily(String font)  /**  * 設(shè)置SansSerif字體族。默認(rèn)”sans-serif”  */ setSansSerifFontFamily(String font)  /**  * 設(shè)置SerifFont字體族,默認(rèn)”sans-serif”  */ setSerifFontFamily(String font)  /**  * 設(shè)置CursiveFont字體族,默認(rèn)”cursive”  */ setCursiveFontFamily(String font)  /**  * 設(shè)置FantasyFont字體族,默認(rèn)”fantasy”  */ setFantasyFontFamily(String font)  /**  * 設(shè)置最小字體,默認(rèn)8. 取值區(qū)間[1-72],超過(guò)范圍,使用其上限值。  */ setMinimumFontSize(int size)  /**  * 設(shè)置最小邏輯字體,默認(rèn)8. 取值區(qū)間[1-72],超過(guò)范圍,使用其上限值。  */ setMinimumLogicalFontSize(int size)  /**  * 設(shè)置默認(rèn)字體大小,默認(rèn)16,取值區(qū)間[1-72],超過(guò)范圍,使用其上限值。  */ setDefaultFontSize(int size)  /**  * 設(shè)置默認(rèn)填充字體大小,默認(rèn)16,取值區(qū)間[1-72],超過(guò)范圍,使用其上限值。  */ setDefaultFixedFontSize(int size)  /**  * 設(shè)置是否加載圖片資源,注意:方法控制所有的資源圖片顯示,包括嵌入的本地圖片資源。  * 使用方法setBlockNetworkImage則只限制網(wǎng)絡(luò)資源圖片的顯示。值設(shè)置為true后,  * webview會(huì)自動(dòng)加載網(wǎng)絡(luò)圖片。默認(rèn)true  */ setLoadsImagesAutomatically(boolean flag)  /**  * 是否加載網(wǎng)絡(luò)圖片資源。注意如果getLoadsImagesAutomatically返回false,則該方法沒(méi)有效果。  * 如果使用setBlockNetworkLoads設(shè)置為false,該方法設(shè)置為false,也不會(huì)顯示網(wǎng)絡(luò)圖片。  * 當(dāng)值從true改為false時(shí)。WebView會(huì)自動(dòng)加載網(wǎng)絡(luò)圖片。  */ setBlockNetworkImage(boolean flag)  /**  * 設(shè)置是否加載網(wǎng)絡(luò)資源。注意如果值從true切換為false后,WebView不會(huì)自動(dòng)加載,  * 除非調(diào)用WebView#reload().如果沒(méi)有android.Manifest.permission#INTERNET權(quán)限,  * 值設(shè)為false,則會(huì)拋出java.lang.SecurityException異常。  * 默認(rèn)值:有android.Manifest.permission#INTERNET權(quán)限時(shí)為false,其他為true。  */ setBlockNetworkLoads(boolean flag)  /**  * 設(shè)置是否允許執(zhí)行JS。  */ setJavaScriptEnabled(boolean flag)  /**  * 是否允許Js訪問(wèn)任何來(lái)源的內(nèi)容。包括訪問(wèn)file scheme的URLs。考慮到安全性,  * 限制Js訪問(wèn)范圍默認(rèn)禁用。注意:該方法只影響file scheme類型的資源,其他類型資源如圖片類型的,  * 不會(huì)受到影響。ICE_CREAM_SANDWICH_MR1版本以及以下默認(rèn)為true,JELLY_BEAN版本  * 以上默認(rèn)為false  */ setAllowUniversalAccessFromFileURLs(boolean flag)   /**  * 是否允許Js訪問(wèn)其他file scheme的URLs。包括訪問(wèn)file scheme的資源。考慮到安全性,  * 限制Js訪問(wèn)范圍默認(rèn)禁用。注意:該方法只影響file scheme類型的資源,其他類型資源如圖片類型的,  * 不會(huì)受到影響。如果getAllowUniversalAccessFromFileURLs為true,則該方法被忽略。  * ICE_CREAM_SANDWICH_MR1版本以及以下默認(rèn)為true,JELLY_BEAN版本以上默認(rèn)為false  */ setAllowFileAccessFromFileURLs(boolean flag)  /**  * 設(shè)置存儲(chǔ)定位數(shù)據(jù)庫(kù)的位置,考慮到位置權(quán)限和持久化Cache緩存,Application需要擁有指定路徑的  * write權(quán)限  */ setGeolocationDatabasePath(String databasePath)  /**  * 是否允許Cache,默認(rèn)false。考慮需要存儲(chǔ)緩存,應(yīng)該為緩存指定存儲(chǔ)路徑setAppCachePath  */ setAppCacheEnabled(boolean flag)  /**  * 設(shè)置Cache API緩存路徑。為了保證可以訪問(wèn)Cache,Application需要擁有指定路徑的write權(quán)限。  * 該方法應(yīng)該只調(diào)用一次,多次調(diào)用自動(dòng)忽略。  */ setAppCachePath(String appCachePath)  /**  * 是否允許數(shù)據(jù)庫(kù)存儲(chǔ)。默認(rèn)false。查看setDatabasePath API 如何正確設(shè)置數(shù)據(jù)庫(kù)存儲(chǔ)。  * 該設(shè)置擁有全局特性,同一進(jìn)程所有WebView實(shí)例共用同一配置。注意:保證在同一進(jìn)程的任一WebView  * 加載頁(yè)面之前修改該屬性,因?yàn)樵谶@之后設(shè)置WebView可能會(huì)忽略該配置  */ setDatabaseEnabled(boolean flag)  /**  * 是否存儲(chǔ)頁(yè)面DOM結(jié)構(gòu),默認(rèn)false。  */ setDomStorageEnabled(boolean flag)  /**  * 是否允許定位,默認(rèn)true。注意:為了保證定位可以使用,要保證以下幾點(diǎn):  * Application 需要有android.Manifest.permission#ACCESS_COARSE_LOCATION的權(quán)限  * Application 需要實(shí)現(xiàn)WebChromeClient#onGeolocationPermissionsShowPrompt的回調(diào),  * 接收J(rèn)s定位請(qǐng)求訪問(wèn)地理位置的通知  */ setGeolocationEnabled(boolean flag)  /**  * 是否允許JS自動(dòng)打開(kāi)窗口。默認(rèn)false  */ setJavaScriptCanOpenWindowsAutomatically(boolean flag)  /**  * 設(shè)置頁(yè)面的編碼格式,默認(rèn)UTF-8  */ setDefaultTextEncodingName(String encoding)  /**  * 設(shè)置WebView代理,默認(rèn)使用默認(rèn)值  */ setUserAgentString(String ua)  /**  * 通知WebView是否需要設(shè)置一個(gè)節(jié)點(diǎn)獲取焦點(diǎn)當(dāng)  * WebView#requestFocus(int,android.graphics.Rect)被調(diào)用的時(shí)候,默認(rèn)true  */ setNeedInitialFocus(boolean flag)  /**  * 基于WebView導(dǎo)航的類型使用緩存:正常頁(yè)面加載會(huì)加載緩存并按需判斷內(nèi)容是否需要重新驗(yàn)證。  * 如果是頁(yè)面返回,頁(yè)面內(nèi)容不會(huì)重新加載,直接從緩存中恢復(fù)。setCacheMode允許客戶端根據(jù)指定的模式來(lái)  * 使用緩存。  * LOAD_DEFAULT 默認(rèn)加載方式  * LOAD_CACHE_ELSE_NETWORK 按網(wǎng)絡(luò)情況使用緩存  * LOAD_NO_CACHE 不使用緩存  * LOAD_CACHE_ONLY 只使用緩存  */ setCacheMode(int mode)  /**  * 設(shè)置加載不安全資源的WebView加載行為。KITKAT版本以及以下默認(rèn)為MIXED_CONTENT_ALWAYS_ALLOW方  * 式,LOLLIPOP默認(rèn)MIXED_CONTENT_NEVER_ALLOW。強(qiáng)烈建議:使用MIXED_CONTENT_NEVER_ALLOW  */ setMixedContentMode(int mode) 

下面我們就舉個(gè)例子來(lái)看下用法
示例1:在WebView中啟用JavaScript:

public class MyActivity extends Activity {   private WebView mWebView;  private Button mBtn;   @Override  public 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:設(shè)置緩存
優(yōu)先使用緩存
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
不使用緩存:
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); 
示例3:打開(kāi)頁(yè)面時(shí),自適應(yīng)屏幕:

WebSettings webSettings = mWebView .getSettings(); webSettings.setUseWideViewPort(true);//設(shè)置此屬性,可任意比例縮放 webSettings.setLoadWithOverviewMode(true); 

效果圖如下:

示例4:使頁(yè)面支持縮放:

WebSettings webSettings = mWebView.getSettings(); //開(kāi)啟javascript支持 webSettings.setJavaScriptEnabled(true); // 設(shè)置可以支持縮放 webSettings.setSupportZoom(true); // 設(shè)置出現(xiàn)縮放工具 webSettings.setBuiltInZoomControls(true); 

示例5:.如果webView中需要用戶手動(dòng)輸入用戶名、密碼或其他,則webview必須設(shè)置支持獲取手勢(shì)焦點(diǎn)
webview.requestFocusFromTouch(); 
其它的設(shè)置就靠大家自己去嘗試?yán)玻@里就不再一一綴述了,大家只需要記著,如果需要設(shè)置webview就從WebSettings里面去找就可以啦。
二、JS調(diào)用Java代碼
在看了如何設(shè)置webview以后,我們來(lái)看下如何讓W(xué)ebview與網(wǎng)頁(yè)中的JS代碼交互的問(wèn)題。
1、概述
更多時(shí)候,網(wǎng)頁(yè)中需要通過(guò)JS代碼來(lái)調(diào)用本地的Android代碼,比如H5頁(yè)面需要判斷當(dāng)前用戶是否登錄等。
利用JS代碼調(diào)用JAVA代碼,主要是用到WebView下面的一個(gè)函數(shù):
public void addJavascriptInterface(Object obj, String interfaceName) 
這個(gè)函數(shù)有兩個(gè)參數(shù):
--Object obj:interfaceName所綁定的對(duì)象
--String interfaceName:所綁定的對(duì)象所對(duì)應(yīng)的名稱
它有意義就是向WebView注入一個(gè)interfaceName的對(duì)象,這個(gè)對(duì)象綁定的是obj對(duì)象,通過(guò)interfaceName就可以調(diào)用obj對(duì)象中的方法,這個(gè)表述可能大家不太理解,因?yàn)閕nterfaceName是一個(gè)String,怎么被你說(shuō)成對(duì)象了,理解不了沒(méi)關(guān)系,下面有具體示例
2、示例
下面同樣是上面的示例,我們對(duì)它加以更改,效果圖如下:


在原來(lái)html上面添加了一個(gè)按鈕,當(dāng)點(diǎn)擊按鈕時(shí)調(diào)用Android的Toast函數(shù)彈出一個(gè)toast消息。
先看Android代碼:

public class MyActivity extends Activity {   private WebView mWebView;  private Button mBtn;   @Override  public 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(), "通過(guò)Natvie傳遞的Toast:"+message, Toast.LENGTH_LONG).show();  } } 

這里最主要是的下面這句:
mWebView.addJavascriptInterface(this, "android"); 
這句的意思是把MyActivity對(duì)象注入到WebView中,在WebView中的對(duì)象別名叫android;另外,我們還在MyActivity中額外寫了一個(gè)函數(shù)toastMessage(String message),用于彈出MSG
下面我們看看html代碼:

<!DOCTYPE html> <html lang="en"> <head>  <meta charset="UTF-8">  <title>Title</title>  <h1>歡迎光臨啟艦的blog</h1>  <input type="button" value="js調(diào)native" onclick="ok()"> </head> <body> <script type="text/javascript"> function ok() {  android.toastMessage("哈哈,i m webview msg"); } </script> </body> </html> 

在這個(gè)html中,我添加了一個(gè)button按鈕,當(dāng)點(diǎn)擊時(shí)調(diào)用ok函數(shù):

function ok() {  android.toastMessage("哈哈,i m webview msg"); } 

它的意義就是調(diào)用android對(duì)象里的toastMessage方法,這個(gè)android就是我們利用mWebView.addJavascriptInterface(this, “android”)注入到WebView的android,它所對(duì)應(yīng)的對(duì)象就將MyActivity;所以在JS中,我們就可以通過(guò)android這個(gè)別名來(lái)調(diào)用MyActivity對(duì)象中的任何public方法。
3、addJavascriptInterface自定義作用對(duì)象
在上面的示例中mWebView.addJavascriptInterface(this, “android”);我們直接通過(guò)this,把當(dāng)前整個(gè)類作為對(duì)象傳給WebView了,但這會(huì)有很大風(fēng)險(xiǎn),因?yàn)槲覀冞@個(gè)類中可能會(huì)有各種函數(shù),而這些函數(shù)是只有本地Native代碼才會(huì)用到,WebView是根本用不到的。所以如果通過(guò)全部注入給WebView的話,那么一些存心不良的同學(xué)就可以任意調(diào)用我們這個(gè)類中的方法,給我們APP帶來(lái)危害。
所以,一般而言,我們很少直接會(huì)傳this,把整個(gè)類注入給WebView,而是單獨(dú)寫一個(gè)類專門用于JS交互,比如:

public class MyActivity extends Activity {   private WebView mWebView;  private Button mBtn;   @Override  public 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(), "通過(guò)Natvie傳遞的Toast:"+message, Toast.LENGTH_LONG).show();  }  } } 

在這段代碼中,在通過(guò)addJavascriptInterface注入時(shí):

mWebView.addJavascriptInterface(new JSBridge(), "android"); 
指定android對(duì)象綁定的是JSBridge對(duì)象!所以在WebView中,通過(guò)JS只能訪問(wèn)JSBridge中所定義的對(duì)象,如果訪問(wèn)其它類的函數(shù),比如MyActivity中的函數(shù),就會(huì)報(bào)下面的錯(cuò)誤(即方法找不到)

大家可以自己嘗試下;
然后對(duì)應(yīng)的html代碼:

<!DOCTYPE html> <html lang="en"> <head>  <meta charset="UTF-8">  <title>Title</title>  <h1>歡迎光臨啟艦的blog</h1>  <input type="button" value="js調(diào)native" onclick="ok()"> </head> <body> <script type="text/javascript"> function ok() {  android.toastMessage("哈哈,i m webview msg");  } </script> </body> </html> 

由于在注入時(shí)的對(duì)象別名和所調(diào)用的函數(shù)名都沒(méi)有變,所以HTML中的JS代碼是無(wú)需更改的。效果圖與上節(jié)一樣,就不再帖出了。
源碼在文章底部給出
4、addJavascriptInterface注入漏洞
上面我們說(shuō)了在addJavascriptInterface注入時(shí),為了防止WebView調(diào)用我們不想被它調(diào)用的函數(shù),所以我們需要單獨(dú)為WebView交互定義一個(gè)類,讓它只執(zhí)行這個(gè)類里面的函數(shù)
但……這真的能擋住黑客的攻擊嗎?
當(dāng)然是NO……,不然我就不會(huì)寫這一段了……
mWebView.addJavascriptInterface(new JSBridge(), "android"); 
在注入時(shí),我們已經(jīng)把對(duì)象傳給了JS,在JS中當(dāng)然可以通過(guò)反射得到APP中的各種類的實(shí)例!現(xiàn)在反編譯Android代碼可不是什么難事(本文結(jié)尾附j(luò)adx反編譯方法),很容易拿到你有哪些類,有哪些函數(shù),通過(guò)這些就可以想執(zhí)行哪個(gè)執(zhí)行哪個(gè)了,有沒(méi)有細(xì)思極恐……
具體的細(xì)節(jié)我就不講了,不在本篇范圍,給大家找了篇文章,有興趣的同學(xué)可以參考下:《Android WebView的Js對(duì)象注入漏洞解決方案》
5、JavascriptInterface注解
為了解決addJavascriptInterface()函數(shù)的安全問(wèn)題,在android:targetSdkVersion數(shù)值為17(Android4.2)及以上的APP中,JS只能訪問(wèn)帶有 @JavascriptInterface注解的Java函數(shù),所以如果你的android:targetSdkVersion是17+,與JS交互的Native函數(shù)中,必須添加JavascriptInterface注解,不然無(wú)效,比如:

public class JSBridge {  @JavascriptInterface  public void toastMessage(String message) {  Toast.makeText(getApplicationContext(), "通過(guò)Natvie傳遞的Toast:" + message, Toast.LENGTH_LONG).show();  } } 

這也就是很多同學(xué)在高target上,addJavascriptInterface()函數(shù)無(wú)效的主要原因。
注意:雖然在target 17以后,已經(jīng)修復(fù)了這個(gè)安全問(wèn)題,但目前大多數(shù)APP都還是target 17以前的,所以大家可以嘗試著找一些APP來(lái)演示下這個(gè)漏洞哦……
三、JAVA調(diào)用JS代碼
1、JAVA調(diào)用JS代碼
前面給大家演示了如何通過(guò)JS調(diào)用Java代碼,這里就反過(guò)來(lái)看看,如何在Native中調(diào)用JS的代碼
本例的效果圖如下:

在點(diǎn)擊“加載URL”按鈕時(shí),調(diào)用webview中的JavaScript求和函數(shù),將結(jié)果顯示在標(biāo)題中。
先看html代碼:

<!DOCTYPE html> <html lang="en"> <head>  <meta charset="UTF-8">  <title>Title</title>  <h1 id="h">歡迎光臨啟艦的blog</h1>  <input type="button" value="js調(diào)native" onclick="ok()"> </head> <body> <script type="text/javascript"> function sum(i,m) {  document.getElementById("h").innerHTML= (i+m); } </script> </body> </html> 

在這里,我們寫了一個(gè)求和函數(shù)sum(i,m)
結(jié)果中就是把h1標(biāo)簽的內(nèi)容改為求和后的結(jié)果值。
再來(lái)看看JAVA的調(diào)用代碼:

public class MyActivity extends Activity {   private WebView mWebView;  private Button mBtn;   @Override  public 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() {  @Override  public void onClick(View v) {  mWebView.loadUrl("javascript:sum(3,8)");  }  });  } } 

在點(diǎn)擊按鈕時(shí)調(diào)用JS函數(shù):
mWebView.loadUrl("javascript:sum(3,8)"); 
這里也就是在JAVA中調(diào)用JS函數(shù)的方法:
String url = "javascript:methodName(params……);" 
webView.loadUrl(url); 
javascript:偽協(xié)議讓我們可以通過(guò)一個(gè)鏈接來(lái)調(diào)用JavaScript函數(shù)
中間methodName是JavaScript中實(shí)現(xiàn)的函數(shù)
jsonParams是傳入的參數(shù)列表
使用起來(lái)難度不大,就不再多講了
源碼在文章底部給出
2、JAVA中如何得到JS中的返回值(Android4.4以前)
現(xiàn)在我們?cè)倏紤]一下,如果我們要在JAVA中需要得到JS的結(jié)果返回值要怎么辦?比如在上面的例子中,我們需要在JAVA中得到在計(jì)算后的結(jié)果值
Android在4.4之前并沒(méi)有提供直接調(diào)用js函數(shù)并獲取值的方法,也就是說(shuō),我們只能調(diào)用JS中的函數(shù),并不能得到該函數(shù)的返回值,想得到返回值我們就得想其它辦法,所以在此之前,常用的思路是 java調(diào)用js方法,js方法執(zhí)行完畢,再次調(diào)用java代碼將值返回。
1).Java調(diào)用js代碼

webView.addJavascriptInterface(this, "android"); mWebView.loadUrl("javascript:sum(3,8)"); 

注意,這里通過(guò)addJavascriptInterface將MyActiviy所對(duì)應(yīng)的對(duì)象注入到WebView中了。
2).js函數(shù)處理,并將結(jié)果通過(guò)調(diào)用java方法返回

function sum(i,m){  var result = i+m;  document.getElementById("h").innerHTML= result;  android.onSumResult(result) } 

3)..Java在回調(diào)方法中獲取js函數(shù)返回值

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調(diào)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)中,先通過(guò)result得到結(jié)果,最后通過(guò)android.onSumResult(result);將結(jié)果傳給Native
然后再來(lái)看看JAVA代碼:

public class MyActivity extends Activity {   private WebView mWebView;  private Button mBtn;   @Override  public 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();  } } 

這里主要做了兩件事:
第一:通過(guò)addJavascriptInterface注入MyActivity對(duì)象,以便JS訪問(wèn)其中的函數(shù)
mWebView.addJavascriptInterface(this, "android"); 
第二:供JS調(diào)用,以返回結(jié)果的函數(shù)onSumResult():

public void onSumResult(int result) {  Toast.makeText(this,"received result:"+result,Toast.LENGTH_SHORT).show(); }

  3、JAVA中如何得到JS中的返回值(Android4.4之后)
Android 4.4之后使用evaluateJavascript即可。這里展示一個(gè)簡(jiǎn)單的交互示例
先寫一個(gè)具有返回值的js方法

function getGreetings() {  return 1; } 

java代碼時(shí)用evaluateJavascript方法調(diào)用:

private void testEvaluateJavascript(WebView webView) {  webView.evaluateJavascript("getGreetings()", new ValueCallback() {  @Override  public void onReceiveValue(String value) {   Log.i(LOGTAG, "onReceiveValue value=" + value);  }  }); } 

從上面的用法中很明顯看到,通過(guò)evaluateJavascript調(diào)用JS中的方法,可以向其中添加結(jié)果回調(diào),來(lái)接收J(rèn)S的return值。
注意:
上面限定了結(jié)果返回結(jié)果為String,對(duì)于簡(jiǎn)單的類型會(huì)嘗試轉(zhuǎn)換成字符串返回,對(duì)于復(fù)雜的數(shù)據(jù)類型,建議以字符串形式的json返回。
evaluateJavascript方法必須在UI線程(主線程)調(diào)用,因此onReceiveValue也執(zhí)行在主線程。
好了,這篇文章中有關(guān)WebView的知識(shí)就先到這,下篇繼續(xù)講。下面給大家講講有關(guān)jadx-gui反編譯的知識(shí)。
四、jadx-gui反編譯
在遇到j(luò)adx-gui反編譯之前,都是使用apktools進(jìn)行反編譯的,apktools有些是反編譯不出來(lái)的,而且……難用……
想知道jadx-gui有多強(qiáng)?它都可以反編譯淘寶、微信代碼,是不是夠強(qiáng)了。下面我們就來(lái)看看它是如何反編譯的;
1)、下載、配置
jadx-gui是開(kāi)源的,項(xiàng)目地址:《https://github.com/skylot/jadx
mac電腦:
打開(kāi)終端,切到某個(gè)路徑下,輸入以下命令:

git clone https://github.com/skylot/jadx.git cd jadx ./gradlew dist 

其實(shí)這里只是做了兩個(gè)動(dòng)作:
第一,使用git命令將 項(xiàng)目clone下來(lái)(這里需要配置git環(huán)境,如果沒(méi)有,請(qǐng)先搜資料配置git環(huán)境,然后再來(lái))
然后,執(zhí)行jadx目錄 下gradlew腳本,這個(gè)是shell腳本
windows電腦:

git clone https://github.com/skylot/jadx.git cd jadx gradlew.bat dist 

在windows電腦中,步驟與mac是一樣的,只是最后一步中,已經(jīng)不再是./gradlew所對(duì)應(yīng)的shell腳本了,而是windows平臺(tái)上的bat腳本。
可見(jiàn)作者有多牛X,shell腳本和bat腳本都會(huì)寫,真是

主站蜘蛛池模板: 平罗县| 信宜市| 金川县| 鄄城县| 柞水县| 陆丰市| 从化市| 海门市| 孝义市| 商水县| 西宁市| 汉阴县| 利津县| 兴隆县| 兴隆县| 区。| 铁力市| 阜南县| 桂东县| 临沂市| 抚松县| 墨竹工卡县| 临沧市| 西乡县| 嵊泗县| 丰县| 保德县| 来安县| 文水县| 灌云县| 孟村| 德阳市| 武胜县| 兴仁县| 隆回县| 桂平市| 建湖县| 突泉县| 班玛县| 黄冈市| 怀化市|