今天主要跟大家说一下这个网络请求框架OKHttp
首先给大家推荐两个很好的博客(掘金):
android:name="android.permission.INTERNET"/>
new Thread() {
@Override
public void run() {
//1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
//2.通过build来创建一个Request请求,
// 没有设置get方法,而是直接设置一个url地址,默认就是一个get方式的请求.
final Request request = new Request.Builder()
.url(path)//这是一个接口地址
.build();
//3.创建一个call对象,参数就是Request请求对象,发送请求
Call call = okHttpClient.newCall(request);
//4.请求加入调度
try {
Response response = call.execute();
Log.d("get",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
二:get的异步请求:(不会阻塞线程)
new Thread() {
@Override
public void run() {
//1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
//2.通过build来创建一个Request请求,
// 没有设置get方法,而是直接设置一个url地址,默认就是一个get方式的请求.
final Request request = new Request.Builder()
.url(path)
.build();
//3.创建一个call对象,参数就是Request请求对象,发送请求
Call call = okHttpClient.newCall(request);
//4.请求加入调度
call.enqueue(new Callback() {
@Override //请求失败执行的方法
public void onFailure(Call call, IOException e) {
}
//请求成功执行的方法
// response就是从服务器得到的参数
@Override
public void onResponse(Call call, Response response) throws IOException {
//response.body()可以得到任意类型,字符串,字节,等等.
htmlStr = response.body().string();
handler.sendEmptyMessage(0);//这里为了和上面区分开直接修改的TextView
//注意:需要创建handler接受请求参数并显示
}
});
}
}.start();
(post请求这里先不说了,基本和get一样,get不需要设置,默认就是get,而post需要设置一下:下面的上传图片中就用的post请求)
//通过点击事件,异步网络请求,拿到返回String数据,并进行本地缓存
new Thread(){
@Override
public void run() {
//缓存大小
int cacheSize=10*1024*1024;//10mb
//创建cache对象,文件寻访到私有目录
Cache cache = new Cache(getCacheDir(), cacheSize);
//创建okhttpClint对象,进行本地缓存设置
OkHttpClient okHttpClient = new OkHttpClient.Builder().cache(cache).build();
Request.Builder builder = new Request.Builder();
Request.Builder url = builder.url(path);
Request request = url.build();
//创建call对象
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
//失败回调
@Override
public void onFailure(Call call, IOException e) {
}
//成功回调
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
}.start();
break;
四:下载图片:
new Thread(){
@Override
public void run() {
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url(path).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override//成功
public void onResponse(Call call, Response response) throws IOException {
byte[] bytes = response.body().bytes();
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
runOnUiThread(new Runnable() {
@Override
public void run() {
mImageViewOkhttp.setImageBitmap(bitmap);
//这里我直接设置给ImageView显示
}
});
}
});
}
}.start();
五:上传图片:
/**
* 当按钮点击时,执行okhttp上传图片到服务器
*注意:有时候上传图片失败,是服务器规定还要上传一个key;
*/
//图片上传的接口地址
String url="http://123.206.14.104:8080/FileUploadDemo/FileUploadServlet";
//创建上传文件的对象
File file = new File(Environment.getExternalStorageDirectory(), "big.jpg");
//创建RequestBody封装参数
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
//创建MultipartBody,给MultipartBody进行设置
MultipartBody multipartBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", "big.jpg", fileBody)
.build();
/**
* GET上传的数据一般是很小的并且安全性能不高的数据,
* 而POST上传的数据适用于数据量大,数据类型复杂,数据安全性能要求高的地方
*/
//创建okhttp对象
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.build();
//创建Request对象
Request request = new Request.Builder()
.url(url)
.post(multipartBody)
.build();
//上传完图片,得到服务器反馈数据
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String string = response.body().string();
//上传到服务器后,我们需要检查一下服务器有没有接受到,需要再请求一下,进行打印输出
}
});
break;
下面说一下网络框架封装工具类:
* 1.代码重复的多,使用过于冗余
* 2.不用开子线程,直接就可以在主线程中使用我们的工具类来完成需求
* 因此我们也不必要在使用过程中不必做线程间的交互,因此逻辑更简单
* 3.节约内存,使所有网络请求都共用一个okhttpclient对象和handler对象
封装之前还需要注意的:
* 封装网络框架:
* 1.每个网络框架,都有自己的特点,所以封装各不相同,因此在封装网络框架之前,要充分了解
* 所封装的网络框架;
* 2.解决代码冗余,我们可以根据自己的思路去对他安装自己的需求;
* 3.封装完,网络框架性能要更优化,节约内存,逻辑处理变得简单(扁平化)
在封装OKHttp网络框架工具类时首先用到了几点:
public class OkHttpUtils
{
public static final long DEFAULT_MILLISECONDS = 10_000L;
private volatile static OkHttpUtils mInstance;
private OkHttpClient mOkHttpClient;
private Platform mPlatform;
public OkHttpUtils(OkHttpClient okHttpClient)
{
if (okHttpClient == null)
{
mOkHttpClient = new OkHttpClient();
} else
{
mOkHttpClient = okHttpClient;
}
mPlatform = Platform.get();
}
public static OkHttpUtils initClient(OkHttpClient okHttpClient)
{
if (mInstance == null)
{
synchronized (OkHttpUtils.class)
{
if (mInstance == null)
{
mInstance = new OkHttpUtils(okHttpClient);
}
}
}
return mInstance;
}
public static OkHttpUtils getInstance()
{
return initClient(null);
}
public Executor getDelivery()
{
return mPlatform.defaultCallbackExecutor();
}
public OkHttpClient getOkHttpClient()
{
return mOkHttpClient;
}
public static GetBuilder get()
{
return new GetBuilder();
}
public static PostStringBuilder postString()
{
return new PostStringBuilder();
}
public static PostFileBuilder postFile()
{
return new PostFileBuilder();
}
public static PostFormBuilder post()
{
return new PostFormBuilder();
}
public static OtherRequestBuilder put()
{
return new OtherRequestBuilder(METHOD.PUT);
}
public static HeadBuilder head()
{
return new HeadBuilder();
}
public static OtherRequestBuilder delete()
{
return new OtherRequestBuilder(METHOD.DELETE);
}
public static OtherRequestBuilder patch()
{
return new OtherRequestBuilder(METHOD.PATCH);
}
public void execute(final RequestCall requestCall, Callback callback)
{
if (callback == null)
callback = Callback.CALLBACK_DEFAULT;
final Callback finalCallback = callback;
final int id = requestCall.getOkHttpRequest().getId();
requestCall.getCall().enqueue(new okhttp3.Callback()
{
@Override
public void onFailure(Call call, final IOException e)
{
sendFailResultCallback(call, e, finalCallback, id);
}
@Override
public void onResponse(final Call call, final Response response)
{
try
{
if (call.isCanceled())
{
sendFailResultCallback(call, new IOException("Canceled!"), finalCallback, id);
return;
}
if (!finalCallback.validateReponse(response, id))
{
sendFailResultCallback(call, new IOException("request failed , reponse's code is : " + response.code()), finalCallback, id);
return;
}
Object o = finalCallback.parseNetworkResponse(response, id);
sendSuccessResultCallback(o, finalCallback, id);
} catch (Exception e)
{
sendFailResultCallback(call, e, finalCallback, id);
} finally
{
if (response.body() != null)
response.body().close();
}
}
});
}
public void sendFailResultCallback(final Call call, final Exception e, final Callback callback, final int id)
{
if (callback == null) return;
mPlatform.execute(new Runnable()
{
@Override
public void run()
{
callback.onError(call, e, id);
callback.onAfter(id);
}
});
}
public void sendSuccessResultCallback(final Object object, final Callback callback, final int id)
{
if (callback == null) return;
mPlatform.execute(new Runnable()
{
@Override
public void run()
{
callback.onResponse(object, id);
callback.onAfter(id);
}
});
}
public void cancelTag(Object tag)
{
for (Call call : mOkHttpClient.dispatcher().queuedCalls())
{
if (tag.equals(call.request().tag()))
{
call.cancel();
}
}
for (Call call : mOkHttpClient.dispatcher().runningCalls())
{
if (tag.equals(call.request().tag()))
{
call.cancel();
}
}
}
public static class METHOD
{
public static final String HEAD = "HEAD";
public static final String DELETE = "DELETE";
public static final String PUT = "PUT";
public static final String PATCH = "PATCH";
}
}
上面的代码中涉及到几个常用的类:Request、Response和Call。