網(wǎng)絡(luò)請(qǐng)求不要忘記加權(quán)限
總體步驟
1 創(chuàng)建OkHttpClient對(duì)象,并初始化,推薦公用一個(gè)OkHttpClient對(duì)象,所以寫成成員變量的形式
private OkHttpClient client
//在onCreate中初始化,設(shè)置超時(shí)時(shí)間
client=new OkHttpClient.Builder()
.connectTimeout(5000, TimeUnit.SECONDS)
.readTimeout(5000,TimeUnit.SECONDS)
.writeTimeout(5000,TimeUnit.SECONDS)
.build();
2 創(chuàng)建一個(gè)Request對(duì)象,指定發(fā)送方式,什么都不寫默認(rèn)是get,設(shè)置url
設(shè)置tag,添加頭文件等信息也在這里添加,用addHeader方法
Request request=new Request.Builder()
.url(url)
.tag(this)
.build();
3 獲取Call對(duì)象
Call call=client.newCall(request);
4 執(zhí)行請(qǐng)求并獲取返回值
//同步請(qǐng)求,直接獲取response對(duì)象,需要將其放在子線程中,并捕獲異常
new Thread(){
@Override
public void run() {
try {
Response response=call.execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
//異步請(qǐng)求,在onResponse中獲取到response,然后獲取到字節(jié)流或者String類型的對(duì)象,執(zhí)行在子線程中,不能直接更新UI
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
上傳功能
如果用get方式上傳,則需要傳的參數(shù)直接卸載url中,參數(shù)總量不能大于1k。很少使用
如果使用post方式上傳,則需要先構(gòu)造一個(gè)RequestBody對(duì)象,上傳的內(nèi)容都卸載RequestBody中,一般上傳都采用post方式上傳。
上傳字符串,普通字符串和json字符串
//上傳json
//1 設(shè)置類型
MediaType mediaType=MediaType.parse("application/json");
//2 構(gòu)造RequestBody,json就是實(shí)際傳入的json字符串的內(nèi)容
RequestBody requestBody=RequestBody.create(mediaType,json);
//3 創(chuàng)建Request請(qǐng)求
Request request=new Request.Builder()
.url(url)
.tag(this)
.post(requestBody)
.build();
//4 創(chuàng)建call對(duì)象
Call call=client.newCall(request)
//執(zhí)行請(qǐng)求
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
//上傳普通字符串
//只需要把mediaType的類型改成text/plain
MediaType mediaType=MediaType.parse("text/plain");
上傳文件
File file=new File(Environment.getExternalStorageDirectory(),"aaa.jpg");
//application/octet-stream代表不限類型,可以傳入任何類型的文件
MediaType mediaType=MediaType.parse("application/octet-stream");
RequestBody requestBody=RequestBody.create(mediaType,file);
Request request=new Request.Builder()
.url(url)
.tag(this)
.post(requestBody)
.build();
Call call=client.newCall(request);
call.enqueue(callback);
上傳key-value鍵值對(duì)
//首先創(chuàng)建RequestBody對(duì)象,鍵值對(duì)用FormBody.Builder來創(chuàng)建
RequestBody requestBody=new FormBody.Builder()
.add("key","value")
.add("key1","value1")
.build();
//創(chuàng)建Request對(duì)象
Request request=new Request.Builder()
.url(url)
.post(requestBody)
.build();
//Call對(duì)象
Call call=client.newCall(request);
//執(zhí)行
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
上傳表單
上傳的表單可以既可以有文件,也可以有key-value對(duì)
File file=new File(Environment.getExternalStorageDirectory(),"aaa.txt");
//首先創(chuàng)建RequestBody對(duì)象
//可以傳入key-value
//也可以上傳文件,當(dāng)上傳文件是需要傳入三個(gè)參數(shù)
//第一個(gè) 相當(dāng)于key
//第二個(gè),制定一個(gè)文件的名稱
//第三個(gè),用RequestBody.create的方式傳入文件
RequestBody requestBody=new MultipartBody.Builder()
.setType(MultipartBody.FORM) //這句必須要有
.addFormDataPart("key","value")
.addFormDataPart("name","name.txt",RequestBody.create(MediaType.parse("application/octet=stream"),file));
//創(chuàng)建Request對(duì)象
Request request=new Request.Builder()
.url(url)
.post(requestBody)
.build();
//Call對(duì)象
Call call=client.newCall(request);
//執(zhí)行
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
下載
用get方式和post方式下載其實(shí)是基本一樣的,但是大多用get方式,這里也用get方式
當(dāng)在callback中收到后臺(tái)返回的response對(duì)象時(shí),就可以根據(jù)response對(duì)象獲取相應(yīng)的字符串或者文件流,然后進(jìn)行解析獲取相應(yīng)的對(duì)象。
接受字符串
//創(chuàng)建Request對(duì)象
Request request=new Request.Builder()
.url(url)
.build();
//Call對(duì)象
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 {
//獲取后臺(tái)返回的字符串,json或者普通的字符串
//先拿到body,再轉(zhuǎn)成string
String result=response.body().string();
//然后在進(jìn)行下一步的處理
}
});
接收文件
//創(chuàng)建Request對(duì)象
Request request=new Request.Builder()
.url(url)
.build();
//Call對(duì)象
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 {
//先拿到body,再轉(zhuǎn)成inputStream
InputStream inputStream=response.body().byteStream();
//對(duì)文件流進(jìn)行處理,保存到文件中
File file=new File("","");
byte[] bytes=new byte[1024];
int len=-1;
FileOutputStream out=new FileOutputStream(file);
while((len=inputStream.read(bytes))!=-1)
{
out.write(bytes,0,len);
}
inputStream.close();
out.close();
}
});```
######圖片文件直接顯示
//創(chuàng)建Request對(duì)象
Request request=new Request.Builder()
.url(url)
.build();
//Call對(duì)象
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 {
//先拿到body,再轉(zhuǎn)成inputStream
InputStream inputStream=response.body().byteStream();
//先轉(zhuǎn)化成bitmap
Bitmap bitmap=BitmapFactory.decodeStream(inputStream);
//然后將圖片顯示,這里不再寫了,但是需要注意這里是子線程
//操作UI是需要用handler或者runOnUiThread
}
});
######顯示下載進(jìn)度
可以獲取文件的總大小,同時(shí)處理文件流時(shí)可以獲取當(dāng)前下載的大小,從而顯示下載進(jìn)度
InputStream inputStream=response.body().byteStream();
//當(dāng)前下載的bit
long current=0;
//文件總bit
long total=response.body().contentLength();
//對(duì)文件流進(jìn)行處理,保存到文件中
File file=new File("","");
byte[] bytes=new byte[1024];
int len=-1;
FileOutputStream out=new FileOutputStream(file);
while((len=inputStream.read(bytes))!=-1)
{
out.write(bytes,0,len);
//更新當(dāng)前的bit
current+=len;
}
inputStream.close();
out.close();