Retrofit在專案中的應用
阿新 • • 發佈:2018-12-23
定義一個註解,用來對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進行標註:
把定義好的註解封裝進gsonpublic 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; } }
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();
}
}
}
}