retrofit 简单使用
1. build.gradle
implementation'com.squareup.retrofit2:retrofit:2.9.0'
implementation'com.google.code.gson:gson:2.8.6'
implementation'com.squareup.retrofit2:converter-gson:2.9.0'
如果想使用最新版本,可以把版本号改为+,然后去 External Libraries,看看下载下来的lib的版本号,再把+改为 看到的版本号即可。。 为什么,再改回来,使用+,可能每次都去网络下载lib,导致编译很慢。
版本号固定,比如gson, 2.8.6,本地已经有了,直接使用本地,不会再网络请求。但是+号会,再次请求对比。不需要实时保持最新。
2. public interface GitHubService {
@GET("check_update.php")
Call>reqNewVersionApk();
}
3.
{
OkHttpClient.Builder builder =new OkHttpClient.Builder();
if (Consts.isDebug) {
HttpLoggingInterceptor loggingInterceptor =new HttpLoggingInterceptor("Retrofit2");
//log打印级别,决定了log显示的详细程度
loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
//log颜色级别,决定了log在控制台显示的颜色
loggingInterceptor.setColorLevel(Level.INFO);
builder.addInterceptor(loggingInterceptor);
}
OkHttpClient client = builder.build();
Retrofit retrofit =new Retrofit.Builder()
.client(client)
.baseUrl("http://www.xxx.xyz/xxx/app/")//要访问的主机地址,注意以 /(斜线) 结束,不然可能会抛出异常
.addConverterFactory(GsonConverterFactory.create())//添加Gson
.build();
GitHubService service = retrofit.create(GitHubService.class);
// xxx/app/
Call> call = service.reqNewVersionApk();
call.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, retrofit2.Response> response) {
RespBase appUpdateResp = response.body();
MyLog.print("appUpdateResp.getCode:" + appUpdateResp.getCode());
MyLog.print("appUpdateResp.getdata.apkurl:" + appUpdateResp.getData().getApkUrl());
}
@Override
public void onFailure(Call> call, Throwable t) {
MyLog.printError(t);
}
});
}
4.HttpLoggingInterceptor
/*
* Copyright 2016 jeasonlzy(廖子尧)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lzy.okgo.interceptor;
import com.lzy.okgo.utils.IOUtils;
import com.lzy.okgo.utils.OkLogger;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import okhttp3.Connection;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.http.HttpHeaders;
import okio.Buffer;
/**
* ================================================
* 作 者:jeasonlzy(廖子尧)Github地址:https://github.com/jeasonlzy
* 版 本:1.0
* 创建日期:2016/1/12
* 描 述:OkHttp拦截器,主要用于打印日志
* 修订历史:
* ================================================
*/
public class HttpLoggingInterceptorimplements Interceptor {
private static final CharsetUTF8 = Charset.forName("UTF-8");
private volatile LevelprintLevel = Level.NONE;
private java.util.logging.LevelcolorLevel;
private Loggerlogger;
public enum Level {
NONE, //不打印log
BASIC, //只打印 请求首行 和 响应首行
HEADERS, //打印请求和响应的所有 Header
BODY //所有数据全部打印
}
public HttpLoggingInterceptor(String tag) {
logger = Logger.getLogger(tag);
}
public void setPrintLevel(Level level) {
if (printLevel ==null)throw new NullPointerException("printLevel == null. Use Level.NONE instead.");
printLevel = level;
}
public void setColorLevel(java.util.logging.Level level) {
colorLevel = level;
}
private void log(String message) {
logger.log(colorLevel, message);
}
@Override
public Responseintercept(Chain chain)throws IOException {
Request request = chain.request();
if (printLevel == Level.NONE) {
return chain.proceed(request);
}
//请求日志拦截
logForRequest(request, chain.connection());
//执行请求,计算请求时间
long startNs = System.nanoTime();
Response response;
try {
response = chain.proceed(request);
}catch (Exception e) {
log("<-- HTTP FAILED: " + e);
throw e;
}
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
//响应日志拦截
return logForResponse(response, tookMs);
}
private void logForRequest(Request request, Connection connection)throws IOException {
boolean logBody = (printLevel == Level.BODY);
boolean logHeaders = (printLevel == Level.BODY ||printLevel == Level.HEADERS);
RequestBody requestBody = request.body();
boolean hasRequestBody = requestBody !=null;
Protocol protocol = connection !=null ? connection.protocol() : Protocol.HTTP_1_1;
try {
String requestStartMessage ="--> " + request.method() +' ' + request.url() +' ' + protocol;
log(requestStartMessage);
if (logHeaders) {
if (hasRequestBody) {
// Request body headers are only present when installed as a network interceptor. Force
// them to be included (when available) so there values are known.
if (requestBody.contentType() !=null) {
log("\tContent-Type: " + requestBody.contentType());
}
if (requestBody.contentLength() != -1) {
log("\tContent-Length: " + requestBody.contentLength());
}
}
Headers headers = request.headers();
for (int i =0, count = headers.size(); i < count; i++) {
String name = headers.name(i);
// Skip headers from the request body as they are explicitly logged above.
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
log("\t" + name +": " + headers.value(i));
}
}
log(" ");
if (logBody && hasRequestBody) {
if (isPlaintext(requestBody.contentType())) {
bodyToString(request);
}else {
log("\tbody: maybe [binary body], omitted!");
}
}
}
}catch (Exception e) {
OkLogger.printStackTrace(e);
}finally {
log("--> END " + request.method());
}
}
private ResponselogForResponse(Response response, long tookMs) {
Response.Builder builder = response.newBuilder();
Response clone = builder.build();
ResponseBody responseBody = clone.body();
boolean logBody = (printLevel == Level.BODY);
boolean logHeaders = (printLevel == Level.BODY ||printLevel == Level.HEADERS);
try {
log("<-- " + clone.code() +' ' + clone.message() +' ' + clone.request().url() +" (" + tookMs +"ms)");
if (logHeaders) {
Headers headers = clone.headers();
for (int i =0, count = headers.size(); i < count; i++) {
log("\t" + headers.name(i) +": " + headers.value(i));
}
log(" ");
if (logBody && HttpHeaders.hasBody(clone)) {
if (responseBody ==null)return response;
if (isPlaintext(responseBody.contentType())) {
byte[] bytes = IOUtils.toByteArray(responseBody.byteStream());
MediaType contentType = responseBody.contentType();
String body =new String(bytes, getCharset(contentType));
log("\tbody:" + body);
responseBody = ResponseBody.create(responseBody.contentType(), bytes);
return response.newBuilder().body(responseBody).build();
}else {
log("\tbody: maybe [binary body], omitted!");
}
}
}
}catch (Exception e) {
OkLogger.printStackTrace(e);
}finally {
log("<-- END HTTP");
}
return response;
}
private static CharsetgetCharset(MediaType contentType) {
Charset charset = contentType !=null ? contentType.charset(UTF8) :UTF8;
if (charset ==null) charset =UTF8;
return charset;
}
/**
* Returns true if the body in question probably contains human readable text. Uses a small sample
* of code points to detect unicode control characters commonly used in binary file signatures.
*/
private static boolean isPlaintext(MediaType mediaType) {
if (mediaType ==null)return false;
if (mediaType.type() !=null && mediaType.type().equals("text")) {
return true;
}
String subtype = mediaType.subtype();
if (subtype !=null) {
subtype = subtype.toLowerCase();
if (subtype.contains("x-www-form-urlencoded") || subtype.contains("json") || subtype.contains("xml") || subtype.contains("html"))//
return true;
}
return false;
}
private void bodyToString(Request request) {
try {
Request copy = request.newBuilder().build();
RequestBody body = copy.body();
if (body ==null)return;
Buffer buffer =new Buffer();
body.writeTo(buffer);
Charset charset =getCharset(body.contentType());
log("\tbody:" + buffer.readString(charset));
}catch (Exception e) {
OkLogger.printStackTrace(e);
}
}
}