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

3. Android框架和工具之 xUtils(HttpUtils)

2016-04-28 08:24 591 查看
1. HttpUtils 作用:

支持同步,异步方式的请求;

支持大文件上传,上传大文件不会oom;

支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD请求;

下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件;

返回文本内容的GET请求支持缓存,可设置默认过期时间和针对当前请求的过期时间。

2. HttpUtils全面注释:

 /*

/**
* 网络请求工具类
* @author 阿福
*
*/
public class HttpUtils {

public final static HttpCache sHttpCache = new HttpCache();

private final DefaultHttpClient httpClient;
private final HttpContext httpContext = new BasicHttpContext();

private HttpRedirectHandler httpRedirectHandler;

/**
* 构造方法,默认联网15秒超时
*/
public HttpUtils() {
this(HttpUtils.DEFAULT_CONN_TIMEOUT, null);
}

/**
* 构造方法设置超时时间
* @param connTimeout 超时时间毫秒
*/
public HttpUtils(int connTimeout) {
this(connTimeout, null);
}

/**
* 构造方法,浏览器的信息包
* @param userAgent
*/
public HttpUtils(String userAgent) {
this(HttpUtils.DEFAULT_CONN_TIMEOUT, userAgent);
}

/**
* 构造方法
* @param connTimeout 链接超时时间,毫秒单位
* @param userAgent  浏览器的信息包
*/
public HttpUtils(int connTimeout, String userAgent) {
HttpParams params = new BasicHttpParams();

ConnManagerParams.setTimeout(params, connTimeout);
HttpConnectionParams.setSoTimeout(params, connTimeout);
HttpConnectionParams.setConnectionTimeout(params, connTimeout);

if (TextUtils.isEmpty(userAgent)) {
userAgent = OtherUtils.getUserAgent(null);
}
HttpProtocolParams.setUserAgent(params, userAgent);

ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(10));
ConnManagerParams.setMaxTotalConnections(params, 10);

HttpConnectionParams.setTcpNoDelay(params, true);
HttpConnectionParams.setSocketBufferSize(params, 1024 * 8);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", DefaultSSLSocketFactory.getSocketFactory(), 443));

httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(params, schemeRegistry), params);

httpClient.setHttpRequestRetryHandler(new RetryHandler(DEFAULT_RETRY_TIMES));

httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
@Override
public void process(org.apache.http.HttpRequest httpRequest, HttpContext httpContext) throws org.apache.http.HttpException, IOException {
if (!httpRequest.containsHeader(HEADER_ACCEPT_ENCODING)) {
httpRequest.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
}
}
});

httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
@Override
public void process(HttpResponse response, HttpContext httpContext) throws org.apache.http.HttpException, IOException {
final HttpEntity entity = response.getEntity();
if (entity == null) {
return;
}
final Header encoding = entity.getContentEncoding();
if (encoding != null) {
for (HeaderElement element : encoding.getElements()) {
if (element.getName().equalsIgnoreCase("gzip")) {
response.setEntity(new GZipDecompressingEntity(response.getEntity()));
return;
}
}
}
}
});
}

// ************************************    default settings & fields ****************************

private String responseTextCharset = HTTP.UTF_8;

private long currentRequestExpiry = HttpCache.getDefaultExpiryTime();

private final static int DEFAULT_CONN_TIMEOUT = 1000 * 15; // 15s

private final static int DEFAULT_RETRY_TIMES = 3;

private static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
private static final String ENCODING_GZIP = "gzip";

private final static int DEFAULT_POOL_SIZE = 3;
private final static PriorityExecutor EXECUTOR = new PriorityExecutor(DEFAULT_POOL_SIZE);

public HttpClient getHttpClient() {
return this.httpClient;
}

// ***************************************** config *******************************************

/**
* 配置请求文本编码,默认UTF-8
* @param charSet
* @return
*/
public HttpUtils configResponseTextCharset(String charSet) {
if (!TextUtils.isEmpty(charSet)) {
this.responseTextCharset = charSet;
}
return this;
}

/**
* http重定向处理
* @param httpRedirectHandler
* @return
*/
public HttpUtils configHttpRedirectHandler(HttpRedirectHandler httpRedirectHandler) {
this.httpRedirectHandler = httpRedirectHandler;
return this;
}

/**
* 配置http缓存大小
* @param httpCacheSize
* @return
*/
public HttpUtils configHttpCacheSize(int httpCacheSize) {
sHttpCache.setCacheSize(httpCacheSize);
return this;
}

/**
* 配置默认http缓存失效 ,默认是60秒
* @param defaultExpiry
* @return
*/
public HttpUtils configDefaultHttpCacheExpiry(long defaultExpiry) {
HttpCache.setDefaultExpiryTime(defaultExpiry);
currentRequestExpiry = HttpCache.getDefaultExpiryTime();
return this;
}

/**
* 配置当前http缓存失效,时间默认60秒
* @param currRequestExpiry
* @return
*/
public HttpUtils configCurrentHttpCacheExpiry(long currRequestExpiry) {
this.currentRequestExpiry = currRequestExpiry;
return this;
}

/**
* cookie存储配置
* @param cookieStore
* @return
*/
public HttpUtils configCookieStore(CookieStore cookieStore) {
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
return this;
}

/**
* 配置浏览器信息包
* @param userAgent
* @return
*/
public HttpUtils configUserAgent(String userAgent) {
HttpProtocolParams.setUserAgent(this.httpClient.getParams(), userAgent);
return this;
}

/**
* 配置时间链接超时
* @param timeout
* @return
*/
public HttpUtils configTimeout(int timeout) {
final HttpParams httpParams = this.httpClient.getParams();
ConnManagerParams.setTimeout(httpParams, timeout);
HttpConnectionParams.setConnectionTimeout(httpParams, timeout);
return this;
}

/**
* 配置socket时间连接溢出
* @param timeout
* @return
*/
public HttpUtils configSoTimeout(int timeout) {
final HttpParams httpParams = this.httpClient.getParams();
HttpConnectionParams.setSoTimeout(httpParams, timeout);
return this;
}

/**
* 配置注册Scheme
* @param scheme
* @return
*/
public HttpUtils configRegisterScheme(Scheme scheme) {
this.httpClient.getConnectionManager().getSchemeRegistry().register(scheme);
return this;
}

/**
* 配置SSLSocketFactory
* @param sslSocketFactory
* @return
*/
public HttpUtils configSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
Scheme scheme = new Scheme("https", sslSocketFactory, 443);
this.httpClient.getConnectionManager().getSchemeRegistry().register(scheme);
return this;
}

/**
* 配置请求重试次数
* @param count 重试次数
* @return
*/
public HttpUtils configRequestRetryCount(int count) {
this.httpClient.setHttpRequestRetryHandler(new RetryHandler(count));
return this;
}

/**
* 配置请求线程池个数
* @param threadPoolSize 线程池个数
* @return
*/
public HttpUtils configRequestThreadPoolSize(int threadPoolSize) {
HttpUtils.EXECUTOR.setPoolSize(threadPoolSize);
return this;
}

// ***************************************** send request 发送请求*******************************************

/**
* 发送异步网络请求 -重要
* @param method get或者post请求等等
* @param url 网络请求路径
* @param callBack 回调
* @return
*/
public <T> HttpHandler<T> send(HttpRequest.HttpMethod method, String url,
RequestCallBack<T> callBack) {
return send(method, url, null, callBack);
}

/**
* 发送异步网络请求 -重要
* @param method get或者post请求等等
* @param url 网络请求路径
* @param params 请求参数
* @param callBack 回调
* @return
*/
public <T> HttpHandler<T> send(HttpRequest.HttpMethod method, String url, RequestParams params,
RequestCallBack<T> callBack) {
if (url == null) throw new IllegalArgumentException("url may not be null");

HttpRequest request = new HttpRequest(method, url);
return sendRequest(request, params, callBack);
}

/**
* 发送同步网络请求 -用得不多
* @param method get或者post等方法
* @param url 联网网络url
* @return
* @throws HttpException
*/
public ResponseStream sendSync(HttpRequest.HttpMethod method, String url) throws HttpException {
return sendSync(method, url, null);
}

/**
* 发送同步网络请求 -用得不多
* @param method get或者post等方法
* @param url 联网网络url
* @param params 请求参数
* @return
* @throws HttpException
*/
public ResponseStream sendSync(HttpRequest.HttpMethod method, String url, RequestParams params) throws HttpException {
if (url == null) throw new IllegalArgumentException("url may not be null");

HttpRequest request = new HttpRequest(method, url);
return sendSyncRequest(request, params);
}

// ***************************************** download  下载*******************************************

/**
* 下载文件方法
* @param url 下载文件的url
* @param target 下载保存的目录
* @param callback 回调
* @return
*/
public HttpHandler<File> download(String url, String target,
RequestCallBack<File> callback) {
return download(HttpRequest.HttpMethod.GET, url, target, null, false, false, callback);
}

/**
* 下载文件方法
* @param url 下载文件的url
* @param target 下载保存的目录
* @param autoResume 是否自动恢复下载
* @param callback 回调
* @return
*/
public HttpHandler<File> download(String url, String target,
boolean autoResume, RequestCallBack<File> callback) {
return download(HttpRequest.HttpMethod.GET, url, target, null, autoResume, false, callback);
}

/**
* 下载文件方法
* @param url 下载文件的url
* @param target 下载保存的目录
* @param autoResume  是否自动恢复下载
* @param autoRename 是否自动重命名
* @param callback 回调
* @return
*/
public HttpHandler<File> download(String url, String target,
boolean autoResume, boolean autoRename, RequestCallBack<File> callback) {
return download(HttpRequest.HttpMethod.GET, url, target, null, autoResume, autoRename, callback);
}

/**
* 下载文件方法
* @param url 下载文件的url
* @param target 下载保存的目录
* @param params 参数类
* @param callback 回调
* @return
*/
public HttpHandler<File> download(String url, String target,
RequestParams params, RequestCallBack<File> callback) {
return download(HttpRequest.HttpMethod.GET, url, target, params, false, false, callback);
}

/**
* 下载文件方法
* @param url  下载文件的url
* @param target 下载保存的目录
* @param params 参数类
* @param autoResume 是否自动恢复下载
* @param callback 回调
* @return
*/
public HttpHandler<File> download(String url, String target,
RequestParams params, boolean autoResume, RequestCallBack<File> callback) {
return download(HttpRequest.HttpMethod.GET, url, target, params, autoResume, false, callback);
}

/**
* 下载文件方法
* @param url 下载文件的url
* @param target 下载保存的目录
* @param params 参数
* @param autoResume 是否自动恢复
* @param autoRename 是否自动命名
* @param callback 回调
* @return
*/
public HttpHandler<File> download(String url, String target,
RequestParams params, boolean autoResume, boolean autoRename, RequestCallBack<File> callback) {
return download(HttpRequest.HttpMethod.GET, url, target, params, autoResume, autoRename, callback);
}

/**
* 下载文件方法
* @param method 请求用get还是post等
* @param url 下载文件的url
* @param target 下载保存的目录
* @param params 参数
* @param callback 回调
* @return
*/
public HttpHandler<File> download(HttpRequest.HttpMethod method, String url, String target,
RequestParams params, RequestCallBack<File> callback) {
return download(method, url, target, params, false, false, callback);
}

/**
* 下载文件方法
* @param method 请求用get还是post等
* @param url 下载文件的url
* @param target 下载保存的目录
* @param params 参数
* @param autoResume 是否自动恢复下载
* @param callback 回调
* @return
*/
public HttpHandler<File> download(HttpRequest.HttpMethod method, String url, String target,
RequestParams params, boolean autoResume, RequestCallBack<File> callback) {
return download(method, url, target, params, autoResume, false, callback);
}

/**
* 下载文件方法
* @param method 请求用get还是post等
* @param url 下载文件的url
* @param target 下载保存的目录
* @param params 参数
* @param autoResume 是否自动恢复下载
* @param autoRename 是否自动重命名
* @param callback 回调
* @return
*/
public HttpHandler<File> download(HttpRequest.HttpMethod method, String url, String target,
RequestParams params, boolean autoResume, boolean autoRename, RequestCallBack<File> callback) {

if (url == null) throw new IllegalArgumentException("url may not be null");
if (target == null) throw new IllegalArgumentException("target may not be null");

HttpRequest request = new HttpRequest(method, url);

HttpHandler<File> handler = new HttpHandler<File>(httpClient, httpContext, responseTextCharset, callback);

handler.setExpiry(currentRequestExpiry);
handler.setHttpRedirectHandler(httpRedirectHandler);

if (params != null) {
request.setRequestParams(params, handler);
handler.setPriority(params.getPriority());
}
handler.executeOnExecutor(EXECUTOR, request, target, autoResume, autoRename);
return handler;
}

////////////////////////////////////////////////////////////////////////////////////////////////
private <T> HttpHandler<T> sendRequest(HttpRequest request, RequestParams params, RequestCallBack<T> callBack) {

HttpHandler<T> handler = new HttpHandler<T>(httpClient, httpContext, responseTextCharset, callBack);

handler.setExpiry(currentRequestExpiry);
handler.setHttpRedirectHandler(httpRedirectHandler);
request.setRequestParams(params, handler);

if (params != null) {
handler.setPriority(params.getPriority());
}
handler.executeOnExecutor(EXECUTOR, request);
return handler;
}

private ResponseStream sendSyncRequest(HttpRequest request, RequestParams params) throws HttpException {

SyncHttpHandler handler = new SyncHttpHandler(httpClient, httpContext, responseTextCharset);

handler.setExpiry(currentRequestExpiry);
handler.setHttpRedirectHandler(httpRedirectHandler);
request.setRequestParams(params);

return handler.sendRequest(request);
}
}


3. HttpUtils使用post/get 方法访问网络:

(1)新建一个Android工程,命名为"HttpUtils",如下:





(2)首先我们来到主布局文件,如下:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.himi.httputils.MainActivity" >

<Button
android:id="@+id/net"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/replynet" />

<TextView
android:id="@+id/loading"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/success"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</ScrollView>

</LinearLayout>


(3)下面来到AndroidManifest.xml配置文件,添加权限。如下:





(4)来到MainActivity,如下:

 package com.himi.httputils;

import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.lidroid.xutils.view.annotation.event.OnClick;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

@ViewInject(R.id.net)
private Button net;

@ViewInject(R.id.loading)
private TextView loading;

@ViewInject(R.id.success)
private TextView success;

/**
* handler线程是主要用来和UI主线程进行交互的
*//*
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:

break;
default:
break;
}
};
};*/

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.inject(this);
}

@OnClick(R.id.net)
public void reply(View v) {

HttpUtils http = new HttpUtils();
http.send(HttpRequest.HttpMethod.GET, "http://www.lidroid.com", new RequestCallBack<String>() {
@Override
public void onLoading(long total, long current, boolean isUploading) {
System.out.println("数据加载中……");
//System.out.println(current + "/" + total);
loading.setText(current + "/" + total);
}

@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
System.out.println("数据加载完毕……");
//System.out.println(responseInfo.result);
success.setText(responseInfo.result);
}

@Override
public void onStart() {
System.out.println("数据开始加载……");
}

@Override
public void onFailure(HttpException error, String msg) {
System.out.println("数据加载失败……");
}
});

}

}


布署程序到手机中,如下:

我们可以知道使用 HttpUtils 访问网络的时候不用new Thread一个子线程,HttpUtils内部自己实现了子线程。

同时我们在RequestCallBack回调的方法中可以直接操作UI界面的更新。







4. HttpUtils使用Get方法提交数据到服务器:

(1)首先我们搭建一个服务器平台,如下:





(2)我们先看看LoginServlet,如下:

 package web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String qq = request.getParameter("qq");
String password = request.getParameter("password");
System.out.println("qq:"+qq);
System.out.println("password:"+password);

/**
* 模拟服务器操作,查询数据库,看qq和密码是否正确.
* response.getOutputStream()获得一个输出流,向浏览器写入数据(提示数据).
* 这里是输出Output,服务器输出到浏览器
*/
if("10086".equals(qq) && "123456".equals(password)) {
response.getOutputStream().write("Login Success".getBytes());
}else {
response.getOutputStream().write("Login Failed".getBytes());
}

}

}


布署上面的web工程到Tomcat服务器上。





(3)接下来我们来到客户端,我们新建一个Android工程,如下:





(4)首先我们这里写了一个工具类StreamTools,如下:

 package com.himi.httputils01;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

/**
* 流的工具类
* @author Administrator
*
*/
public class StreamTools {
/**
* 把输入流的内容转换成字符串
* @param is
* @return null解析失败, string读取成功
*/
public static String readStream(InputStream is) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
String result = baos.toString();
baos.close();
return result;

}
}


(5)我们首先来到主布局文件activity_main.xml,如下:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="vertical" >

<ImageView
android:layout_width="50dip"
android:layout_height="50dip"
android:src="@drawable/ic_launcher" />

<EditText
android:id="@+id/et_qq"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入qq号码" />

<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:inputType="textPassword" />

<CheckBox
android:id="@+id/cb_remember"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="记住密码"
/>

<Button
android:onClick="login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登陆"

/>
</LinearLayout>


布局效果如下:





(6)接下来我们来到MainActivity,如下:

 package com.himi.httputils01;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
private static final String Tag = "MainActivity";
private EditText et_qq;
private EditText et_pwd;
private CheckBox cb_remember;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 查询关心的控件
et_qq = (EditText) findViewById(R.id.et_qq);
et_pwd = (EditText) findViewById(R.id.et_pwd);
cb_remember = (CheckBox) findViewById(R.id.cb_remember);
Log.i(Tag, "oncreate 被调用");

// 完成数据的回显。
readSavedData();
}

// 读取保存的数据
private void readSavedData() {
// getFilesDir() == /data/data/包名/files/ 获取文件的路径 一般系统是不会清理的。
// 用户手工清理,系统会有提示。
// getCacheDir()== /data/data/包名/cache/ 缓存文件的路径 当系统内存严重不足的时候 系统会自动的清除缓存
// 用户手工清理系统没有提示
File file = new File(getFilesDir(), "info.txt");
if (file.exists() && file.length() > 0) {
try {
// FileInputStream fis = new FileInputStream(file);
FileInputStream fis = this.openFileInput("info.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
// 214342###abcdef
String info = br.readLine();
String qq = info.split("###")[0];
String pwd = info.split("###")[1];
et_qq.setText(qq);
et_pwd.setText(pwd);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* 登陆按钮的点击事件,在点击事件里面获取数据
*
* @param view
*/
public void login(View view) {
final String qq = et_qq.getText().toString().trim();
final String pwd = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(qq) || TextUtils.isEmpty(pwd)) {
Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
return;
}
// 判断用户是否勾选记住密码。
if (cb_remember.isChecked()) {
// 保存密码
Log.i(Tag, "保存密码");
try {
// File file = new File(getFilesDir(),"info.txt");
// FileOutputStream fos = new FileOutputStream(file);
FileOutputStream fos = this.openFileOutput("info.txt", 0);
// 214342###abcdef
fos.write((qq + "###" + pwd).getBytes());
fos.close();
Toast.makeText(this, "保存成功", 0).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "保存失败", 0).show();
}
} else {
// 无需保存密码
Log.i(Tag, "无需保存密码");
}

/**
* 传统方法:使用子线程访问网络
*/
/*new Thread() {
public void run() {
// String path
// ="http://localhost:8080/web/LoginServlet";这里不能写成localhost
try {
String path = getString(R.string.serverip);
URL url = new URL(path + "?qq=" + qq + "&password=" + pwd);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
String result = StreamTools.readStream(is);
showToastInAnyThread(result);
} else {
showToastInAnyThread("请求失败");
}
} catch (Exception e) {
e.printStackTrace();
showToastInAnyThread("请求失败");
}
};

}.start();*/

/**
* 使用HttpUtils Get方式访问网络
*/

HttpUtils http = new HttpUtils();
String path = getString(R.string.serverip);
URL url = null;
try {
url = new URL(path+"?qq="+ qq + "&password="+pwd);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

http.send(HttpRequest.HttpMethod.GET, url.toString(),
new RequestCallBack<String>() {

@Override
public void onFailure(HttpException arg0, String arg1) {
showToastInAnyThread("提交数据失败");

}

@Override
public void onSuccess(ResponseInfo<String> arg0) {
showToastInAnyThread("提交数据成功");

}

});

}

/**
* 显示土司 在主线程更新UI
*
* @param text
*/
public void showToastInAnyThread(final String text) {
runOnUiThread(new Runnable() {

@Override
public void run() {
Toast.makeText(MainActivity.this, text, 0).show();

}
});
}
}


上面使用到res/values/string.xml,如下:

 <?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="app_name">HttpUtils01</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="serverip">http://49.123.72.28:8088/web/LoginServlet</string>

</resources>


(7)这里需要网络权限

(8)布署程序到模拟器上,如下:



输入账号和密码,如下:



保存账号到手机内存data/data/包名/files目录下,如下:





导出info.txt,查看里面内容如下:







我们查看服务器端,说明提交数据到服务器端成功。如下:



5. 使用HttpUtils下载文件

支持断点续传,随时停止下载任务,开始任务

(1)开启Apache服务器,如下:

(2)在Apache服务器安装(解压)目录下htdocs存放文件夹movies,文件夹内部存放一个MP4文件,如下:





(3)新建一个Android工程,如下:





(4)首先我们来到主布局文件,如下:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<Button
android:text="下载"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:onClick="download" />
<Button
android:text="取消"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:onClick="cancel_download" />

<TextView
android:id="@+id/tv_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="提示信息" />

</LinearLayout>


(5)这里需要使用 网络,则在AndroidManifest.xml中添加相应的权限,如下:

 <uses-permission android:name="android.permission.INTERNET"/>


(6)接着,我们来到MainActivity,如下:

 package com.himi.httputils02;

import java.io.File;

import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.HttpHandler;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {

private TextView tv;

private HttpHandler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

tv = (TextView) findViewById(R.id.tv_info);
}

public void download(View v) {
String download_url = getString(R.string.source_url);
String target_url = getString(R.string.target_url);
HttpUtils http = new HttpUtils();
/**
* 下载文件方法
*
* @param url
*            下载文件的url
* @param target
*            下载保存的目录
* @param autoResume
*            是否自动恢复下载
* @param autoRename
*            是否自动重命名
* @param callback
*            回调
* @return
*/
handler = http.download(download_url, target_url, true, // 如果目标文件存在,接着未完成的部分继续下载。服务器不支持RANGE时将从新下载。
true, // 如果从请求返回信息中获取到文件名,下载完成后自动重命名。
new RequestCallBack<File>() {

@Override
public void onStart() {
tv.setText("conn...");
}

@Override
public void onLoading(long total, long current, boolean isUploading) {
//当然这里也可以使用进度条
tv.setText(current + "/" + total);

}

@Override
public void onSuccess(ResponseInfo<File> responseInfo) {
tv.setText("downloaded:" + responseInfo.result.getPath());
}

@Override
public void onFailure(HttpException error, String msg) {
tv.setText(msg);
}
});
}

public void cancel_download(View v){
//调用cancel()方法停止下载
handler.cancel();
tv.setText("It's canceled");
}

}


(7)布署程序到模拟器上,如下:

点击"下载",等待下载成功。



我们追踪data/data/com.himi.httputils02/files/video.mp4,如下:







点击"下载",没有下载完,就点击"取消".





观察比较下载中断之后的数据和原来服务器端的数据的大小,结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: