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