Retrofit基本介紹和簡單的使用方式

Retrofit:Android和Java的類型安全的HTTP客戶端。

Introduction:

1.Retrofit把你的HTTP API轉換成Java接口
public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

2.Retrofit類去實現GitHubService的接口

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);

3.每個Call去創建GitHubService可以實現同步或者異步去請求遠程網絡服務器
Call<List<Repo>> repos = service.listRepos("octocat");

使用註解去描述HTTP請求:

1.支持URL參數替換和查詢參數

2.對象轉換爲請求主體(例如,JSON,協議緩衝區)

3.Multipart請求主體和文件上傳

API Declaration:

在接口方法及其參數註釋指示請求將如何處理。

1.REQUEST METHOD(請求方法):
每個方法都必須有一個HTTP註釋提供的請求方法和相對URL。有五個內置的註釋:GET, POST, PUT, DELETE, and HEAD。資源的相對URL在註釋中指定。

例如:
@GET("users/list")

還可以指定URL的查詢參數,例如:
@GET("users/list?sort=desc")

2.URL MANIPULATION(URL操作):

請求的URL可以動態使用的方法替換塊和參數進行更新。替換使用{},裏面是字母數字字符串,相應的參數必須與@path註釋使用相同的字符串。

例如:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

查詢參數也可以被添加,例如:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);

對於複雜的查詢參數組合可以使用map,例如:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);

3.REQUEST BODY(請求體):

一個對象可以作爲一個HTTP請求正文使用的@Body註解指定,例如:
@POST("users/new")
Call<User> createUser(@Body User user);

該對象也將被使用在retrofit實例指定一個轉換器轉換。如果沒有添加轉換器,僅僅RequestBody可以被使用。

4.FORM ENCODED AND MULTIPART(表單和多表單):

方法也可以聲明發送form-encoded 和multipart data。

form-encoded數據發送當@FormUrlEncoded方法存在時,每一個key-value使用註解@Field包含名稱和提供該值的對象,例如:
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

多請求被使用當@Multipart存在方法上時,聲明部分使用@Part註解,例如:
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

Multipart parts使用一個Retrofit的轉換器或者他們可以實現RequestBody來處理自己的序列化。

5.HEADER MANIPULATION(處理請求頭):

你可以設置使用@Headers註釋靜態頭的方法,例如:
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();

多個請求頭,例如:
@Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);

注意頭不會互相覆蓋。具有相同名稱的所有頭將被包括在該請求。

一個請求頭使用@Header註釋可以動態更新。@Header必須提供相應的參數。如果該值爲null,頭就會被忽略掉。否則,toString將被回調這個value,使用其結果,例如:
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

需要被添加到每請求頭可以用一個OkHttp攔截來指定。

6.SYNCHRONOUS VS. ASYNCHRONOUS(同步VS異步):

call實例可以被同步或異步執行,每一個實例只能使用一次,但是使用clone()方法將創建新的實例被使用。

在Android中,回調函數將在主線程上執行,在JVM虛擬機上,回調函數會發生在同一線程執行HTTP請求。

Retrofit Configuration(配置)

Retrofit是API接口的類轉化爲可調用的對象。retorfit將爲你的平臺提供健全的默認值但是它允許定製。

CONVERTERS(轉換器):

默認情況下,retrofit只能反序列化okhttp中的ResponseBody類型和它只能接受其@Body RequestBody類型。

轉換器可以添加到其他類型的支持,以下是6個常用的序列化庫:
Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

Retrofit的基本配置項目中的使用

Android studio中的配置Retrofitgradle添加依賴
compile 'com.squareup.retrofit2:retrofit:2.1.0'

如果使用的解析方式是Gson,添加converter-gson:
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

Retrofit需要至少Java 7或Android 2.3。

一個簡單使用Retrofit中的例子

1.首先聚合上申請的接口,身份證查詢:

地址:http://apis.juhe.cn/idcard/index?key=您申請的KEY&cardno=330326198903081211

