第10章 使用网络技术
2015-11-05 22:37
926 查看
WebView 的用法
相当与Android系统中的一个内置浏览器,可以很方便的在应用中展示各种网页,当然也可以设置成让他是否支持JavaScript。
使用HTTP协议访问网络
2.1 HttpURLConnection
(1)获取HttpURLConnection的实例,一般new出一个URL对象,传入目标的网络地址,并且调用openConnection()方法即可
(2)接下来我们用GET方法来设置connection进行请求数据
(3)我们可以像浏览器一样对发出的请求做各种各样的定制了,比如超时的时间等等,我们这里设置的是8秒钟。
(4)之后,用getInputStream()可以获取服务器返回的输入流了,获取到输入流后我们可以用Java中的方法进行处理了
(5)最后调用disconnect()将http连接关掉。
2.2 HttpClient
HttpClient是Apache提供的访问接口,能实现和HttpURLConnection一样的效果,但是他们的用法却有很大的不同。
(1)因为HttpClient是一个接口,所以我们不能new出一个实例,我们一般都是new出DefaultHttpClient的实例
(2)接下来,如果要发出GET请求,则需要创建一个HttpGet对象,若要发出POST请求,则创建HttpPost对象
(3)执行完execute方法后,就会返回一个HttpResponse对象,服务器所有的返回信息都会存储在该对象中,我们先从HttpResponse取出服务器返回的状态码,如果是200的话,我们就可以继续往下执行了
(4)接下来,我们可以在if中调用getEntity()返回一个HttpEntity实例,然后调用EntityUtils.toString()静态方法将entity转换成String,同时可以指定他的编码方式。
HttpClient相当于是一个增强版的HttpURLConnection,但是HttpClient也有他的局限性,比如说不能执行html中的JavaScript代码。
解析XML格式数据
首先在我们的本机上面有一个get_data.xml文件,通过 http://127.0.0.1/get_data.xml 可以访问,然后他的内容如下
解析XML文件有PULL,SAX,DOM等方式,我们这里只讲解前面两种方式
3.1 Pull解析方式
我们先来看一段使用Pull解析的代码
首先通过XmlPullParserFactory的实例获得XmlPullParser的对象,然后调用该对象的setInput()将服务器返回的xml数据传进去就可以开始解析了。在解析的过程中,getEventType()方法获得当前的解析事件,然后在一个while中不断的解析,如果当前的解析事件不为XmlPullParser.END_DOCUMENT,就说明还没有到达文档末尾,调用next()获取下一个解析事件。
在while中,用getName()获取当前节点的名字,nextText()获取当前节点的具体内容,这样每当解析完一个节点,就将他打印出来。
3.2 SAX解析方式
SAX解析的用法比Pull会麻烦一些,但在语义方面会更加清楚一点。
通常情况下我们会创建一个类来继承DefaultHandler,然后重写父类的5个方法
4 JSON数据解析
4.1 使用JSONObject
我们先把服务器返回的数据交给JSONArray,然后循环遍历JSONArray,取出来的每一个都是JSONObject,接下来只需用getString()取出即可
4.2 使用GSON
GSON是谷歌的开源库,处理JSON数据会比JSONObject更加的方便,简单。
5 网络编程的最佳实践
在我们编写App的时候,肯定会经常性的进行一些网络的请求,这样我们就需要大量的使用HttpURLConnection或者HttpClient,然后在每一次进行网络请求的背后,很多代码都是重复的,比如两次请求的不同点只是目标网络地址发生了变化。这就驱使我们来写一个HttpUtil类,该类提供一个静态方法供我们使用。
我们先写一个1.0版本的
我们可以这样使用上面的类
但这会引起一个问题,就是这些代码是在主线程里面执行的,所以可能会引起App的阻塞,出现ANR问题。因为我们并没有在HttpUtil中开启新线程,但是我们也不能直接开启一个新线程,因为这样就不能返回数据了。我们可以用Java的回调机制。
首先需要定义一个接口,比如命名为HttpCallbackListener
接着,修改HttpUtil中的代码,如下
相当与Android系统中的一个内置浏览器,可以很方便的在应用中展示各种网页,当然也可以设置成让他是否支持JavaScript。
使用HTTP协议访问网络
2.1 HttpURLConnection
(1)获取HttpURLConnection的实例,一般new出一个URL对象,传入目标的网络地址,并且调用openConnection()方法即可
URL url = new URL("http://www.baidu.com"); connection = (HttpURLConnection) url.openConnection();
(2)接下来我们用GET方法来设置connection进行请求数据
connection.setRequestMethod("GET");
(3)我们可以像浏览器一样对发出的请求做各种各样的定制了,比如超时的时间等等,我们这里设置的是8秒钟。
connection.setConnectTimeout(8000); connection.setReadTimeout(8000);
(4)之后,用getInputStream()可以获取服务器返回的输入流了,获取到输入流后我们可以用Java中的方法进行处理了
InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in));
(5)最后调用disconnect()将http连接关掉。
2.2 HttpClient
HttpClient是Apache提供的访问接口,能实现和HttpURLConnection一样的效果,但是他们的用法却有很大的不同。
(1)因为HttpClient是一个接口,所以我们不能new出一个实例,我们一般都是new出DefaultHttpClient的实例
HttpClient httpClient = new DefaultHttpClient();
(2)接下来,如果要发出GET请求,则需要创建一个HttpGet对象,若要发出POST请求,则创建HttpPost对象
//GET请求 HttpGet httpGet = new HttpGet("http://www.baidu.com"); httpClient.execute(httpGet); //POST请求 HttpPost httpPost = new HttpPost("http://www.baidu.com"); List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("username", "admin")); params.add(new BasicNameValuePair("password", "123456")); httpClient.execute(httpPost);
(3)执行完execute方法后,就会返回一个HttpResponse对象,服务器所有的返回信息都会存储在该对象中,我们先从HttpResponse取出服务器返回的状态码,如果是200的话,我们就可以继续往下执行了
if (httpResponse.getStatusLine().getStatusCode() == 200) { }
(4)接下来,我们可以在if中调用getEntity()返回一个HttpEntity实例,然后调用EntityUtils.toString()静态方法将entity转换成String,同时可以指定他的编码方式。
HttpEntity httpEntity = httpResponse.getEntity(); String response = EntityUtils.toString(httpEntity, "utf-8");
HttpClient相当于是一个增强版的HttpURLConnection,但是HttpClient也有他的局限性,比如说不能执行html中的JavaScript代码。
解析XML格式数据
首先在我们的本机上面有一个get_data.xml文件,通过 http://127.0.0.1/get_data.xml 可以访问,然后他的内容如下
<apps> <app> <id>1</id> <name>Google Maps</name> <version>1.0</version> </app> <app> <id>2</id> <name>Chrome</name> <version>2.1</version> </app> <app> <id>3</id> <name>Google Play</name> <version>2.3</version> </app> </apps>
解析XML文件有PULL,SAX,DOM等方式,我们这里只讲解前面两种方式
3.1 Pull解析方式
我们先来看一段使用Pull解析的代码
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); } } default: break; } eventType = xmlPullParser.next(); } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
首先通过XmlPullParserFactory的实例获得XmlPullParser的对象,然后调用该对象的setInput()将服务器返回的xml数据传进去就可以开始解析了。在解析的过程中,getEventType()方法获得当前的解析事件,然后在一个while中不断的解析,如果当前的解析事件不为XmlPullParser.END_DOCUMENT,就说明还没有到达文档末尾,调用next()获取下一个解析事件。
在while中,用getName()获取当前节点的名字,nextText()获取当前节点的具体内容,这样每当解析完一个节点,就将他打印出来。
3.2 SAX解析方式
SAX解析的用法比Pull会麻烦一些,但在语义方面会更加清楚一点。
通常情况下我们会创建一个类来继承DefaultHandler,然后重写父类的5个方法
public class MyHandler extends DefaultHandler { //在开始解析Xml时调用 @Override public void startDocument() throws SAXException { } //在开始解析某个节点时调用 @Override public void startElement(String uri, String localName, } //在获取节点内容时调用 @Override public void characters(char[] ch, int start, int length) throws SAXException { } //会在完成某个节点解析时调用 @Override public void endElement(String uri, String localName, String qName) throws SAXException { } //会在完成整个XML解析时调用 @Override public void endDocument() throws SAXException { } }
4 JSON数据解析
4.1 使用JSONObject
private void parseJSONWithJSONObject(String jsonData) { try { JSONArray jsonArray = new JSONArray(jsonData); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String id = jsonObject.getString("id"); String version = jsonObject.getString("version"); String name = jsonObject.getString("name"); Log.d("MainActivity", "id is "); } } catch (JSONException e) { e.printStackTrace(); } }
我们先把服务器返回的数据交给JSONArray,然后循环遍历JSONArray,取出来的每一个都是JSONObject,接下来只需用getString()取出即可
4.2 使用GSON
GSON是谷歌的开源库,处理JSON数据会比JSONObject更加的方便,简单。
5 网络编程的最佳实践
在我们编写App的时候,肯定会经常性的进行一些网络的请求,这样我们就需要大量的使用HttpURLConnection或者HttpClient,然后在每一次进行网络请求的背后,很多代码都是重复的,比如两次请求的不同点只是目标网络地址发生了变化。这就驱使我们来写一个HttpUtil类,该类提供一个静态方法供我们使用。
我们先写一个1.0版本的
public class HttpUtil {
public static void sendHttpRequest(final String address) {
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 br = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
} catch (Exception e) {
e.printStaceTrace();
} finally {
if (connection != null)
connection.disconnect();
}
}
}
我们可以这样使用上面的类
String address = "http://www.baidu.com"; String response = HttpUtil.sendHttpRequest(address);
但这会引起一个问题,就是这些代码是在主线程里面执行的,所以可能会引起App的阻塞,出现ANR问题。因为我们并没有在HttpUtil中开启新线程,但是我们也不能直接开启一个新线程,因为这样就不能返回数据了。我们可以用Java的回调机制。
首先需要定义一个接口,比如命名为HttpCallbackListener
public interface HttpCallbackListener { void onFinish(String response); void onError(Exception e); }
接着,修改HttpUtil中的代码,如下
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 br = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
**if (listener != null) {
listener.onFinish(response.toString());
}**
} catch (Exception e) {
**if (listener != null) {
listener.onError(e);
}**
} finally {
if (connection != null)
connection.disconnect();
}
}
}**).start()**;
}
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories