Retrofit在項目中的應用,Retrofit項目應用
定義一個註解,用來對bean進行要序列化的欄位
import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 用於Gson命名策略的註解 */@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface ParamName { String value();}
將註解對需要網路傳輸bean進行標註:
public class requestBean implements Parcelable {public static final int RESPONSE_OK = 1;@ParamName("id") private String mId;@ParamName("name") private String mName;@ParamName("result")private int mResult;@ParamName("message")private String mMessage;public int getResult() {return mResult;}public String getMessage() {return mMessage;}public String getId() {return mId;} public String getName() { return mName; }public boolean succeed() {return getResult() == RESPONSE_OK;}}
把定義好的註解封裝進gson
import com.google.gson.FieldNamingPolicy;import com.google.gson.FieldNamingStrategy;import com.google.gson.Gson;import com.google.gson.GsonBuilder;import com.newandbie.privatecustomize.Config;import com.newandbie.privatecustomize.annotate.ParamName;import com.newandbie.privatecustomize.model.Gender;import java.lang.reflect.Field;/** * 自訂的Gson */public class GsonUtils { public static Gson newInstance() { GsonBuilder builder = new GsonBuilder(); builder.setFieldNamingStrategy(new AnnotateNaming()); return builder.create(); } private static class AnnotateNaming implements FieldNamingStrategy { @Override public String translateName(Field field) { ParamName a = field.getAnnotation(ParamName.class); return a != null ? a.value() : FieldNamingPolicy.IDENTITY.translateName(field); } }}
import com.squareup.okhttp.Cache;import com.squareup.okhttp.OkHttpClient;import android.content.Context;import java.io.File;import java.io.IOException;import java.util.concurrent.TimeUnit;/** * OkHttpClient自訂工具類 */public class OkHttpUtils { private static OkHttpClient singleton; public static OkHttpClient getInstance(Context context) { if (singleton == null) { synchronized (OkHttpUtils.class) { if (singleton == null) { File cacheDir = new File(context.getCacheDir(), Config.RESPONSE_CACHE); singleton = new OkHttpClient(); try { singleton.setCache(new Cache(cacheDir, Config.RESPONSE_CACHE_SIZE)); } catch (IOException e) { e.printStackTrace(); } singleton.setConnectTimeout(Config.HTTP_CONNECT_TIMEOUT, TimeUnit.MILLISECONDS); singleton.setReadTimeout(Config.HTTP_READ_TIMEOUT, TimeUnit.MILLISECONDS); } } } return singleton; }}
定義Retrofit工具將以上兩個工具配置到RetrofitUtils
import android.content.Context;import retrofit.RestAdapter;import retrofit.client.OkClient;import retrofit.converter.GsonConverter;public class RetrofitUtils { private static RestAdapter singleton; public static <T> T createApi(Context context, Class<T> clazz) { if (singleton == null) { synchronized (RetrofitUtils.class) { if (singleton == null) { RestAdapter.Builder builder = new RestAdapter.Builder(); builder.setEndpoint(ip地址);//設定遠程地址 builder.setConverter(new GsonConverter(GsonUtils.newInstance())); builder.setClient(new OkClient(OkHttpUtils.getInstance(context))); builder.setLogLevel( Config.DEBUG ? RestAdapter.LogLevel.FULL : RestAdapter.LogLevel.NONE); singleton = builder.build(); } } } return singleton.create(clazz); }}那麼工具集準備好了,
使用retrofit放在父類以便子類調用
import retrofit.Callback;import retrofit.RetrofitError;import retrofit.client.Response;/** * 介面的基類 */public class BaseActivity extends ActionBarActivity {.... /** * 建立API執行個體 * * @param cls Api定義類的類型 * @param <T> 範型 * @return API執行個體 */ public <T> T createApi(Class<T> cls) { return RetrofitUtils.createApi(this, cls); } public static abstract class ActivityCallback<T> implements Callback<T> { <span style="white-space:pre"></span>//軟引用,緩衝引用對象 private final WeakReference<BaseActivity> mRef; public ActivityCallback(BaseActivity activity) { mRef = new WeakReference<BaseActivity>(activity); } public Activity getActivity() { return mRef.get(); } @Override public void failure(RetrofitError error) { final BaseActivity activity = mRef.get(); Response response = error.getResponse(); if (response != null) { Toast.makeText(activity, activity.getString(R.string.server_error), Toast.LENGTH_SHORT).show(); Log.e(getLogTag(), "code:" + response.getStatus() + ", reason:" + response.getReason()); error.printStackTrace(); } } }..... }
定義下面的一個REST API介面。 該介面定義了一個函數 ask, 該函數會通過HTTP post請求去訪問伺服器的//ellassy/teacher/ask
路徑並把返回的結果封裝為requestBean Java對象返回。
import retrofit.Callback;import retrofit.http.Field;import retrofit.http.FormUrlEncoded;import retrofit.http.Header;import retrofit.http.POST;public interface ExpertApi { @FormUrlEncoded @POST("/ellassy/teacher/ask") void ask(@Header("token") String token, @Field("member_id") String memberId, @Field("title") String title, @Field("description") String description, @Field("teacher_id") String expertId, Callback<requestBean> cb);}
rect用戶端請求服務端
import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;import retrofit.client.Response;public class AskActivity extends implements View.OnClickListener { private ExpertApi mExpertApi; //... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... mExpertApi = createApi(ExpertApi.class); } @Override public void onClick(View v) { //...調用rest 介面 mExpertApi.ask(getToken(), mUserInfo.getId(), title, question, mExpertId, new AskCallback(AskActivity.this)); }//回調介面返回從伺服器返回的資料 private static final class AskCallback extends ActivityCallback<requestBean> { public AskCallback(AskActivity activity) { super(activity); } @Override public void success(requestBean requestbean, Response response) { AskActivity activity = (AskActivity) getActivity(); if (requestbean.succeed()) { Toast.makeText(activity, "成功返回資料", Toast.LENGTH_SHORT).show(); activity.finish(); } else { Toast.makeText(activity, askResponse.getMessage(), Toast.LENGTH_SHORT).show(); } } }}