OkHttp3 시작 안내
기사 1, OkHttp3 시작 설명:https://www.jianshu.com/p/af144d662bfd2. OkHttp3 시작하여 설명하는 쿠키 지속성:https://www.jianshu.com/p/23b35d403148
OkHttp는 네트워크 요청을 처리하는 소스 오픈 프로젝트로 안드로이드에서 가장 핫한 경량급 프레임워크로 본고는 주로 OkHttp3의 기본적인 사용 방법을 소개한다.홈페이지:http://square.github.io/okhttp/ Github:https://github.com/square/okhttpOkHttp3Demo 전송문:https://github.com/linzhiyong/OkHttp3Demo서버 데모 전송문:https://github.com/linzhiyong/SpringMVCDemo
자신의 프로젝트 경험과 결합하여 주로 다음과 같은 몇 가지 측면에서 소개한다.
OkHttp3 시작 안내
개발 구성
AndroidStudio에서 개발한 app의build.gradle 파일에 okhttp3에 대한 의존도 증가:
dependencies {
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
}
네트워크 요청에는 네트워크 권한이 필요합니다. AndroidManifest에 있어야 합니다.xml 구성:
<uses-permission android:name="android.permission.INTERNET" />
OkHttpClient 기본 매개변수 소개
OkHttpClient는 OkHttpClient를 통과합니다.Builder에서 매개변수를 구성합니다. 기본 매개변수는 다음과 같습니다.
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.readTimeout(HTTP_TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(HTTP_TIME_OUT, TimeUnit.SECONDS)
.connectTimeout(HTTP_TIME_OUT, TimeUnit.SECONDS)
);
OkHttpClient okHttpClient = okHttpClient = builder.build();
쿠키 유지, Https 인증서 설정, Interceptor 차단기 설정 등 다른 매개변수에 대해서는 다음 장에서 설명합니다.
주: 1. 프로젝트에서 OkHttpClient 실례를 만들고 다시 사용하는 것을 권장합니다. 이것은 모든 실례가 자신의 연결 탱크와 스레드 탱크를 가지고 있기 때문입니다. 연결 탱크와 스레드 탱크를 다시 사용하면 지연을 줄이고 메모리를 절약할 수 있습니다.2. 이 예에서 나는 OkHttpClient 실례를 LOkHttp3Utils에 봉하고 LOkHttp3Utils를 사용한다.okHttpClient()를 가져옵니다.
일반 GET 요청(동기식/비동기식)
//
Request request = new Request.Builder()
.url(url) //
.get() // get
.addHeader("name", "value") //
.tag("getSync") // request tag, okHttpClient tag
.build();
Call call = LOkHttp3Utils.okHttpClient().newCall(request);
//
Response response = call.execute();
//
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("", "");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
int code = response.code();
if (code == 200) {
String result = response.body().string();
Log.i("r", result);
}
else {
Log.e("e", response.message());
}
}
});
주: 1. 콜 대상은 요청 집행자로서 요청을 취소할 수 있고 콜 요청은 한 번만 실행할 수 있다.2. Response는 응답체로서 되돌아오는 string을 가져오려면response를 사용합니다.body().string (), 되돌아오는 바이트를 가져오려면response를 사용하십시오.body().bytes (), 되돌아오는 바이트 흐름 (다운로드 파일) 을 가져오려면response를 사용하십시오.body().byteStream();
일반 POST 요청(동기식/비동기식)
// body,MediaType
RequestBody requestBody = RequestBody.create(MediaType.parse("text/html; charset=utf-8"), content);
//
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.addHeader("name", "value")
.tag("postSync")
.build();
Call call = LOkHttp3Utils.okHttpClient().newCall(request);
//
Response response = call.execute();
//
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("", "");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
int code = response.code();
if (code == 200) {
String result = response.body().string();
Log.i("r", result);
}
else {
Log.e("e", response.message());
}
}
});
주: RequestBody는 요청 제출의 패키지로서 다양한 실현 형식이 있습니다.FormBody,MultipartBody,string,file,stream,form을 제출하는 캐리어입니다.
tag에서 요청 취소
요청 Request를 만들 때 tag 속성이 추가된 경우 tag를 통해 요청을 취소할 수 있습니다.
/**
* Tag
*
* @param client OkHttpClient
* @param tag tag
*/
public static void cancelTag(OkHttpClient client, Object tag) {
if (client == null || tag == null) return;
for (Call call : client.dispatcher().queuedCalls()) {
if (tag.equals(call.request().tag())) {
call.cancel();
}
}
for (Call call : client.dispatcher().runningCalls()) {
if (tag.equals(call.request().tag())) {
call.cancel();
}
}
}
/**
*
*
* @param client OkHttpClient
*/
public static void cancelAll(OkHttpClient client) {
if (client == null) return;
for (Call call : client.dispatcher().queuedCalls()) {
call.cancel();
}
for (Call call : client.dispatcher().runningCalls()) {
call.cancel();
}
}
주: 중복된 코드의 양을 줄이기 위해 다음에string, json, file 제출에 관한 방법은 RequestBody를 어떻게 만드는지 적고 후속 Request,Call, 동기화 비동기 호출은 중복 나열에 없습니다.
POST 요청 제출 String
//
String content = " ";
RequestBody requestBody = RequestBody.create(MediaType.parse("text/html; charset=utf-8"), content);
POST 요청 커뮤니케이션
RequestBody requestBody = new RequestBody() {
@Override
public MediaType contentType() {
return MediaType.parse("application/octet-stream; charset=utf-8");
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
sink.writeUtf8(" ");
//
}
};
POST 요청 제출 JSON(개체 이전 JSON)
// JSON
String bodyStr = "json";
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), bodyStr);
POST 요청 일반 Form 양식 제출
FormBody formBody = new FormBody.Builder()
.add("key1", "value1")
.add("key2", "value2")
.add("key3", "value3")
.build();
POST에서 혼합 Form 양식 제출 요청(텍스트 매개 변수 + 파일)
File file = new File("filePath");
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream; charset=utf-8"), file);
//
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("key1", "value1")
.addFormDataPart("key2", "value2")
.addFormDataPart("key3", "value3")
.addFormDataPart("file1", "name1", fileBody)
.build();
//
FormBody formBody = new FormBody.Builder()
.add("key1", "value1")
.add("key2", "value2")
.add("key3", "value3")
.build();
RequestBody requestBody1 = new MultipartBody.Builder()
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"params\""),
formBody)
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"file\"; filename=\"plans.xml\""),
fileBody)
.build();
POST 요청 제출 양식/다중 파일(진행률 표시줄)
1. 진행률 표시줄 없이 단일 파일 제출
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.txt");
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
//
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file1", file.getName(), fileBody)
.build();
//
RequestBody requestBody1 = new MultipartBody.Builder()
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"file1\"; filename=\"" + file.getName() + "\""),
fileBody)
.build();
2. 진행률 막대 없이 여러 파일 제출
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.txt");
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
RequestBody fileBody2 = RequestBody.create(MediaType.parse("application/octet-stream"), file);
//
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file1", file.getName(), fileBody)
.addFormDataPart("file2", file.getName(), fileBody2)
.build();
//
RequestBody requestBody1 = new MultipartBody.Builder()
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"file1\"; filename=\"" + file.getName() + "\""),
fileBody)
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"file2\"; filename=\"" + file.getName() + "\""),
fileBody2)
.build();
3. 서류 제출(!!!진도표 달기!!!)
앞에서 언급한 의사소통 방식에 따라 RequestBody의 writeTo(BufferedSink sink) 방법으로 파일 전송 진도를 감청합니다.
//
RequestBody fileBody = LOkHttp3Utils.createProgressRequestBody(MediaType.parse("application/octet-stream"), file,
new ProgressListener() {
@Override
public void onStart() {
}
@Override
public void onProgress(long total, float progress) {
// progress
}
@Override
public void onFinish(File file) {
}
@Override
public void onError(Exception e) {
}
});
/**
* requestbody,
*
* @param mediaType
* @param file
* @param listener
* @return
*/
public static RequestBody createProgressRequestBody(final MediaType mediaType, final File file,
final ProgressListener listener) {
return new RequestBody() {
@Override
public MediaType contentType() {
return mediaType;
}
@Override
public long contentLength() throws IOException {
return file.length();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
listener.onStart();
Source source;
try {
source = Okio.source(file);
//sink.writeAll(source);
Buffer buf = new Buffer();
Long remaining = contentLength();
for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
sink.write(buf, readCount);
listener.onProgress(contentLength(), 1 - (float)(remaining -= readCount) / contentLength());
}
listener.onFinish(file);
} catch (Exception e) {
listener.onError(e);
e.printStackTrace();
}
}
};
}
업로드 진행 모니터로 ProgressListener 인터페이스를 정의합니다.
public interface ProgressListener {
void onStart();
void onProgress(long total, float progress);
void onFinish(File file);
void onError(Exception e);
}
GET 요청 파일 다운로드(진행률 막대 포함)
여기는Callback 인터페이스를 다시 실현하여Response 대상의 파일 흐름을 가져와 파일 저장 작업을 하고 진행 상황을 감청하려면 파일 흐름을 읽을 때 처리해야 한다.
1. 파일 다운로드(진행률 표시줄 없음)
//
Request request = new Request.Builder()
.url(url) //
.get()
.addHeader("name", "value")
.tag("getFileAsync")
.build();
final Call call = LOkHttp3Utils.okHttpClient().newCall(request);
call.enqueue(new FileNoProgressCallback(Environment.getExternalStorageDirectory().getAbsolutePath(), "test.png") {
@Override
public void onFinish(File file) {
}
@Override
public void onError(Exception e) {
}
});
// Callback ,
public abstract class FileNoProgressCallback implements Callback {
private String destFileDir;
private String destFileName;
public FileNoProgressCallback(String destFileDir, String destFileName) {
this.destFileDir = destFileDir;
this.destFileName = destFileName;
}
@Override
public void onFailure(Call call, IOException e) {
onError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
this.saveFile(response);
}
private void saveFile(Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
FileOutputStream fos = null;
try {
is = response.body().byteStream();
final long total = response.body().contentLength();
long sum = 0L;
File dir = new File(this.destFileDir);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, this.destFileName);
fos = new FileOutputStream(file);
int len = 0;
while ((len = is.read(buf)) != -1) {
sum += (long) len;
fos.write(buf, 0, len);
}
fos.flush();
onFinish(file);
} catch (Exception e) {
onError(e);
} finally {
try {
response.body().close();
if (is != null) {
is.close();
}
} catch (IOException var23) {
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException var22) {
}
}
}
public abstract void onFinish(File file);
public abstract void onError(Exception e);
}
2. 파일 다운로드(!!!진행률 표시줄!!!)
//
Request request = new Request.Builder()
.url(url) //
.get()
.addHeader("name", "value")
.tag("getFileProgressAsync")
.build();
final Call call = LOkHttp3Utils.okHttpClient().newCall(request);
call.enqueue(new FileCallback(Environment.getExternalStorageDirectory().getAbsolutePath(), "test.png") {
@Override
public void onStart() {
}
@Override
public void onProgress(long total, float progress) {
}
@Override
public void onFinish(File file) {
}
@Override
public void onError(Exception e) {
}
});
// FileCallback Callback,
public abstract class FileCallback implements Callback, ProgressListener {
private String destFileDir;
private String destFileName;
public FileCallback(String destFileDir, String destFileName) {
this.destFileDir = destFileDir;
this.destFileName = destFileName;
}
@Override
public void onFailure(Call call, IOException e) {
onError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
this.saveFile(response);
}
private void saveFile(Response response) throws IOException {
onStart();
InputStream is = null;
byte[] buf = new byte[2048];
FileOutputStream fos = null;
try {
is = response.body().byteStream();
final long total = response.body().contentLength();
long sum = 0L;
File dir = new File(this.destFileDir);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, this.destFileName);
fos = new FileOutputStream(file);
int len = 0;
while ((len = is.read(buf)) != -1) {
sum += (long) len;
fos.write(buf, 0, len);
onProgress(total, (float) sum * 1.0F / (float) total);
}
fos.flush();
onFinish(file);
} catch (Exception e) {
onError(e);
} finally {
try {
response.body().close();
if (is != null) {
is.close();
}
} catch (IOException var23) {
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException var22) {
}
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Android 프레임 워 크 의 OkHttp 3 소스 코드 분석OkHttp 의 기본 사용 에서 우 리 는 okHttpClient.newCall()방법 을 통 해 이 call 대상 을 얻 었 습 니 다.new Call 이 어떻게 가 는 지 보 겠 습 니 다. 이 소스 코드 에서 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.