public class RetrofitManager {
/**
* 需要的引用
* retrofit2 + okhttp3 引用
* compile 'com.android.support.constraint:constraint-layout:1.0.2'
* compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
* compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
* compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
* compile 'com.squareup.retrofit2:converter-scalars:2.0.0-beta4'
* compile 'com.squareup.okhttp3:okhttp:3.2.0'
* compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
* compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
*
* rxjava引用
* compile 'io.reactivex:rxandroid:1.1.0'
* compile 'io.reactivex:rxjava:1.1.0'
*
* 拼url 的資料 @see{ http://blog.csdn.net/linzhenxiang123/article/details/52593971 }
*
* cookie持久化解決方案 @see{ https://github.com/franmontiel/PersistentCookieJar }
*
*/
private static final long TIMEOUT = 1000 * 30;
private static final String BASE_URL="http://gank.io/api/";
private static RetrofitManager retrofitManager;
protected ApiService apiService;
private RetrofitManager(Context context) {
OkHttpClient client = initOkHttpClient(context);
Retrofit retrofit = initRetrofit(client);
apiService = retrofit.create(ApiService.class);
}
/**
* 初始化okhttp
*
* @param context
* @return
*/
private OkHttpClient initOkHttpClient(Context context) {
//建立一個檔案用來緩存網絡請求
File cacheDirectory = new File(context.getCacheDir().getAbsolutePath(), "HttpCache");
ClearableCookieJar cookieJar =
new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
//執行個體化一個OkHttpClient.Builder
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)//設定連接配接逾時
.readTimeout(TIMEOUT, TimeUnit.SECONDS)//設定從主機讀資訊逾時
.writeTimeout(TIMEOUT, TimeUnit.SECONDS)//設定寫資訊逾時
.retryOnConnectionFailure(true)///如果連接配接失敗,嘗試重連
.cache(new Cache(cacheDirectory, 10 * 1024 * 1024))//設定緩存檔案
.addInterceptor(initInterceptor())//設定okhttp攔截器,這樣做的好處是可以為你的每一個retrofit2的網絡請求都增加相同的head頭資訊,而不用每一個請求都寫頭資訊
.addInterceptor(initLogInterceptor())//列印日志
.cookieJar(cookieJar)
.build();
return client;
}
/**
* 初始化http攔截器
*
* @return
*/
private Interceptor initInterceptor() {
BasicParamsInterceptor builder =new BasicParamsInterceptor.Builder()
.addHeaderParam("Content-Type", "application/json; charset=UTF-8")
.addHeaderParam("Connection", "keep-alive")
.addHeaderParam("Accept", "*/*")
.addHeaderParam("Cache-Control", String.format("public, max-age=%d", 60))
.build();
return builder;
}
private Interceptor initLogInterceptor(){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.i("info", "請求參數:" + message);
}
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return interceptor;
}
/**
* 初始化 Retrofit
* @param client
* @return
*/
private Retrofit initRetrofit(OkHttpClient client) {
Retrofit builder = new Retrofit.Builder()
.client(client)//設定 HTTP Client 用于請求的連接配接
.addConverterFactory(ScalarsConverterFactory.create())//如果網絡通路傳回的字元串,而不是json資料格式,要使用下面的轉換器
.addConverterFactory(GsonConverterFactory.create())//如果網絡通路傳回的是json字元串,使用gson轉換器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//此處順序不能和上面對調,否則不能同時相容普通字元串和Json格式字元串 為了支援rxjava,需要添加下面這個把 Retrofit 轉成RxJava可用的适配類
.baseUrl(BASE_URL)//請求的父目錄
.build();
return builder;
}
public static RetrofitManager getInstance(Context context) {
if (retrofitManager == null) {
synchronized (RetrofitManager.class) {
if (retrofitManager == null)
retrofitManager = new RetrofitManager(context);
}
}
return retrofitManager;
}
public ApiService getApiService(){
return apiService;
}
}
public abstract class ApiCallBack<T> extends Subscriber<T> {
protected abstract void onSuccess(T t);
protected abstract void onFailure();
protected abstract void onFinish();
@Override
public void onCompleted() {
onFinish();
}
@Override
public void onError(Throwable e) {
if(e instanceof HttpException){
HttpException exception = (HttpException)e;
int code = exception.response().code();
Log.i("info","code:"+code);
}else if (e instanceof JsonParseException
|| e instanceof JSONException) {
Log.i("info","code:解析錯誤");
} else if (e instanceof ConnectException) {
Log.i("info","code:連接配接失敗");
} else if (e instanceof javax.net.ssl.SSLHandshakeException) {
Log.i("info","code:證書驗證失敗");
} else {
Log.i("info","code:未知錯誤");
}
onFailure();
}
@Override
public void onNext(T t) {
onSuccess(t);
}
}
public class BasicParamsInterceptor implements Interceptor {
Map<String, String> queryParamsMap = new HashMap<>();
Map<String, String> paramsMap = new HashMap<>();
Map<String, String> headerParamsMap = new HashMap<>();
List<String> headerLinesList = new ArrayList<>();
private BasicParamsInterceptor() {
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
// process header params inject
Headers.Builder headerBuilder = request.headers().newBuilder();
if (headerParamsMap.size() > 0) {
Iterator iterator = headerParamsMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
}
}
if (headerLinesList.size() > 0) {
for (String line: headerLinesList) {
headerBuilder.add(line);
}
}
requestBuilder.headers(headerBuilder.build());
// process header params end
// process queryParams inject whatever it's GET or POST
if (queryParamsMap.size() > 0) {
injectParamsIntoUrl(request, requestBuilder, queryParamsMap);
}
// process header params end
// process post body inject
if (request.method().equals("POST") && request.body().contentType().subtype().equals("x-www-form-urlencoded")) {
FormBody.Builder formBodyBuilder = new FormBody.Builder();
if (paramsMap.size() > 0) {
Iterator iterator = paramsMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
formBodyBuilder.add((String) entry.getKey(), (String) entry.getValue());
}
}
RequestBody formBody = formBodyBuilder.build();
String postBodyString = bodyToString(request.body());
postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
} else { // can't inject into body, then inject into url
injectParamsIntoUrl(request, requestBuilder, paramsMap);
}
request = requestBuilder.build();
return chain.proceed(request);
}
// func to inject params into url
private void injectParamsIntoUrl(Request request, Request.Builder requestBuilder, Map<String, String> paramsMap) {
HttpUrl.Builder httpUrlBuilder = request.url().newBuilder();
if (paramsMap.size() > 0) {
Iterator iterator = paramsMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
httpUrlBuilder.addQueryParameter((String) entry.getKey(), (String) entry.getValue());
}
}
requestBuilder.url(httpUrlBuilder.build());
}
private static String bodyToString(final RequestBody request){
try {
final RequestBody copy = request;
final Buffer buffer = new Buffer();
if(copy != null)
copy.writeTo(buffer);
else
return "";
return buffer.readUtf8();
}
catch (final IOException e) {
return "did not work";
}
}
public static class Builder {
BasicParamsInterceptor interceptor;
public Builder() {
interceptor = new BasicParamsInterceptor();
}
public Builder addParam(String key, String value) {
interceptor.paramsMap.put(key, value);
return this;
}
public Builder addParamsMap(Map<String, String> paramsMap) {
interceptor.paramsMap.putAll(paramsMap);
return this;
}
public Builder addHeaderParam(String key, String value) {
interceptor.headerParamsMap.put(key, value);
return this;
}
public Builder addHeaderParamsMap(Map<String, String> headerParamsMap) {
interceptor.headerParamsMap.putAll(headerParamsMap);
return this;
}
public Builder addHeaderLine(String headerLine) {
int index = headerLine.indexOf(":");
if (index == -1) {
throw new IllegalArgumentException("Unexpected header: " + headerLine);
}
interceptor.headerLinesList.add(headerLine);
return this;
}
public Builder addHeaderLinesList(List<String> headerLinesList) {
for (String headerLine: headerLinesList) {
int index = headerLine.indexOf(":");
if (index == -1) {
throw new IllegalArgumentException("Unexpected header: " + headerLine);
}
interceptor.headerLinesList.add(headerLine);
}
return this;
}
public Builder addQueryParam(String key, String value) {
interceptor.queryParamsMap.put(key, value);
return this;
}
public Builder addQueryParamsMap(Map<String, String> queryParamsMap) {
interceptor.queryParamsMap.putAll(queryParamsMap);
return this;
}
public BasicParamsInterceptor build() {
return interceptor;
}
}
}
public interface ApiService {
// @POST("site/search")
// Observable<SearchResult> search(@Body SearchRequestBody searchRequestBody);
/**
* 擷取App啟動頁資訊
* @return
*/
@GET("json/page/app-data/info.json?v=3.0.1&os=1&ver=4")
Observable<AppStart> getAppStartInfo();
// 随機資料
@GET("random/data/{type}/{count}")
Observable<GankModel> loadRandomData(@Path("type")String type , @Path("count") int count);
}
public class BaseActivity extends AppCompatActivity {
private CompositeSubscription compositeSubscription;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
compositeSubscription = new CompositeSubscription();
}
@Override
protected void onDestroy() {
if (compositeSubscription.hasSubscriptions()) {
compositeSubscription.unsubscribe();
}
super.onDestroy();
}
public void doHttpRequest(Observable observable, Subscriber subscriber) {
compositeSubscription.add(
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber));
}
}
public class GankModel {
private boolean error;
List<Results> results;
public boolean getError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
public List<Results> getResults() {
return results;
}
public void setResults(List<Results> results) {
this.results = results;
}
public static class Results {
private String _id;
private String createdAt;
private String desc;
private String publishedAt;
private String type;
private String url;
private boolean used;
private String who;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public boolean isUsed() {
return used;
}
public void setUsed(boolean used) {
this.used = used;
}
public String getWho() {
return who;
}
public void setWho(String who) {
this.who = who;
}
@Override
public String toString() {
return "Results{" +
"_id='" + _id + '\'' +
", createdAt='" + createdAt + '\'' +
", desc='" + desc + '\'' +
", publishedAt='" + publishedAt + '\'' +
", type='" + type + '\'' +
", url='" + url + '\'' +
", used=" + used +
", who='" + who + '\'' +
'}';
}
}
}
調用方法
doHttpRequest(RetrofitManager.getInstance(this).getApiService().loadRandomData("福利", 20), new ApiCallBack<GankModel>() {
@Override
protected void onSuccess(GankModel gankModels) {
Log.i("info","gankModel--->"+gankModels.getError());
}
@Override
protected void onFailure() {
Log.i("info","------------------onFailure----------------");
}
@Override
protected void onFinish() {
Log.i("info","------------------onFinish----------------");
}
@Override
public void onStart() {
}
});
資源位址: http://download.csdn.net/detail/qq_22256027/9902831