OkHttp3入门
OkHttp是一个处理网络请求的开源项目;
安卓端轻量级框架;
用于替代HttpUrlConnection和Apache HttpClient;
准备工作
添加依赖
//网络请求OkHttp3
implementation 'com.squareup.okhttp3:okhttp:4.3.1'
设置网络权限
<uses-permission android:name="android.permission.INTERNET" />
API级别28或更高级别手机,在http请求时(非Https请求)会有错误提示,并且请求不到数据。
CLEARTEXT communication to www.baidu.com not permitted by network security policy
需要在AndroidManifest的application中设置android:usesCleartextTraffic=“true”
创建
okhttp提供有同步、异步两种请求方式,差别不大
同步请求时在请求过程中线程处于堵塞状态,不建议放在主线程中运行,容易出现ANR(Application Not responding)(应用程序没有响应)。
简单创建四步走
1、创建OkHttpClient对象
2、通过Builder模式创建Request对象
3、通过request的对象去构造得到一个Call对象
4、执行请求,调用call.enqueue()执行异步请求,调用call .execute()执行同步请求
异步请求
OkHttpClient client = new OkHttpClient(); //实例化OkHttpClient 对象
Request request = new Request.Builder() //创建Request对象的Builder模式
.url("http://www.baidu.com") //设置访问的网址
//.get() //设置为GET请求 默认为GET请求,可以忽略
.build(); //创建Request对象
Call call = client.newCall(request); //通过request的对象去构造得到一个Call对象
call.enqueue(new Callback() { //调用call的enqueue(),进行异步请求
@Override
public void onFailure(Call call, IOException e) {
//错误回调,通过e.getMessage()可以拿到错误信息
Log.d("onFailure","onFailure: "+e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//成功回调,在这里我们可以拿到服务器返回的数据
Log.d("onResponse","onResponse: "+response.body().string());
}
});
同步请求
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.get()
.build();
Call call = client.newCall(request);
Response response = null;
try {
response = call .execute();//调用call的execute()进行同步请求,在请求过程中处于堵塞状态,建议写在子线程中
Log.d("onResponse","onResponse: "+response.body().string());
} catch (IOException e) {
e.printStackTrace();
Log.d("onFailure", "onFailure: "+e.getMessage());
}
onResponse回调有一个参数是response为响应数据
如果返回的数据是字符串,可以通过response.body().string()得到
如果返回的数据是二进制字节数组,可以通过response.body().bytes()得到
如果返回的数据是inputStream,可以通过response.body().byteStream()得到
中止请求
调用call的cancel()进行中止,停止请求
call.cancel();
具体介绍
OkHttp支持PUT,DELETE,POST,GET等请求;
文件的上传下载
以下都使用异步请求进行
GET请求
GET请求比较简单,就是上面的简单四步
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("")
.get()
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
}
});
POST请求
POST请求支持提交文件,流,string,表单等等
简单的POST请求(提交表单)
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder()//创建表单
.add("key","value") //传入需要提交的数据
.add("key","value") //传入需要提交的数据
.build(); //创建请求体
Request request = new Request.Builder()
.url("") //设置提交数据的网址
.post(requestBody) //设置为POST请求,传入请求体
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() { //异步请求
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
}
});
下载(保存到本地)
其实很简单,就是GET请求或POST请求
只是将返回的数据转为流(response.body().byteStream()),再通过InputStream(), OutputStream()保存本地即可。
简单的下载请求(示例)
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://image.baidu.com/search/down?tn=download&ipn=dwnl&word=download" +
"&ie=utf8&fr=result&url=http%3A%2F%2Fc.hiphotos.baidu.com%2Fzhidao%2" +
"Fpic%2Fitem%2Fd009b3de9c82d1587e249850820a19d8bd3e42a9.jpg&thumburl=" +
"http%3A%2F%2Fimg1.imgtn.bdimg.com%2Fit%2Fu%3D3675415932%2C4054970339%26" +
"fm%3D26%26gp%3D0.jpg") //百度上的图片
.get()
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.d("onFailure", "onFailure: " + e.getMessage());
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String path = Environment.getExternalStorageDirectory().getPath()+"/Download";//文件路径,根目录Download目录下
File file = new File(path,"image.jpg");//设置文件路劲及文件名
InputStream is = response.body().byteStream();
BufferedInputStream bis = new BufferedInputStream(is);
FileOutputStream fos = new FileOutputStream(new File(path));
byte[] bytes = new byte[1024];
int len;
Log.d("onResponse", "onResponse: 开始");
while ((len=is.read(bytes))!=-1){
fos.write(bytes,0,len);
}
fos.flush();
Log.d("onResponse", "onResponse: 结束");
is.close();
bis.close();
fos.close();
}
});
准备工作
权限获取
获取SD卡的存取权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Android 6.0 注意动态授权
Google在 Android 6.0 开始引入了权限申请机制,使用危险权限时需要动态的申请并得到用户的授权才能使用。存取权限属于危险权限。
如何动态获取?
这里提供一个工具类,用于动态授权
public class PermissionUtil {
public static String READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE; //内存读取
public static String WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE; //内存写入
public static void getPermissions(Activity activity, String... permission) {
List<String> permissions = new ArrayList<>();
//此处做动态权限申请
//判断系统是否大于等于Android 6.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for(int i=0;i<permission.length;i++){
int request = ContextCompat.checkSelfPermission(activity, permission[i]);
//判断是否未获取权限
if (request != PackageManager.PERMISSION_GRANTED)
permissions.add(permission[i]);
}
if (permissions.size()>0) {//缺少权限,进行权限申请
//当前上下文;一个权限数组;一个唯一的请求码(0~65535的16位数)
ActivityCompat.requestPermissions(activity, permissions.toArray(new String[permissions.size()]), 0XFF);
} else {
//权限同意 已全部授权
}
} else {
//低于api 23 不需要动态授权
}
}
}
在MainActivity的onCreate()中使用,进行动态授权
PermissionUtil.getPermissions(this, PermissionUtil.READ_EXTERNAL_STORAGE, PermissionUtil.WRITE_EXTERNAL_STORAGE);
显示下载进度
下载一定要有下载进度的
显示下载进度有两种方法:
- 在onResponse回调中实时获取
- 对网络响应ResponseBody进行来代理
第一种比较简单(仅限当前可用,与其他框架联用可能会失效,如:Retrofit+OkHttp3+RxJava2联合使用时会失效,因为Retrofit的关系)
第二种有点复杂,涉及到拦截器,直接贴代码
activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="下载" />
</LinearLayout>
MainActivity
public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Android 6.0 及以上系统需要动态申请,PermissionUtil工具已经在上面贴出,这里进行动态申请
PermissionUtil.getPermissions(this, PermissionUtil.READ_EXTERNAL_STORAGE, PermissionUtil.WRITE_EXTERNAL_STORAGE);
progressBar = findViewById(R.id.progressBar);
//设置按钮点击事件
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
download();//点击后进行下载
}
});
}
public void download(){
String path = Environment.getExternalStorageDirectory().getPath() + "/Download/qq.exe";//保存的路径及文件名
String url = "https://qd.myapp.com/myapp/qqteam/pcqq/PCQQ2020.exe";//这里给的是QQPC版的下载地址,文件较大
//设置下载路径和下载网址,开始下载
OkHttpHelper.getInstance().setDownloadUrl(url).startDownload(path,new OkHttpHelper.DownloadCallback() {
@Override
public void start(final long max) {
//这里处于子线程,需返回主线程更新UI
progressBar.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "开始下载", Toast.LENGTH_SHORT).show();
progressBar.setMax((int) max);
}
});
}
@Override
public void loading(final long progress) {
progressBar.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress((int) progress);
}
});
}
@Override
public void complete(String msg) {
}
@Override
public void fail(String message) {
}
});
}
}
OkHttpHelper
public class OkHttpHelper {
private OkHttpClient client;
private Request request;
private static OkHttpHelper instance = null;
private OkHttpHelper() {
initOkHttp();//初始化
}
static OkHttpHelper getInstance() {//单例模式
if (instance == null) {
synchronized (OkHttpHelper.class) {
if (instance == null) {
instance = new OkHttpHelper();
}
}
}
return instance;
}
private void initOkHttp() {
client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}
//设置问GET请求,设置下载网址
OkHttpHelper setDownloadUrl(String url) {
request = new Request.Builder()
.url(url)
//.header("RANGE","")//断点续传时需要使用的
.get()
.build();
return this;
}
//设置下载路径,开始下载
public void startDownload(final String path,final DownloadCallback callback) {
if (client == null) {
initOkHttp();
}
OkHttpClient okHttpClient = client.newBuilder().addInterceptor(new MyInterceptor(callback)).build();//插入自定义的MyInterceptor()拦截器
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
callback.fail(e.getMessage());
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
download(response,path);
callback.complete("完成");
}
});
}
//创建MyInterceptor类,实现Interceptor 拦截器
static class MyInterceptor implements Interceptor {
DownloadCallback callback;
public MyInterceptor(DownloadCallback callback) {
super();
this.callback = callback;
}
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response.newBuilder().body(new MyResponseBody(response,callback)).build();
}
}
//创建MyResponseBody 类,继承 ResponseBody类
static class MyResponseBody extends ResponseBody {
Response response;
DownloadCallback callback;
MyResponseBody(Response response,DownloadCallback callback) {
super();
this.response = response;
this.callback = callback;
}
@Override
public long contentLength() {
//获取文件的总字节数
callback.start(response.body().contentLength());
return response.body().contentLength();
}
@Nullable
@Override
public MediaType contentType() {
//可以获取文件的类型
return response.body().contentType();
}
@NotNull
@Override
public BufferedSource source() {
contentLength();
contentType();
//可以获取文件资源
return Okio.buffer(new ForwardingSource(response.body().source()) {
long bytesLength=0;
@Override
public long read(@NotNull Buffer sink, long byteCount) throws IOException {
//获取下载进度
final long bytesRead = super.read(sink, byteCount);
bytesLength += bytesRead;
callback.loading(bytesLength);
return bytesRead;
}
});
}
}
//注:MyResponseBody里的三个接口contentLength,contentType,source,并不会程序自己主动调用执行,需要人为被动执行;
//source接口的执行,在程序执行到download方法的“InputStream is = response.body().byteStream();”时才会被调用;
// 然后我们自己调用contentLength(),contentType()方法去执行,
// 或者我们在download方法的“InputStream is = response.body().byteStream();”上面添加两行代码response.body().contentLength();,response.body().contentType();
//下载,执行下载、保存
public static void download(Response response,String path) throws IOException {
//response.body().contentLength();
//response.body().contentType();
InputStream is = response.body().byteStream();//拿到资源,转为字节流
BufferedInputStream bis = new BufferedInputStream(is);
FileOutputStream fos = new FileOutputStream(new File(path));//设置需要保存的位置,及文件
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1) {
fos.write(bytes, 0, len);//保存
}
fos.flush();
is.close();
bis.close();
fos.close();
}
//一些必要的接口
public interface DownloadCallback { //各种下载需要的接口
//开始下载
void start(long max); //传入文件总字节数
//正在下载
void loading(long progress); //传入已下载的字节数
//下载完成
void complete(String msg); //传入成功信息
//请求失败
void fail( String message); //传入错误信息
}
}
注:MyResponseBody里的三个接口方法contentLength(),contentType(),source(),并不会程序自己主动调用执行,需要人为被动执行;
source()的执行,是在程序执行到download方法的“InputStream is = response.body().byteStream();”时才会被调用;
然后我们自己调用contentLength(),contentType()去执行;
或者我们在download方法里添加两行代码response.body().contentLength();,response.body().contentType();,也会执行。
第一种
修改OkHttpHelper 即可
public class OkHttpHelper {
private static OkHttpHelper instance = null;
private OkHttpClient client;
private Request request;
private OkHttpHelper() {
initOkHttp();//初始化
}
static OkHttpHelper getInstance() {//单例模式
if (instance == null) {
synchronized (OkHttpHelper.class) {
if (instance == null) {
instance = new OkHttpHelper();
}
}
}
return instance;
}
OkHttpHelper setDownloadUrl(String url) {
request = new Request.Builder()
.url(url)
//.header("RANGE","")//断点续传时需要使用的
.get()
.build();
return this;
}
private void initOkHttp() {
client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}
void startDownload(final String path, final DownloadCallback callback) {
if (client == null) {
initOkHttp();
}
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
callback.fail(e.getMessage());
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
downlaod(response, path, callback);
callback.complete("完成");
}
});
}
public static void downlaod(Response response, String path, DownloadCallback callback) throws IOException {
long max = response.body().contentLength();
callback.start(max);
InputStream is = response.body().byteStream();
BufferedInputStream bis = new BufferedInputStream(is);
FileOutputStream fos = new FileOutputStream(new File(path));
byte[] bytes = new byte[1024];
int len;
long length = 0;//记录已下载的字节数
while ((len = is.read(bytes)) != -1) {
length += len;
fos.write(bytes, 0, len);
callback.loading(length);
}
fos.flush();
is.close();
bis.close();
fos.close();
}
public interface DownloadCallback {
//开始下载
void start(long max);//传入文件总字节数
//正在下载
void loading(long progress);//传入已下载的字节数
//下载完成
void complete(String msg);
//请求失败
void fail(String message);
}
}
上传
文件上传
上传文件之前要设置上传文件的类型
例:MediaType.parse("text/plain; charset=utf-8")
text/html html
text/plain 文本文档
text/xml xml
image/gif gif
image/jpeg jpg
image/png png
application/xhtml-xml XHTML
application/json json
application/pdf pdf
application/msword word文档
application/octet-stream 二进制流
文件上传(简单示例)
OkHttpClient client = new OkHttpClient();//实例化
//拿到上传的文件
File file = new File(Environment.getExternalStorageDirectory(),"/Download/qq.exe");
//设置上传类型
MediaType type = MediaType.parse("");
//设置请求体
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("","")
//将文件类型和文件放入请求体
.addFormDataPart("","",RequestBody.create(file, type))
.build();
//RequestBody body = RequestBody.create(file, type);
//设置上传网址(要支持上传的网址),放入请求体
Request request = new Request.Builder()
.url("")
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {//异步请求
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
}
});
涉及到的类与方法
new RequestBody();
RequestBody.create(byte[]);
RequestBody.create(File, MediaType); //上传文件是用到
RequestBody.create(byte[], MediaType); //上传二进制字节时用到
RequestBody.create(String, MediaType); //上传文本时用到
RequestBody.create(ByteString, MediaType); //上传字节流时用到
RequestBody.create(byte[], MediaType,int offset); // offset 从offset开始上传
RequestBody.create(byte[], MediaType,int offset,int byteCount ); // offset, byteCount 从offset开始,到offset后byteCount字节结束,上传
new MultipartBody();
new MultipartBody.Builder();
builder.setType(MediaType); //MultipartBody.FORM 设置类型是表单
builder.addFormDataPart(String, String); //添加数据
builder.addFormDataPart(String, String, RequestBody); //添加上传的文件及必要信息
builder.build(); //返回RequestBody
new MediaType();
MediaType.parse(String); //设置上传的文件的类型
上传监听(显示上传进度)
对网络请求RequestBody进行来代理
这里直接上代码
activity_main 同上
MainActivity
public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PermissionUtil.getPermissions(this, PermissionUtil.READ_EXTERNAL_STORAGE, PermissionUtil.WRITE_EXTERNAL_STORAGE);
progressBar = findViewById(R.id.progressBar);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
upload();
}
});
}
public void upload() {
Map<String, String> map = new HashMap<>();
String path = Environment.getExternalStorageDirectory().getPath() + "/Download/123.jpg";
File file = new File(path);
String url = "";
OkHttpHelper.getInstance().setUploadUrl(url).startUpload(map, file, new OkHttpHelper.UploadCallback() {
@Override
public void start(long max) {
}
@Override
public void loading(long progress) {
}
@Override
public void complete(String msg) {
}
@Override
public void fail(String message) {
}
});
}
}
OkHttpHelper
public class OkHttpHelper {
private static OkHttpHelper instance = null;
private OkHttpClient client;
private Request request;
private OkHttpHelper() {
initOkHttp();//初始化
}
static OkHttpHelper getInstance() {//单例模式
if (instance == null) {
synchronized (OkHttpHelper.class) {
if (instance == null) {
instance = new OkHttpHelper();
}
}
}
return instance;
}
public OkHttpHelper setUploadUrl(String url) {
request = new Request.Builder()
.url(url)
.build();
return this;
}
public void startUpload(Map<String, String> map, File file,final UploadCallback callback) {
//重构Request,在.post()中传入的请求体
Request request = this.request.newBuilder().post(new MyRequestBody(setUploadBody(map, file),callback)).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
callback.fail(e.getMessage());
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
callback.complete(response.body().string());
}
});
}
private static class MyRequestBody extends RequestBody {
RequestBody body = null;
UploadCallback callback;
public MyRequestBody(MultipartBody multipartBody, UploadCallback callback) {
super();
body = multipartBody;
this.callback = callback;
}
@Nullable
@Override
public MediaType contentType() {
return body.contentType();
}
@Override
public long contentLength() throws IOException {
callback.start(body.contentLength());
return body.contentLength();
}
@Override
public void writeTo(@NotNull BufferedSink bufferedSink) throws IOException {
//包装
Sink sk = sink(bufferedSink);
bufferedSink = Okio.buffer(sk);
//写入
body.writeTo(bufferedSink);
//必须调用flush,否则最后一部分数据可能不会被写入
bufferedSink.flush();
}
/**
* 写入,回调进度接口
*
* @param sink Sink
* @return Sink
*/
private Sink sink(Sink sink) {
return new ForwardingSink(sink) {
long bytesWritten = 0L;
@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
//获取上传进度
bytesWritten += byteCount;
callback.loading(bytesWritten);
}
};
}
}
//将需要上传的数据进行打包
private MultipartBody setUploadBody(Map<String, String> map, File file) {
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
RequestBody fileBody = RequestBody.create(file, MediaType.parse("image/png"));
if (map != null && map.size() > 0) {
for (String key : map.keySet()) {
String value = map.get(key);
if (value != null) {
builder.addFormDataPart(key, value);
}
}
}
return builder.addFormDataPart("file", "fileName", fileBody).build();
}
public interface UploadCallback {
//开始上传
void start(long max);//传入文件总字节数
//正在上传
void loading(long progress);//传入已下载的字节数
//上传完成
void complete(String msg);
//请求失败
void fail(String message);
}
}
其他
拦截器
拦截器是一种强大的机制,可以监视、重写和重试调用。
//这是一个最简单的拦截器
static class MyInterceptor implements Interceptor {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
return response;
//return chain.proceed(chain.request());
}
}
//如何使用
OkHttpHelper client = new OkHttpClient.Builder()
.addInterceptor(new MyInterceptor()) //注册应用拦截器
.addNetworkInterceptor()//注册网络拦截器
.build();
调用chain.proceed(request)是每个拦截器实现的关键部分。这种简单的方法是所有HTTP工作发生的地方,它会产生一个响应来满足请求。如果chain.proceed(request)被多次调用,则必须关闭先前的响应主体。(官方翻译)
应用拦截器
无需担心中间响应,例如重定向和重试。
即使从缓存提供HTTP响应,也总是被调用一次。
遵守应用程序的原始意图。不关心OkHttp注入的标头,例如If-None-Match。
允许短路而不是Chain.proceed()。
允许重试并多次致电Chain.proceed()。
网络拦截器
能够对重定向和重试之类的中间响应进行操作。
不会为使网络短路的缓存响应调用。
观察数据,就像通过网络传输数据一样。
访问Connection带有请求的。
重写请求
重写响应
重试及重定向拦截器 RetryAndFollowUpInterceptor
桥接拦截器 BridgeInterceptor
缓存拦截器 CacheInterceptor
连接拦截器 ConnectInterceptor
读写拦截器 CallServerInterceptor
日志打印 LoggerInterceptor
打印网络请求的头信息
打印请求的网址
缓存:cache-control, max-age=xxx
可能涉及到的类与方法
new Cache(File,long,FileSystem); //设置缓存数使用,long有效缓存时长
new Cache(File,long); //设置缓存数使用
new OkHttpClient();
newBuilder();自定义一个共享的OkHttpClient实例
new OkHttpClient.Builder()
builder.connectTimeout(Long, TimeUnit); //long 设置连接超时时长,TimeUnit 设置时间单位(时,分,秒)
builder.readTimeout(Long, TimeUnit); //long 设置读取超时时长,
builder.writeTimeout(Long, TimeUnit); //long 设置写入超时时长,
builder.addInterceptor(Interceptor); //设置拦截器
builder.cache(Cache); //设置缓存
builder.build(); //返回 OkHttpClient
new MediaType();
MediaType.parse(String);
new RequestBody();
RequestBody.create(byte[]);
RequestBody.create(File, MediaType); //上传文件是用到
RequestBody.create(byte[], MediaType); //上传二进制字节时用到
RequestBody.create(String, MediaType); //上传文本时用到
RequestBody.create(ByteString, MediaType); //上传字节流时用到
RequestBody.create(byte[], MediaType,int offset); // offset 从offset开始上传
RequestBody.create(byte[], MediaType,int offset,int byteCount); // offset, byteCount 从offset开始,到offset后byteCount字节结束,上传
new FormBody(); //设置表单
new FormBody.Builder();
formBody.add(String, String);
formBody.build(); //返回RequestBody
new MultipartBody();
new MultipartBody.Builder();
builder.setType(MediaType); //MultipartBody.FORM 设置类型是表单
builder.addFormDataPart(String, String); //添加数据
builder.addFormDataPart(String, String, RequestBody);
builder.build(); //返回RequestBody
new Request();
new Request.Builder();
builder.url(String);
builder.post(RequestBody);
builder.addHeader(String, String); //设置请求头
builder.method(String, RequestBody) //设置请求类型(GET,POST)和请求体
builder.build();
new Call();
call.execute(); //同步请求
call.enqueue(Callback); //异步请求
call.cancel(); //请求终止
new Response();
response.body();
response.body().string();
response.body().bytes();
response.body().byteStream();