2.這裏根據輸入身份證號獲取個人的基本信息,接下來創建接口:
public interface UserCardnoService {
    //基本信息查詢
    @GET("/idcard/index")
    Call<InforBean> getInfoResult(@Query("key") String key, @Query("cardno") String cardno);
    //信息是否泄漏
    @GET("/idcard/leak")
    Call<LeakBean> getLeakResult(@Query("key") String key, @Query("cardno") String cardno);
    //身份證是否掛失
    @GET("/idcard/loss")
    Call<LossBean> getLossResult(@Query("key") String key, @Query("cardno") String cardno);
}

3.創建實體類,這裏放的實體類是基本信息的查詢:
public class InforBean {

    /**
     * resultcode : 200
     * reason : 成功的返回
     * result : {"area":"浙江省溫州市平陽縣","sex":"男","birthday":"1989年03月08日"}
     */
    public String resultcode;
    public String reason;
    public int error_code;
    /**
     * area : 浙江省溫州市平陽縣
     * sex : 男
     * birthday : 1989年03月08日
     */

    public ResultBean result;

    public static class ResultBean {
        public String area;
        public String sex;
        public String birthday;

        public String getArea() {
            return area;
        }

        public void setArea(String area) {
            this.area = area;
        }

        public String getSex() {
            return sex;
        }

        public void setSex(String sex) {
            this.sex = sex;
        }

        public String getBirthday() {
            return birthday;
        }

        public void setBirthday(String birthday) {
            this.birthday = birthday;
        }
    }

    public String getResultcode() {
        return resultcode;
    }

    public void setResultcode(String resultcode) {
        this.resultcode = resultcode;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public int getError_code() {
        return error_code;
    }

    public void setError_code(int error_code) {
        this.error_code = error_code;
    }

    public ResultBean getResult() {
        return result;
    }

    public void setResult(ResultBean result) {
        this.result = result;
    }
}

4.創建用戶信息查詢的類UserInfoActivity,構建retrofit實例訪問接口,解析數據,對數據進行賦值:
public class UserInfoActivity extends AppCompatActivity implements View.OnClickListener {

    public static final String TAG = "UserInfoActivity";

    private EditText mEtInput;
    private Button btnQuery;
    private TextView mTvArea;
    private TextView mTvSex;
    private TextView mTvBirthday;
    private LinearLayout llInfo;

    private String mCardno;

    private Context mContext;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = UserInfoActivity.this;
        setContentView(R.layout.base_layout);
        initView();
    }

    private void initView() {
        mEtInput = (EditText) findViewById(R.id.etInput);
        btnQuery = (Button) findViewById(R.id.btnQuery);
        mTvArea = (TextView) findViewById(R.id.tvArea);
        mTvSex = (TextView) findViewById(R.id.tvSex);
        mTvBirthday = (TextView) findViewById(R.id.tvBirthday);
        llInfo = (LinearLayout) findViewById(R.id.ll_Info);
        btnQuery.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        mCardno = mEtInput.getText().toString().trim();
        if (!mCardno.matches(RegexpUtils.USER_CARD)) {
            Toast.makeText(mContext, "輸入有誤,請重新輸入!", Toast.LENGTH_SHORT).show();
        } else {
            getNetData();
        }
    }

    private void getNetData() {
        //構建rtrofit實例
        Retrofit retrofit = new Retrofit
                .Builder()
                .baseUrl(GlobalContact.BASEURL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        UserCardnoService infoService = retrofit.create(UserCardnoService.class);

        Call<InforBean> call = infoService.getInfoResult(GlobalContact.KEY, mCardno);

        call.enqueue(new Callback<InforBean>() {
            @Override
            public void onResponse(Call<InforBean> call, Response<InforBean> response) {
                Log.i(TAG, "onResponse: " + response.body().toString());
                if (response.isSuccessful()) {
                    llInfo.setVisibility(View.VISIBLE);
                    //對數據進行賦值
                    mTvArea.setText(response.body().result.area);
                    mTvSex.setText(response.body().result.sex);
                    mTvBirthday.setText(response.body().result.birthday);
                } else {
                    llInfo.setVisibility(View.GONE);
                }
            }

            @Override
            public void onFailure(Call<InforBean> call, Throwable t) {
                Log.i(TAG, "onFailure: " + t.toString());
            }
        });
    }
}
















發佈了43 篇原創文章 · 獲贊 17 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章