向Retrofit打響第一炮

廢話:
強行開啟了Retrofit的學(xué)習(xí)模式坡疼,但是發(fā)現(xiàn)啊彬呻,我找到的一些入門文章,簡直不要太坑柄瑰,敲不出來demo不要緊啊闸氮,你得講的讓我看懂吧?好教沾,有一篇能看懂的了蒲跨,喂能不能講完啊,講一半死球了不做完一套demo幾個意思授翻!

OK既然沒有好的Retrofit第一炮的文章或悲,那么我的機會就來了

看完本文并且do it你將收獲

  1. 使用Retrofit進行一次基礎(chǔ)的不能再基礎(chǔ)的網(wǎng)絡(luò)請求
  2. 沒了

正文開始

  • Retrofit是啥?

我想既然朋友你找到這篇文章堪唐,一定心里有個底巡语,簡單說就是一個簡化網(wǎng)絡(luò)操作的庫

  • 準(zhǔn)備工作
1. 添加依賴
//這是Retrofit的包
    compile 'com.squareup.retrofit2:retrofit:2.2.0'
//這是Retrofit用來將得到的json轉(zhuǎn)化成bean對象的包
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
2. 用于請求數(shù)據(jù)的api,這里送你一個
//最后面的num=3淮菠,這個數(shù)字可以自己改男公,需要幾條數(shù)據(jù)就寫幾
http://www.imooc.com/api/teacher?type=4&num=3
3. json對應(yīng)的javabean

咱們先將2中的url用瀏覽器訪問一下,會得到一串json字符串
根據(jù)json內(nèi)容自己敲一個bean
復(fù)制json字符串兜材,然后去jsonschema2pojo將他轉(zhuǎn)化成一個bean

jsonschema2pojo

下載之后你得到了:Bean.javaDatum.java兩個源文件

/**Bean.java**/
public class Bean {
        public Integer status;
        public List<Datum> data = null;
        public String msg;
        private Map<String, Object> additionalProperties = new HashMap<>();

        public Map<String, Object> getAdditionalProperties() {
            return this.additionalProperties;
        }

        public void setAdditionalProperty(String name, Object value) {
            this.additionalProperties.put(name, value);
        }
}
/**Datum.java**/
public class Datum {
        public Integer id;
        public String name;
        public String picSmall;
        public String picBig;
        public String description;
        public Integer learner;
        private Map<String, Object> additionalProperties = new HashMap<>();

        public Map<String, Object> getAdditionalProperties() {
            return this.additionalProperties;
        }

        public void setAdditionalProperty(String name, Object value) {
            this.additionalProperties.put(name, value);
        }
}

接下來你需要將他們復(fù)制到你項目的包下理澎,因為你要用到他們
至此,準(zhǔn)備就工作就全部做完了

  • 正式開始使用Retrofit
1. 首先需要寫一個接口

這個接口規(guī)定get曙寡、post請求的url參數(shù)糠爬;規(guī)定一個返回Call對象(這個call對象用于正式發(fā)起請求并獲得返回數(shù)據(jù))的方法,這個方法接收的參數(shù)為url參數(shù)值举庶,用開始給的url舉例:

http://www.imooc.com/api/teacher?type=4&num=3
//num=3,num是一個參數(shù)执隧,3是參數(shù)值,而這個接口內(nèi)就規(guī)定了url中有哪些參數(shù)
//返回Call對象 的方法 接收的參數(shù)户侥,就是url的參數(shù)值

那么對于這個api镀琉,我們需要寫的接口應(yīng)該是這樣:

public interface ApiService {
        @GET("teacher?type=4")
        Call<Bean> getCall(@Query("num") int count);
    }
//這個"@GET"是Retrofit的注解,表示進行g(shù)et請求蕊唐,()括號內(nèi)的字符串就是url的*參數(shù)信息*
//那為什么"&num=3"不見了呢屋摔?看官請看我下面...
//-------Call<Bean> getCall(@Query("num") int count);-------
//這個方法返回一個Call<Bean>對象,等會兒正式發(fā)起請求并獲取數(shù)據(jù)就靠他了
//對頭替梨,Bean就對應(yīng)于Bean.java钓试!因為我們需要解析json變成一個Bean實例嘛
//(@Query("num") int count)就厲害了装黑,他表示:
//在@GET("teacher?type=4")之中的字符串的后面,再添加"&num="
//那么num等于多少呢弓熏,這就在使用getCall方法的時候由參數(shù)int count決定了

好了恋谭,一個進行g(shù)et請求的接口就寫完了,也就這么兩行挽鞠,太簡單了疚颊!

其實,在這里還有另外一種情況信认,如果url不是在后面&添加參數(shù)材义,而需要指定的變量在url的路徑中呢?比如github這個api:

https://api.github.com/users/{user}/repos

{user}是需要查找的用戶名
這個時候接口就應(yīng)該這樣寫:

public interface ApiService {
      @GET("users/{user}/repos")
      Call<Bean> getCall(@Path("user") String u);
  }
//{user}直接理解為一個變量,這個變量的值由↓決定
//@Path("user")表示將以上路徑中的{user}變量賦值為參數(shù)u的值
//當(dāng)然切記狮杨,這里的Call<Bean>的Bean應(yīng)該換成另外你根據(jù)API返回的json生成的bean

以上內(nèi)容母截,請另外嘗試,與本次demo無關(guān)呀

什么橄教?post請求的接口該怎么寫清寇?
**我也不知道(/▽╲)**
2. 接下來創(chuàng)建一個Retrofit實例,通過Retrofit實例創(chuàng)建 接口的實例
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.imooc.com/api/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        ApiService apiService = retrofit.create(ApiService.class);
//機智护蝶,就是通過baseUrl補全整個url信息了华烟!是不是上面@GET中殘缺url的疑惑一下就解決了?持灰!
//當(dāng)然在剛剛的接口中盔夜,你也可以一次性寫全url,但是這樣就不夠靈活了堤魁!
//----------------addConverterFactory(GsonConverterFactory.create())
//這一句規(guī)定解析json用哪個庫喂链,這就是最開始要你導(dǎo)入Gson庫的原因啦,咱們用Gson解析json
//當(dāng)然你也可以用其他的庫解析json妥泉,比如jackson椭微,寫法是一樣的,注意引入別人的庫就是了
//然后很完美的創(chuàng)建了一個retrofit實例盲链,并且通過retrofit實例來創(chuàng)建了一個接口的實例
3. 緊接著我們需要一個Call實例來正式的發(fā)起請求獲取數(shù)據(jù)
//請求3條數(shù)據(jù)蝇率,最后url就拼接成了最頂上給的url,是一毛一樣的
//沒錯刽沾,網(wǎng)絡(luò)請求有異常本慕,得try/catch一下
        Call<Bean> call = apiService.getCall(3);
        try {
            call.execute();//執(zhí)行call,也就是正式發(fā)起網(wǎng)絡(luò)請求咯侧漓!
        } catch (IOException e) {
            e.printStackTrace();
        }

那么問題來了锅尘,發(fā)起網(wǎng)絡(luò)請求之后,我去哪兒得到數(shù)據(jù)呢布蔗!機智的我把鼠標(biāo)放在"execute()"上鉴象,然后按下ctrl鍵:

得到了call.execute()的返回值

原來call.execute()直接返回了一個請求結(jié)果忙菠,那么我們拿到這個結(jié)果來看看都有啥:

Response<Bean> response= call.execute();
result.//看下圖
result都有啥

哇何鸡,這么多方法纺弊,返回的都是什么?其實一看方法名和返回類型便知骡男,這里我們挑兩個打印出來看看:

        try {
            Response<Bean> response= call.execute();
            Log.i(TAG, "response.body()----->" + response.body());
            Log.i(TAG, "response.message()----->" + response.message());
            Log.i(TAG, "response.code()----->" + response.code());
            //明明打印了3個O巍!
        } catch (IOException e) {
            e.printStackTrace();
        }
  • 拿到返回結(jié)果之后

好的隔盛,現(xiàn)在所有代碼如下:

public class MainActivity extends AppCompatActivity {
        private static final String TAG = "MainActivity";
        public interface ApiService {
            @GET("teacher?type=4")
            Call<Bean> getCall(@Query("num") int count);
        }
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://www.imooc.com/api/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            ApiService apiService = retrofit.create(ApiService.class);
            Call<Bean> call = apiService.getCall(3);
            try {
                Response<Bean> response= call.execute();
                Log.i(TAG, "response.body()----->" + response.body());
                Log.i(TAG, "response.message()----->" + response.message());
                Log.i(TAG, "response.code()----->" + response.code());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}

好像很完美了犹菱,馬上就能收獲利用retrofit發(fā)起網(wǎng)絡(luò)請求獲得數(shù)據(jù)的喜悅了!
來吮炕,Run起來腊脱!
------------別Run了,你的結(jié)果一定是:

程序掛掉了啊哈哈哈哈

因為你沒有添加網(wǎng)絡(luò)權(quán)限A住陕凹!

<uses-permission android:name="android.permission.INTERNET" />

好,這下OK了鳄炉,這次我們真正的Run起來杜耙!

程序**又**掛掉了啊哈哈哈哈哈哈我不行了

報錯信息:

//這尼瑪我怎么在主線程進行網(wǎng)絡(luò)請求了呢!拂盯!
Caused by: android.os.NetworkOnMainThreadException

好了佑女,這下要真正的解決問題了!真正的所有代碼MainActivity.java:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    public interface ApiService {
        @GET("teacher?type=4")
        Call<Bean> getCall(@Query("num") int count);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.imooc.com/api/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        ApiService apiService = retrofit.create(ApiService.class);
        final Call<Bean> call = apiService.getCall(3);
//----這里直接new了一個子線程來進行網(wǎng)絡(luò)請求谈竿,看下方有一個Retrofit自帶的異步請求方法
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response<Bean> response= call.execute();
                    Log.i(TAG, "response.body()----->" + response.body());
                    Log.i(TAG, "response.message()----->" + response.message());
                    Log.i(TAG, "response.code()----->" + response.code());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
//如果你選擇了這種寫法
//可千萬別忘了start()!不然等會兒看不到log团驱,你又要拿起砍刀找我了!
//-------------------------------------
    }

Retrofit還有一個本身就是異步請求的方法:

        //call.enqueue()方法接收一個Callback回調(diào)空凸,我們直接new出來嚎花,這是異步請求方法
        call.enqueue(new Callback<Bean>() {
            @Override
            public void onResponse(Call<Bean> call, Response<Bean> response) {
                //當(dāng)獲取到返回結(jié)果的時候回調(diào)這個方法
                Log.i(TAG, "response.body()----->" + response.body());
                Log.i(TAG, "response.message()----->" + response.message());
                Log.i(TAG, "response.code()----->" + response.code());
            }
            @Override
            public void onFailure(Call<Bean> call, Throwable t) {
                //網(wǎng)絡(luò)請求失敗的時候回調(diào)這個方法
            }
        });

把上面的上面的new Thread(......).start();全部換成上面的代碼,也一樣OK了劫恒!

  • 當(dāng)然更推薦這里寫法了贩幻!

好了,廢話這么多两嘴,來看看log到底打印出來了一些什么吧:

log信息

真的太完美了丛楚,這個結(jié)果告訴我們請求碼是200,請求信息是OK憔辫,還給了我一個Bean對象趣些!
噢對了,看看我會不會拿到一個假的Bean對象贰您!眼見為實

        ......
            Bean b = response.body();
            Log.i(TAG, "Bean內(nèi)容:" + b.msg);
            Log.i(TAG, "Bean內(nèi)容:" + b.data.get(0).description);
         ......
還好拿到了真對象

好了坏平,至此我們已經(jīng)成功利用Retrofit進行網(wǎng)絡(luò)請求拢操,并且將得到的json直接變成了Bean對象,簡直不要太爽

  • 如果我的文章確實有幫助到你舶替,請不要忘了點一下文末的"?"讓他變成"?"
  • 作為新手難免很多地方理解不到位令境,文中若有錯誤請直(bu)接(yao)指(ma)出(wo)
  • 寫作不易!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末顾瞪,一起剝皮案震驚了整個濱河市舔庶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌陈醒,老刑警劉巖惕橙,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钉跷,居然都是意外死亡弥鹦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門爷辙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彬坏,“玉大人,你說我怎么就攤上這事犬钢〔韵剩” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵玷犹,是天一觀的道長混滔。 經(jīng)常有香客問我,道長歹颓,這世上最難降的妖魔是什么坯屿? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮巍扛,結(jié)果婚禮上领跛,老公的妹妹穿的比我還像新娘。我一直安慰自己撤奸,他們只是感情好吠昭,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胧瓜,像睡著了一般矢棚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上府喳,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天蒲肋,我揣著相機與錄音,去河邊找鬼。 笑死兜粘,一個胖子當(dāng)著我的面吹牛申窘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播孔轴,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼剃法,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了距糖?” 一聲冷哼從身側(cè)響起玄窝,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎悍引,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帽氓,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡趣斤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了黎休。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浓领。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖势腮,靈堂內(nèi)的尸體忽然破棺而出联贩,到底是詐尸還是另有隱情,我是刑警寧澤捎拯,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布泪幌,位于F島的核電站,受9級特大地震影響署照,放射性物質(zhì)發(fā)生泄漏祸泪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一建芙、第九天 我趴在偏房一處隱蔽的房頂上張望没隘。 院中可真熱鬧,春花似錦禁荸、人聲如沸右蒲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瑰妄。三九已至,卻和暖如春钧大,著一層夾襖步出監(jiān)牢的瞬間翰撑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留眶诈,地道東北人涨醋。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像逝撬,于是被迫代替她去往敵國和親浴骂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理宪潮,服務(wù)發(fā)現(xiàn)溯警,斷路器,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 簡介 剛接觸Retrofit的時候狡相,就寫了一篇簡單的使用介紹:Retrofit 2.0基本使用方法,算是對Retr...
    Whyn閱讀 2,844評論 4 24
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法梯轻,類相關(guān)的語法,內(nèi)部類的語法尽棕,繼承相關(guān)的語法喳挑,異常的語法,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 原文鏈接:http://www.reibang.com/p/a8b88c7fe831http://blog.csd...
    庸碌無為閱讀 12,414評論 20 80
  • for循環(huán) 如果你想要通過索引遍歷一個數(shù)組或者一個 list滔悉,你可以這么做: 注意這種"在區(qū)間上遍歷"會編譯成優(yōu)化...
    十旋轉(zhuǎn)45度閱讀 115評論 0 0