WebView的用法
基礎用法很簡單..
webView = (WebView) findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, Stringurl) {
view.loadUrl(url); // 根據(jù)傳入的參數(shù)再去加載新的網(wǎng)頁
return true; // 表示當前WebView可以處理打開新網(wǎng)頁的請求抛猫,不用借助系統(tǒng)瀏覽器
}
});
webView.loadUrl("http://www.baidu.com");
網(wǎng)絡訪問需要權限:
android.permission.INTERNET
10.2使用HTTP協(xié)議訪問網(wǎng)絡
Android中發(fā)送HTTP請求一般通過HttpURLConnection和HttpClient.
首先需要獲取到 HttpURLConnection 的實例少欺,一般只需 new 出一個 URL 對象,并傳入目標的網(wǎng)絡地址抡锈,然后調用一下 openConnection()方法即可.
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
獲取HttpURLConnection實例后設置HTTP請求方法,常用是是Get和Post.Get表示獲取數(shù)據(jù),Post表示提數(shù)據(jù).
connection.setRequestMethod("GET");
之后就可以設置連接超時,讀取超時的毫秒數(shù)或者服務器希望得到的消息頭等.
在調用getInputStream()就可以獲得服務器返回的輸入流.
InputStream in = connection.getInputStream();
最后可以調用disconnect()關閉該HTTP連接.
Post示例:
connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");
10.2.2 使用HttpClient
Android6.0后已廢棄.
10.3解析XML格式數(shù)據(jù)
10.3.1Pull解析方式
private void parseXMLWithPull(String xmlData) {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlData));
int eventType = xmlPullParser.getEventType();
String id = "";
String name = "";
String version = "";
while (eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = xmlPullParser.getName();
switch (eventType) {
// 開始解析某個結點
case XmlPullParser.START_TAG: {
if ("id".equals(nodeName)) {
id = xmlPullParser.nextText();
} else if ("name".equals(nodeName)) {
name = xmlPullParser.nextText();
} else if ("version".equals(nodeName)) {
version = xmlPullParser.nextText();
}
break;
}
// 完成解析某個結點
case XmlPullParser.END_TAG: {
if ("app".equals(nodeName)) {
Log.d("MainActivity", "id is " + id);
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "version is " + version);
}
break;
}
default:
break;
}
eventType = xmlPullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}
獲取的數(shù)據(jù)不對(sad臉
10.3.2SAX解析方式
新建一個類繼承DefaultHandle,重寫startDocument(),startElement(),characters(),endElement(),endDocument()五個方法.
- startDocument()方法會在開始 XML 解析的時候調用.
- startElement()方法會在開始解析某個結點的時候調用.
- characters()方法會在獲取結點中內容的時候調用.
- endElement()方法會在完成解析某個結點的時候調用.
- endDocument()方法會在完成整個 XML 解析的時候調用.
其中恩敌, startElement()瞬测、 characters()和 endElement()這三個方法是有參數(shù)的,從 XML 中解析出的數(shù)據(jù)就會以參數(shù)的形式傳入到這些方法中纠炮。需要注意的是月趟,在獲取結點中的內容時, characters()方法可能會被調用多次恢口,一些換行符也被當作內容解析出來孝宗,我們需要針對這種情況在代碼中做好控制
示例:
public class ContentHandler extends DefaultHandler {
private String nodeName;
private StringBuilder id;
private StringBuilder name;
private StringBuilder version;
@Override
public void startDocument() throws SAXException {
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}
@Override
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
// 記錄當前結點名
nodeName = localName;
}
@Override
public void characters(char[] ch, int start, int length) throwsSAXException {
// 根據(jù)當前的結點名判斷將內容添加到哪一個StringBuilder對象中
if ("id".equals(nodeName)) {
id.append(ch, start, length);
} else if ("name".equals(nodeName)) {
name.append(ch, start, length);
} else if ("version".equals(nodeName)) {
version.append(ch, start, length);
}
}
@Override
public void endElement(String uri, String localName, String qName) throwsSAXException {
if ("app".equals(localName)) {
Log.d("ContentHandler", "id is " + id.toString().trim());
Log.d("ContentHandler", "name is " + name.toString().trim());
Log.d("ContentHandler", "version is " + version.toString().trim());
// 最后要將StringBuilder清空掉id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}
@Override
public void endDocument() throws SAXException {
}
}
private void parseXMLWithSAX(String xmlData) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
ContentHandler handler = new ContentHandler();
// 將ContentHandler的實例設置到XMLReader中
xmlReader.setContentHandler(handler);
// 開始執(zhí)行解析
xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
}
}
10.4解析JSON格式數(shù)據(jù)
JSON相對于xml體積更小,但是語義較差,沒xml直觀.解析JSON可以使用官方提供的 JSONObject,也可以使用谷歌的開源庫 GSON耕肩∫蚋荆或者第三方的開源庫如 Jackson、 FastJSON .
10.4.1使用JSONObject
10.4.2使用GSON
新建類,包含標簽.
public class App {
private String id;
private String name;
private String version;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
使用方法:
private void parseJSONWithGSON(String jsonData) {
Gson gson = new Gson();
List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>() {}.getType());
for (App app : appList) {
Log.d("MainActivity", "id is " + app.getId());
Log.d("MainActivity", "name is " + app.getName());
Log.d("MainActivity", "version is " + app.getVersion());
}
}
10.5 網(wǎng)絡編程的最佳實踐
可以把所有的網(wǎng)絡操作提取到一個公共的類中,并提供靜態(tài)方法.
網(wǎng)絡請求通常都是屬于耗時操作猿诸,而 sendHttpRequest()方法的內部并沒有開啟線程婚被,這樣就有可能導致在調用 sendHttpRequest()方法的時候使得主線程被阻塞住。若開啟線程,則sendHttpRequest()會在服務器相應前執(zhí)行結束而無法返回相應的數(shù)據(jù).組要使用回調機制.
例如:
定義接口:
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
}
實現(xiàn)接口:
public class HttpUtil {
public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL(address);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.setDoInput(true);
connection.setDoOutput(true);
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(newInputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
if (listener != null) {
// 回調onFinish()方法
listener.onFinish(response.toString());
}
} catch (Exception e) {
if (listener != null) {
//回調onError()方法
listener.onError(e);
}
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
}
需要發(fā)起HTTP請求時:
String address = "http://www.baidu.com";
String response = HttpUtil.sendHttpRequest(address);