首先是抽象的基類java
public abstract class BaseApi { public static final String API_SERVER = "服務器地址" private static final OkHttpClient mOkHttpClient = new OkHttpClient(); private static Retrofit mRetrofit; protected static Retrofit getRetrofit() { if (Retrofit == null) { Context context = Application.getInstance().getApplicationContext(); //設定30秒超時 mOkHttpClient.setConnectTimeout(30, TimeUnit.SECONDS); //設置攔截器,以用於自定義Cookies的設置 mOkHttpClient.networkInterceptors() .add(new CookiesInterceptor(context)); //設置緩存目錄 File cacheDirectory = new File(context.getCacheDir() .getAbsolutePath(), "HttpCache"); Cache cache = new Cache(cacheDirectory, 20 * 1024 * 1024); mOkHttpClient.setCache(cache); //構建Retrofit mRetrofit = new Retrofit.Builder() //配置服務器路徑 .baseUrl(API_SERVER + "/") //設置日期解析格式,這樣能夠直接解析Date類型 .setDateFormat("yyyy-MM-dd HH:mm:ss") //配置轉化庫,默認是Gson .addConverterFactory(ResponseConverterFactory.create()) //配置回調庫,採用RxJava .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //設置OKHttpClient爲網絡客戶端 .client(mOkHttpClient) .build(); } return mRetrofit; } }
而後是Cookies攔截器緩存
public class CookiesInterceptor implements Interceptor{ private Context context; public CookiesInterceptor(Context context) { this.context = context; } //重寫攔截方法,處理自定義的Cookies信息 @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Request compressedRequest = request.newBuilder() .header("cookie", CookieUtil.getCookies(context)) .build(); Response response = chain.proceed(compressedRequest); CookieUtil.saveCookies(response.headers(), context); return response; } }
CookieUtil則是一些自定義解析和生成方法以及SharedPreferences的存取,代碼略服務器
而後是Api類cookie
public class UserApi extends BaseApi{ //定義接口 private interface UserService { //GET註解不可用@FormUrlEncoded,要用@Query註解引入請求參數 @GET("user/user_queryProfile") Observable<UserProfileResp> queryProfile(@Query("userId") int userId); //POST方法沒有緩存,適用於更新數據 @FormUrlEncoded @POST("user/user_updateUserName") Observable<BaseResp> updateUserName(@Field("userName") String userName); } protected static final UserService service = getRetrofit().create(UserService.class); //查詢用戶信息接口 public static Observable<UserProfileResp> queryProfile(int userId){ return service.queryProfile(userId); } //更新用戶名接口 public static Observable<BaseResp> updateUserName(String userName){ return service.updateUserName(userName); } }
再就是將Retrofit的響應消息通過Gson解析成指望的數據結構,稱之爲Model類
上文的BaseResp和UserProfileResp則是自定義的Model網絡
假定服務器約定返回的Json格式爲數據結構
{ "result":"結果代號,0表示成功", "msg":"異常信息,僅在失敗時返回數據", "userInfo": { "id":"用戶id", "userName":"用戶名名字" } }
那麼UserProfileResp能夠寫成ide
public class UserProfileResp { //@SerializedName是指定Json格式中的Key名 //能夠不寫,則默認採用與變量名同樣的Key名 @SerializedName("userInfo") private UserProfileModel userInfo; public UserProfileModel getUserInfo() { return userInfo; } }
UserProfileModel則是具體的數據結構ui
public class UserProfileModel { private int userId; private String userName; public String getUserName(){ return userName; } }
須要注意的是,若是沒有使用@SerializedName指定Key名,當工程被混淆時,變量名會被混淆得與指望的Key名不符。所以須要將這類Model類統一放到一個工程目錄,再在proguard-project文件中加入排除項this
//不混淆Model類 -keep class com.xxx.model.xxx.** { *; }
最後是實際調用.net
public void getProfile(int userId){ UserApi.queryProfile(userId) .subscribeOn(Schedulers.io()) .subscribe(new Subscriber<UserProfileResp>(){ @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(UserProfileResp userProfileResp) { } }); }