您的位置:首页 > 理论基础 > 计算机网络

【Android】网络通讯

2015-08-21 19:25 483 查看
看完了Android存储方面的内容,由于之前自己对数据存储方面有自己写过小封装,Android提供的api也都比较简单,所以就不打算再重新写了。今天看了下关于网络通讯方面的内容,进步加深对网络方面的一个理解,写下自己的理解,和一些基本的操作,这样方便以后在遇到一些基础的问题的时候,不需要自己谷歌,通过博客就可以很好地找到,提升效率。

网络通讯

1.网络通讯流程

2.WebView

3.HttpURLConnection

4.HttpClient

5.数据解析

5.1XML
5.2Json
5.3Gson


6.线程间通过监听器回调传递数据

网络通讯流程

网络通讯,就是我们使用http协议实现本地端和服务器之间进行交互。通讯的第一步,就是发送请求。第二步,服务器接受我们的请求,进行相应的处理,然后返回我们通过请求希望得到的数据。第三步,返回的数据是按照一定的格式反馈给我们的,然后本地对这种格式进行一个解析,这样网络通讯的整个流程就结束了。

WebView

在应用中,我们可能需要展示一个网页,如果是调起本地浏览器,用户体验势必会很差,为了解决这个问题,Android提供了Webview

这个控件,通过这个控件,我们只需要提供一个url,我们就可以得到一个解析好的页面。

public void showWebPage(URL url){
WebView mwebView = (WebView)findViewById(R.id.webpage);
mwebView.getSettings().getJavaScriptEnabled();
mwebView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
//返回为true,表示不再重新开启浏览器
return true;
}
});
mwebView.loadUrl(url.toString());
}


HttpURLConnection

public void sendRequestByHttpUrlConnection(){
try {
URL url = new URL("http://www.baidu.com");
//根据url建立连接
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
//连接请求的属性设置
connection.setRequestMethod("GET");
connection.setConnectTimeout(500);
connection.setReadTimeout(500);
//获得返回数据的流
InputStream stream = connection.getInputStream();
//关闭连接
connection.disconnect();
}catch (MalformedURLException e){

}catch (IOException e){

}

}


上面演示的是通过get发送请求,发送请求之后,我们获得一个输入流,通过这个流,我们可以实现接收网络流过来的数据。如何携带数据到我们请求的地址呢?通过post进行网络的请求,建立一个输出流,对我们请求地址的一个输出流,然后通过这个流,传递我们的一些信息。

DataOutputStream stream1 = new DataOutputStream(connection.getOutputStream());
stream1.writeBytes("name=admin&password=234");


到这里,就介绍完了通过HttpUrlConnection进行通讯方式了,从中可以看出一个问题就是在使用post进行请求的提交的时候,写起来不是很清晰,但是官方最终继续开始维护,而放弃了之前的HttpClient。不过现在最多用的就是官方提供的volley框架。

HttpClient

Android系统还提供了一个接口,httpClient,这个应该是最初使用的进行网络传输的。之前进行一些网络请求的时候也是采用的这个。因为这个是一个接口,无法创建其实例。通常会采用实现了该接口的DefaultHttpClient。然后根据我们的请求类型,创建相应的请求类型,通过client执行得到响应实体,将实体进行处理。

进行get请求

HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://www.baidu.com");
httpClient.execute(httpGet);


进行post请求

HttpClient httpClient = new DefaultHttpClient();
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"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");
httpPost.setEntity(entity);
HttpResponse httpResponse = httpClient.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity);
}


上面只是对相应的类进行了一个api的罗列,现在也逐渐意识到,编程只是在对一堆的接口进行罗列,当然能够看懂api也可以算的上是一种能力,但是,如果去学这个技术,我们要做的不是去背这个api,看一遍,大体上知道个操作流程,具体的api,就可以等到有实际应用的时候再去具体的研究。仔细的看在使用中去进一步的学习,同时更清晰记住。那我们所要学的就是一些实现机制,偏向底层的东西,设计模式,算法(这个特别是在一些较为复杂的逻辑处理上是比较有用的),这样我们在写程序的时候,大脑中的思路就会很清晰的知道哪一步该做什么,该用到什么,出现一些问题,也能够很好地解决。

数据解析

在请求之后,我们得到了数据返回的数据,我们要进行的下一步就是根据其指定的格式,对其进行相应的解析,然后将数据应用到我们的程序之中。常用的数据传输格式有xml,json,json体积较为小,比较适合网络传输,但是语义表达能力不如xml,但是一些很好地json解析库很好的解决了这个问题,比如谷歌官方的Gson等。将json数据映射到对象。

XML

xml的解析方式有两种一个是SAX,另一种是Pull,考虑到其应用没有json那么广泛,所以不准备对其进行深入的研究,准备研究下json,和json的这个大名鼎鼎的解析框架Gson。

Json

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。

Android提供了JsonObject来进行Json的解析操作,下面是一个用JsonObject解析的例子:

这里的jsonData是一个字符串,作为字符串传入

JSONArray jsonArray = new JSONArray(jsonData);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String version = jsonObject.getString("version");


下面重点来了Gson

Gson的强大之处在于可以将我们的json数据,映射到我们的一个类上,对于与各个类的字段。而不需要我们对json进行解析,然后在通过循环分配。

单一数据处理

{"name":"Tom","age":20}
Gson gson = new Gson();
Person person = gson.fromJson(jsonData, Person.class);


json数组处理

List<Person> people = gson.fromJson(jsonData, new TypeToken<List<Person>>() {}.getType());


通过TypeToken匿名类,向fromJson传递json数据所要映射到的类型是什么,这样我们就可以将列表中的数据拿出来就是我们所要用的对象,而且携带者数据。简短几行就解决掉了我们复杂的json解析处理问题。当然,我们还是需要建立一个类,用这个类来作为json数据的映射。后续将对Gson和Volley框架进行进一步的详细学习,使用和机制,源码阅读。这里只是浅浅的提一下其概念和基础应用。

监听回调机制

之前,一直比较好奇,监听类和回调函数的实现,今天的学习中遇到了这个问题,要解决的问题是如何在一个持有子线程类中将数据传递到主线程中,当然我们可以通过携带handler过去,然后将消息传递出来,今天在书上看到的一个实现是通过自己的一个监听类,然后在对持有子线程的类的调用的时候,实现一个匿名类对象传递过去,然后在另一个线程中根据相应的逻辑执行时间点,调用对象的相应方法,从而实现所谓的回调。

引用《第一行代码》上一个实例(很不错的一本书)

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


HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {
@Override
public void onFinish(String response) { // 在这里根据返回内容执行具体的逻辑
}
@Override
public void onError(Exception e) {
// 在这里对异常情况进行处理 }
});




现在也是逐渐体会到这个曲线的含义了,感觉懂了一些设计模式之后,自我评估真的是指数爆炸式增长。

接下来更新Gson,Volley,自定义View,碎片等
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: