天天看點

Android學習之網絡請求庫Retrofit2

網絡請求庫有很多種,例如使用HttpUrlConnection,使用HttpClient,或者使用Volley,使用OKHttp,而現在的主流是使用OKHttp + Retrofit,往細了講本人也不是很清楚其中的差別,今天也不講它們的差別。Retrofit是一個十分強大的優秀的網絡請求庫,隻要熟悉了以後,使用起來也是十分友善的。

Retrofit位址:https://github.com/square/retrofit

Retrofit幫助文檔位址:http://square.github.io/retrofit/

大家可以從這個位址compile這個庫,先看下使用Retrofit所需要的庫,需要使用到OKHttp,因為Retrofit依賴于它,然後因為要擷取JSON資料,是以要解析JSON,是以使用Gson:

compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.retrofit2:retrofit:2.0.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0'
compile 'com.google.code.gson:gson:2.6.2'      

我們首先肯定需要一個API位址來測試,這裡使用百度APIStore的手機歸屬地查詢服務來測試

位址:http://apistore.baidu.com/apiworks/servicedetail/794.html

接口位址:http://apis.baidu.com/apistore/mobilenumber/mobilenumber

首先要擷取Api Key,接下來調用時要使用。APIStore中一個使用者隻有一個Api Key,可以調用平台所有即用服務。怎麼申請這裡不講了。

這個接口的API主機位址為:http://apis.baidu.com,資源位址為:/apistore/mobilenumber/mobilenumber,我們需要一個key等于apikey的Header和一個key等于phone的查詢關鍵字,該請求為GET請求。是以我們需要構造一個GET請求,添加一個Header,添加一個Query關鍵字,通路該API傳回的資料格式如下:

{

    "errNum": 0,

    "retMsg": "success",

    "retData": {

        "phone": "XXXXXXXXXXX",

        "prefix": "XXXXXXX",

        "supplier": "移動",

        "province": "上海",

        "city": "上海",

        "suit": "136卡"

    }

}

這裡我的手機号碼用X來代替了,實際得到的是自己輸入的号碼,然後是建立資料對象,相信使用過Gson庫都知道為什麼要這麼做。資料對象可以幫助我們更好的處理資料:

/**
 * PhoneResult
 *
 * @author yuzhentao
 */
public class PhoneResult {

    private int errNum;
    private String retMsg;
    private RetDataEntity retData;

    public int getErrNum() {
        return errNum;
    }

    public void setErrNum(int errNum) {
        this.errNum = errNum;
    }

    public String getRetMsg() {
        return retMsg;
    }

    public void setRetMsg(String retMsg) {
        this.retMsg = retMsg;
    }

    public RetDataEntity getRetData() {
        return retData;
    }

    public void setRetData(RetDataEntity retData) {
        this.retData = retData;
    }

    public static class RetDataEntity {

        private String phone;
        private String prefix;
        private String supplier;
        private String province;
        private String city;
        private String suit;

        public String getPhone() {
            return phone;
        }

        public void setPhone(String phone) {
            this.phone = phone;
        }

        public String getPrefix() {
            return prefix;
        }

        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }

        public String getSupplier() {
            return supplier;
        }

        public void setSupplier(String supplier) {
            this.supplier = supplier;
        }

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getSuit() {
            return suit;
        }

        public void setSuit(String suit) {
            this.suit = suit;
        }

    }

}      

然後根據官方文檔的說明建立接口:

/**
 * PhoneService
 *
 * @author yuzhentao
 */
public interface PhoneService {

    @GET("/apistore/mobilenumber/mobilenumber")
    Call<PhoneResult> getResult(@Header("apikey") String apikey, @Query("phone") String phone);

}      

GET方式就是用@GET,@GET裡面填寫的就是資源位址,方法的參數就是我們需要傳入的Value。根據API文檔來@Header或者@query。

其中@Header用來添加Header,@Query用來添加查詢關鍵字

建構好接口之後,分4步來走:

1.建立Retrofit對象

2.建立通路API的請求

3.發送請求

4.處理結果

/**
 * 主界面
 *
 * @author yuzhentao
 */
public class MainActivity extends Activity {

    private static final String BASE_URL = "http://apis.baidu.com";
    private static final String API_KEY = "";//這裡輸入Api Key

    private Context context;

    private EditText et;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        context = this;
        et = (EditText) findViewById(R.id.edittext_activity_main);
        findViewById(R.id.button_activity_main).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                query();
            }
        });
    }

    /**
     * 查詢
     */
    private void query() {
        Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(BASE_URL).build();
        PhoneService phoneService = retrofit.create(PhoneService.class);
        Call<PhoneResult> phoneResultCall = phoneService.getResult(API_KEY, et.getText().toString());
        phoneResultCall.enqueue(new Callback<PhoneResult>() {
            @Override
            public void onResponse(Call<PhoneResult> call, Response<PhoneResult> response) {
                if (response.isSuccessful()) {
                    Log.e("yuzhentao", "擷取成功");
                    PhoneResult phoneResult = response.body();
                    if (phoneResult != null) {
                        PhoneResult.RetDataEntity retDataEntity = phoneResult.getRetData();
                        Toast.makeText(context, retDataEntity.getCity(), Toast.LENGTH_SHORT).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<PhoneResult> call, Throwable t) {
                Log.e("yuzhentao", "擷取失敗");
            }
        });
    }

}      

關于GsonConverterFactory.create()是什麼呢?

這是用來轉換伺服器資料到對象使用的。該Demo中使用API傳回的資料是JSON格式,是以使用Gson來轉換,如果伺服器傳回的是其他類型的資料,則根據需要編寫對應的解析方法。

或許Retrofit一開始使用起來比較麻煩,但是隻要我們會使用了,以後就是一帆風順,相信以後的工作中大家都會使用到的,希望對大家有點幫助。

效果圖:

Android學習之網絡請求庫Retrofit2

Demo位址:http://download.csdn.net/detail/qq_23940659/9470427

最後感謝:http://www.devwiki.net/2016/03/02/Retrofit-Use-Course-1/