emm这篇文章很久就开始写了,每次写到一半都忘记保存哭死,现在重新开始写吧。
OkHttp简介
OkHttp是一个优秀的网络请求框架,它使用建造者模式来对网络进行请求。
OkHttp使用
1.添加OkHttp依赖:
2.构造OkHttpClient对象
3.构造Request对象
Request对象包括:
- URL
- method
- headers
- body
4.将Request封装成call
5.同步请求||异步请求
同步请求会一直等待网络响应,是阻塞式的;异步请求会接着往下执行,网络响应之后会调用回调方法。其中onResponse()方法中的response对象封装着返回的网络响应。
Response对象中包含:
- code
- headers
- body
同步调用:
Response response=call.execute();
异步调用:
需要注意的是,主线程一般用于更新UI操作,所以同步调用会阻塞主线程,一般不适用。
异步调用的回调函数是在子线程,我们不能在子线程更新UI,需要借助于runOnUiThread()
方法或者Handler
来处理。
因为下面的例子没有更新UI操作,所以没有用Handler。
异步Get请求:
异步post请求:
这和异步Get请求相似,只是多了用FormBody来封装请求的参数。并传递给Request。这里的post参数是通过构造一个FormBody通过键值对的方式添加进去的。
异步post请求提交字符串:
有时候我们常常会遇到要传入一个字符串的需求,比如客户端给服务器发送一个json字符串,那这种时候就需要用到另一种方式来构造一个RequestBody
如下所示:
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"), "{username:admin;password:admin}");
异步post请求上传文件:
private void put() {
String filepath="";
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
filepath=Environment.getExternalStorageDirectory().getAbsolutePath();
}else{
return;
}
String data="xqyhahaha";
File file=new File(filepath,"wangshu.txt");
try {
FileWriter fileWriter=new FileWriter(file.getName(),true);
fileWriter.write(data);
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
Request request=new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN,file))
.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG,response.body().string());
}
});
}
我在这里遇到一个问题,就是wangshu.txt这个文件里面的内容总是写不进去。
异步Post请求提交表单:
File file = new File(Environment.getExternalStorageDirectory(), "1.png");
if (!file.exists()){
Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();
return;
}
RequestBody muiltipartBody = new MultipartBody.Builder()
//一定要设置这句
.setType(MultipartBody.FORM)
.addFormDataPart("username", "admin")//
.addFormDataPart("password", "admin")//
.addFormDataPart("myfile", "1.png", RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
(1)如果提交的是表单,一定要设置setType(MultipartBody.FORM)
这一句
(2)提交的文件addFormDataPart()
的第一个参数,就上面代码中的myfile
就是类似于键值对的键,是供服务端使用的,就类似于网页表单里面的name
属性,例如下面:
<input type="file" name="myfile">
复制代码
(3)提交的文件addFormDataPart()
的第二个参数文件的本地的名字,第三个参数是RequestBody
,里面包含了我们要上传的文件的路径以及MidiaType
(4)记得在AndroidManifest.xml
文件中添加存储卡读写权限
异步post下载文件:
private void dowanload()
{
OkHttpClient client=new OkHttpClient();
final Request request=new Request.Builder()
.get()
.url("https://www.baidu.com/img/bd_logo1.png")
.build();
Call call =client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is=response.body().byteStream();
// int len=0;
// File file=new File(Environment.getExternalStorageState(),"n.png");
// FileOutputStream fos=new FileOutputStream(file);
// byte[] buf=new byte[128];
//
// while((len=is.read(buf))!=-1)
// {
// fos.write(buf,0,len);
// }
//
// fos.flush();
// fos.close();
// is.close();
final Bitmap bitmap= BitmapFactory.decodeStream(is);
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
is.close();
}
});
}
参考资料:https://juejin.im/post/5a31db566fb9a045257820b2#heading-1
《Android进阶之光》