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

网络连接之Http及异步操作AsyncTask

2015-08-13 09:52 585 查看
Http个人理解为是基于请求、响应,无状态,应用层的超文本传输协议。其特点有:支持客户端与服务器之间交互模式;简单快捷;灵活;无连接;无状态。

引用具体介绍:(想要更深入的了解可以参考下面的网站:http://www.360doc.com/content/10/0930/17/3668821_57590979.shtml

Http介绍:HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。

HTTP协议的主要特点可概括如下:

1.支持客户/服务器模式。

2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

在使用网络连接前我们要在AndroidManifest.xml中注册相应的权限,将其放在application和manifest之间,也就是说和application是并列的权限,其代码如下所示:

<span style="font-size:18px;"><uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</span>


在实际连网之前要先检查当前的网络环境是否可用,其代码如下所示:

<span style="font-size:18px;">ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
//网络连接可用
} else {
//网络连接不可用!
}
</span>


网络操作会遇到不可预期的延迟。显然为了避免一个不好的用户体验,总是在UI Thread之外去执行网络操作。AsyncTask 类提供了一种简单的方式来处理这个问题

doInBackground()) 执行 downloadUrl()方法。Web URL作为参数,方法downloadUrl() 获取并处理网页返回的数据,执行完毕后,传递结果到onPostExecute()。参数类型为String.onPostExecute()) 获取到返回数据并显示到UI上。其相关代码如下所示:

<span style="font-size:18px;">private class DownloadWebpageText extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {

// 参数从execute()方法传入, params[0]表示url.
//获取url资源数据并返回
}

// onPostExecute方法中处理AsyncTask返回的结果
@Override
protected void onPostExecute(String result) {

}

}
</span>


下面为实例的代码,在xml布局中只放置了两个Button分别用于不同的连接获取方式和一个TextView用于显示获取到的内容,此处获取到的图片资源暂时没有解析显示,其具体的代码如下所示:

<span style="font-size:18px;">package com.sc.android.httpcoliect;
/**
* 由于此处没有学习图片的解析,所以图片的内容没有显示出来
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.Button;

import com.sc.android.R;
import com.sc.android.util.Logs;

public class HttpActivity extends Activity {
private Button mHttpContentBtn, mHttpUrlBtn;
private WebView mHttpWebView;//用于显示读取到的Url连接内容
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_http_layout);

mHttpContentBtn = (Button) findViewById(R.id.http_client_btn);
mHttpUrlBtn = (Button) findViewById(R.id.http_url_btn);
mHttpWebView = (WebView) findViewById(R.id.http_webview);

mHttpContentBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//htmlUrl是Tomcat服务器中自己写的html布局信息
String htmlUrl = "http://192.168.1.153:8080/html/login.html";
new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
String url = params[0];

return getHttpClient(url);
}
protected void onPostExecute(String result) {
if (result != null) {
Logs.v("服务端返回的信息是  :" + result);

mHttpWebView.loadData(result,
"text/html; charset=UTF-8", null);

}
}

}.execute(htmlUrl);

}
});
mHttpUrlBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
String htmlUrl = "http://www.baidu.com";
new AsyncTask<String, Void, String>() {

@Override
protected String doInBackground(String... params) {
String url = params[0];

return getDataByHttpUrlConnection(url);
}

protected void onPostExecute(String result) {
if (result != null) {
Logs.v("服务端返回的信息是  :" + result);

mHttpWebView.loadData(result,
"text/html; charset=UTF-8", null);
}
}
}.execute(htmlUrl);
}
});
}
public String getHttpClient(String httpUrl) {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(httpUrl);
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
//HttpURLConnection.HTTP_OK即200响应码
if (statusCode == HttpURLConnection.HTTP_OK) {
InputStream ins = response.getEntity().getContent();
//将读取到的信息转换成utf-8编码
BufferedReader br = new BufferedReader(new InputStreamReader(
ins, "utf-8"));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return null;
}

/**
* 从网络获取数据通过HttpURLConnection方式实现 Get
*/
private String getDataByHttpUrlConnection(String url1) {
StringBuffer sb = null;
InputStream is = null;
BufferedReader br = null;
HttpURLConnection conn = null;
OutputStream os = null;
BufferedWriter bw = null;
try {
// 封装访问服务器的地址
URL url = new URL(url1);
// 打开对服务器的连接
conn = (HttpURLConnection) url.openConnection();
// 设置输入输出流
// conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("GET");
// 连接服务器
conn.connect();

/** 读入服务器数据的过程 **/
// 得到输入流
is = conn.getInputStream();
// 创建包装流
br = new BufferedReader(new InputStreamReader(is, "utf-8"));
// 定义String类型用于储存单行数据
String line = null;
// 创建StringBuffer对象用于存储所有数据
sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
conn.disconnect();
if (bw != null) {
bw.close();
}
if (os != null) {
os.close();
}
if (br != null) {
br.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}

}
</span>


其效果显示如下:





用getHttpClient方式获取网络资源是有可能会解析出错或解析不出来的情况。由于刚接触,有错的地方请见谅。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: