Android okhttp3的使用

1、在模块中下载或者添加依赖:

implementation 'com.squareup.okhttp3:okhttp:4.7.2'

当你看到这的时候,可能最新的稳定版已经不是3.10.0了,你需要移步官方GitHub来查看最新版本。 官方地址 https://github.com/square/okhttp,另外不要忘了在清单文件声明访问Internet的权限,如果使用 DiskLruCache,那还得声明写外存的权限。

2、okhttp使用

a、异步GET请求

-new OkHttpClient;
-构造Request对象;
-通过前两步中的对象构建Call对象;
-通过Call#enqueue(Callback)方法来提交异步请求;

String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
        .url(url)
        .get()//默认就是GET请求,可以不写
        .build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: ");
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d(TAG, "onResponse: " + response.body().string());
    }
});

b、同步GET请求

前面几个步骤和异步方式一样,只是最后一部是通过 Call#execute() 来提交请求,注意这种方式会阻塞调用线程,所以在Android中应放在子线程中执行,否则有可能引起ANR异常,Android3.0 以后已经不允许在主线程访问网络。

String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
        .url(url)
        .build();
final Call call = okHttpClient.newCall(request);
new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Response response = call.execute();
            Log.d(TAG, "run: " + response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

c、POST方式提交String

这种方式与前面的区别就是在构造Request对象时,需要多构造一个RequestBody对象,用它来携带我们要提交的数据。在构造 RequestBody 需要指定MediaType,用于描述请求/响应 body 的内容类型,关于 MediaType 的更多信息可以查看 RFC 2045,RequstBody的几种构造方式:

MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
String requestBody = "I am Jdqm.";
Request request = new Request.Builder()
        .url("https://api.github.com/markdown/raw")
        .post(RequestBody.create(mediaType, requestBody))
        .build();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: " + e.getMessage());
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d(TAG, response.protocol() + " " +response.code() + " " + response.message());
        Headers headers = response.headers();
        for (int i = 0; i < headers.size(); i++) {
            Log.d(TAG, headers.name(i) + ":" + headers.value(i));
        }
        Log.d(TAG, "onResponse: " + response.body().string());
    }
});

响应内容

http/1.1 200 OK 
Date:Sat, 10 Mar 2018 05:23:20 GMT 
Content-Type:text/html;charset=utf-8
Content-Length:18
Server:GitHub.com 
Status:200 OK 
X-RateLimit-Limit:60
X-RateLimit-Remaining:52
X-RateLimit-Reset:1520661052
X-CommonMarker-Version:0.17.4
Access-Control-Expose-Headers:ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval

Access-Control-Allow-Origin:*
Content-Security-Policy:default-src 'none'
Strict-Transport-Security:max-age=31536000; includeSubdomains; preload 
X-Content-Type-Options:nosniff 
X-Frame-Options:deny 
X-XSS-Protection:1; mode=block 
X-Runtime-rack:0.019668
Vary:Accept-Encoding 
X-GitHub-Request-Id:1474:20A83:5CC0B6:7A7C1B:5AA36BC8 
onResponse: <p>I am Jdqm.</p>

d、POST方式提交流

RequestBody requestBody = new RequestBody() {
    @Nullable
    @Override
    public MediaType contentType() {
        return MediaType.parse("text/x-markdown; charset=utf-8");
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        sink.writeUtf8("I am Jdqm.");
    }
};

Request request = new Request.Builder()
        .url("https://api.github.com/markdown/raw")
        .post(requestBody)
        .build();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: " + e.getMessage());
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d(TAG, response.protocol() + " " +response.code() + " " + response.message());
        Headers headers = response.headers();
        for (int i = 0; i < headers.size(); i++) {
            Log.d(TAG, headers.name(i) + ":" + headers.value(i));
        }
        Log.d(TAG, "onResponse: " + response.body().string());
    }
});

e、POST提交文件

MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
OkHttpClient okHttpClient = new OkHttpClient();
File file = new File("test.md");
Request request = new Request.Builder()
        .url("https://api.github.com/markdown/raw")
        .post(RequestBody.create(mediaType, file))
        .build();
okHttpClient.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: " + e.getMessage());
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d(TAG, response.protocol() + " " +response.code() + " " + response.message());
        Headers headers = response.headers();
        for (int i = 0; i < headers.size(); i++) {
            Log.d(TAG, headers.name(i) + ":" + headers.value(i));
        }
        Log.d(TAG, "onResponse: " + response.body().string());
    }
});

f、POST方式提交表单

OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()
        .add("search", "Jurassic Park")
        .build();
Request request = new Request.Builder()
        .url("https://en.wikipedia.org/w/index.php")
        .post(requestBody)
        .build();

okHttpClient.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: " + e.getMessage());
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d(TAG, response.protocol() + " " +response.code() + " " + response.message());
        Headers headers = response.headers();
        for (int i = 0; i < headers.size(); i++) {
            Log.d(TAG, headers.name(i) + ":" + headers.value(i));
        }
        Log.d(TAG, "onResponse: " + response.body().string());
    }
});

提交表单时,使用 RequestBody 的实现类FormBody来描述请求体,它可以携带一些经过编码的 key-value 请求体,键值对存储在下面两个集合中:

  private final List<String> encodedNames;
  private final List<String> encodedValues;

 

3、封装okhttp

a、定义接口OnFunHttpCallBack

public interface OnFunHttpCallBack {

	void onFailure(int errorCode);

	void onSuccess(String url, String result);

}

b、HttpMethod.java

//okhttp3封装
public class HttpMethod {

	private final static String TAG = HttpMethod.class.getSimpleName();
	private final static int TIME = 10000;
	public final static int NETWORK_ACCESS_ERROR = 0x0001;
	public final static int SERVER_BACK_ERROR = 0x0002;
	private static HttpMethod m_instance = null;
	private static OkHttpClient m_okHttpClient = null;

	/**
	 * 单一实例
	 */
	public static HttpMethod getInstance() {
		if (m_instance == null) {
			m_instance = new HttpMethod();
			if (m_okHttpClient == null) {
				m_okHttpClient = new OkHttpClient();
				//m_okHttpClient = new OkHttpClient.Builder().connectTimeout(TIME, TimeUnit.SECONDS).readTimeout(TIME, TimeUnit.SECONDS).build();
			}
		}
		return m_instance;
	}

	private class HttpCallback {

		private String m_strUrl = "";
		private OnFunHttpCallBack m_back_http = null; //任务的回调函数

		public HttpCallback(String url, OnFunHttpCallBack back) {
			m_strUrl = url;
			m_back_http = back;
		}

		/**
		 * AsyncHttp的回调函数
		 */
		private Callback m_handler = new Callback() {

			@Override
			public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
				if(response.code() == 200){
					String result = response.body().string();
					if(m_back_http != null){
						m_back_http.onSuccess(m_strUrl, result);
					}
					if (response.body()!=null){
						response.body().close();
					}
					Log.i(TAG, "HTTP-Response-Url: " + m_strUrl + "-----" + result);
				}else{
					if(m_back_http != null){
						m_back_http.onFailure(SERVER_BACK_ERROR);
					}
					Log.e(TAG, "HTTP-Request-Url: " + m_strUrl + " 服务器错误(Server error) " + response.code());
				}
			}

			@Override
			public void onFailure(@NotNull Call call, @NotNull IOException e) {
				if(m_back_http != null){
					m_back_http.onFailure(NETWORK_ACCESS_ERROR);
				}
				Log.e(TAG, "HTTP-Request-Url: " + m_strUrl + " 访问失败(Access failed)");
			}
		};
	}

	/**
	 * 异步GET请求
	 * 
	 * @param url
	 *            发送请求的URL
	 * @param para
	 *            请求参数,请求参数应该是name1=value1&name2=value2的形式。
	 * @return URL所代表远程资源的响应
	 */
	public void clientGet(String url, String para, OnFunHttpCallBack back) {
		Log.i(TAG, "HTTP-Request-Url: " + url + "?" + para);
		String reqUrl = url;
		if(para != null && !para.equals("")){
			reqUrl = url + "?" + para;
		}
		//执行get方法
		Request request = new Request.Builder()
				.url(reqUrl)
				.get()//默认就是GET请求,可以不写
				.build();
		m_okHttpClient.newCall(request).enqueue(new HttpCallback(url, back).m_handler);
	}

	/**
	 * POST方式提交表单
	 *
	 * @param url
	 *            发送请求的URL
	 * @param para
	 *            请求参数,请求参数应该是name1=value1&name2=value2的形式。
	 * @return URL所代表远程资源的响应
	 */
	public void clientPost(String url, String para, OnFunHttpCallBack back) {
		Log.i(TAG, "HTTP-Request-Url: " + url + "?" + para);
		String[] tmp1 = null;
		String[] tmp2 = null;
		int size = 0;
		//构建表单参数
		FormBody.Builder requestBuild=new FormBody.Builder();
		//解析出各个参数
		if (para != null && !para.equals("")) {
			tmp1 = para.split("&");
			size = tmp1.length;
			for (int i = 0; i < size; i++) {
				tmp2 = tmp1[i].split("=");
				if (tmp2.length != 2) {
					//return;
					continue;
				}
				//设置请求的参数名和参数值
				requestBuild.add(tmp2[0], tmp2[1]);
			}
		}
		//执行post方法
		Request request = new Request.Builder()
				.url(url)
				.post(requestBuild.build())
				.build();
		m_okHttpClient.newCall(request).enqueue(new HttpCallback(url, back).m_handler);
	}

	/**
	 * post文件上传
	 * 
	 * @param url
	 *            url
	 * @param file
	 *            文件
	 * @param back
	 *            回调接口
	 */
	public void upLoad(String url, File file, OnFunHttpCallBack back) {
		MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
		Request request = new Request.Builder()
				.url(url)
				.post(RequestBody.create(file, mediaType))
				.build();
		m_okHttpClient.newCall(request).enqueue(new HttpCallback(url, back).m_handler);
	}
}

c、HttpTask.java

public class HttpTask {

	private String m_strUrl = "";
	private String m_strPara = "";
	private File m_file = null;
	private OnFunHttpCallBack m_back_http = null;// 任务的回调函数

	public HttpTask(String url, String para, OnFunHttpCallBack back) {
        m_strUrl = url;
        m_strPara = para;
        m_back_http = back;
    }

    public HttpTask(String url, File file, OnFunHttpCallBack back) {
        m_strUrl = url;
        m_file = file;
        m_back_http = back;
    }

	public void runPost() {
		HttpMethod.getInstance().clientPost(m_strUrl, m_strPara, m_back_http);
	}

	public void runGet() {
		HttpMethod.getInstance().clientGet(m_strUrl, m_strPara, m_back_http);
	}

	public void upLoad() {
		HttpMethod.getInstance().upLoad(m_strUrl, m_file, m_back_http);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值