日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android快捷开发之Retrofit网络加载框架的简单使用

發布時間:2023/12/9 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android快捷开发之Retrofit网络加载框架的简单使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家都知道,安卓最大的特點就是開源化,這自然會產生很多十分好用的第三方API,而基本每一個APP都會與網絡操作和緩存處理機制打交道,當然,你可以自己通過HttpUrlConnection再通過返回數據進行解析解決,而我們自己學的東西大多數情況下都沒有針對網絡很糟糕的情況進行優化。下面就給大家帶來Square Inc這家有創新精神的公司留下的Retrofit網絡加載庫的使用!

?

項目已經同步至github:https://github.com/nanchen2251/retrofitDemo

?

Retrofit封裝了從Web API下載數據,解析成一個普通的java對象(POJO),這里我們就去天狗網使用他們的一個菜譜的API做簡單演示,供大家一起學習思考。在天狗網的API文檔網站http://www.tngou.net/doc/cook的菜譜API接口:http://www.tngou.net/api/cook/list

?

詳細使用:

1)首先得添加支持包?

compile 'com.squareup.retrofit2:retrofit:2.1.0'

  

2)然后每一次使用都需要定義一個接口,用于下載網絡數據,注意其中的{category}是為了之后更好的擴展性,我們定義一個未知的子目錄,通過參數中指定可以訪問固定的子目錄,這個方式非常棒。

package com.example.nanchen.retrofitdemo;import com.example.nanchen.retrofitdemo.json.Tngou;import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Path; import retrofit2.http.Query;/*** Created by 南塵 on 16-7-15.*/ public interface Service {@GET("/")//網址下面的子目錄Call<String> getBaidu();@GET("/api/{category}/list")//網址下面的子目錄 category表示分類,因為子目錄只有一點不一樣Call<Tngou> getList(@Path("category") String path,@Query("id") int id, @Query("page") int page, @Query("rows") int rows); }

  

3)由于我們返回的數據為Json數據,所以我們可以用它本身自帶的Gson解析方式進行返回數據的解析,同樣先導入支持包

compile 'com.squareup.retrofit2:converter-gson:2.1.0'

  

4)我們寫一個DataBean用于存放返回的數據

?

package com.example.nanchen.retrofitdemo.json;import com.google.gson.annotations.SerializedName;import java.util.List;/*** Created by 南塵 on 16-7-15.*/ public class Tngou {//加上注解@SerializedName("status")private boolean status;@SerializedName("total")private int total;@SerializedName("tngou")private List<Cook> list;public boolean isStatus() {return status;}public void setStatus(boolean status) {this.status = status;}public int getTotal() {return total;}public void setTotal(int total) {this.total = total;}public List<Cook> getList() {return list;}public void setList(List<Cook> list) {this.list = list;} }

  里面要放List, 是一個類,所以要新建一個類。

package com.example.nanchen.retrofitdemo.json;import com.google.gson.annotations.SerializedName;/*** 菜譜* Created by 南塵 on 16-7-15.*/ public class Cook {@SerializedName("id")private int id;@SerializedName("name")private String name;//名稱@SerializedName("food")private String food;//食物@SerializedName("img")private String img;//圖片@SerializedName("images")private String images;//圖片,@SerializedName("description")private String description;//描述@SerializedName("keywords")private String keywords;//關鍵字@SerializedName("message")private String message;//資訊內容@SerializedName("count")private int count;//訪問次數@SerializedName("fcount")private int fcount;//收藏數@SerializedName("rcount")private int rcount;//評論讀數public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getFood() {return food;}public void setFood(String food) {this.food = food;}public String getImg() {return img;}public void setImg(String img) {this.img = img;}public String getImages() {return images;}public void setImages(String images) {this.images = images;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getKeywords() {return keywords;}public void setKeywords(String keywords) {this.keywords = keywords;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public int getFcount() {return fcount;}public void setFcount(int fcount) {this.fcount = fcount;}public int getRcount() {return rcount;}public void setRcount(int rcount) {this.rcount = rcount;} }

  

5)我們做一個簡單演示,把返回并解析的數據放在ListView里面顯示,所以自定義一個顯示Item的Xml文件

?

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:layout_width="70dp"android:layout_height="70dp"android:src="@mipmap/ic_launcher"android:id="@+id/item_iv"/><LinearLayoutandroid:layout_gravity="center_vertical"android:orientation="vertical"android:layout_weight="1"android:layout_width="0dp"android:layout_height="wrap_content"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="標題"android:textAppearance="@android:style/TextAppearance.Large"android:id="@+id/item_title"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:maxLines="2"android:text="abcabcacbacbacbacbacbacacacacacasdadasd"android:ellipsize="end"android:id="@+id/item_info"/></LinearLayout> </LinearLayout>

  

6)主布局

<?xml version="1.0" encoding="utf-8"?> <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.nanchen.retrofitdemo.RetrofitJsonActivity"><ListViewandroid:id="@+id/json_lv"android:layout_width="match_parent"android:layout_height="match_parent"></ListView> </RelativeLayout>

  

7)自定義適配器,其中又用到了他們的圖片加載框架picasso,我們在一個項目中最好都用一個團隊的框架,這樣才會讓出錯的幾率大大降低。

當然別忘了添加支持包

compile 'com.squareup.picasso:picasso:2.3.2'

  再是Adapter

1 package com.example.nanchen.retrofitdemo.json; 2 3 import android.content.Context; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.BaseAdapter; 8 import android.widget.ImageView; 9 import android.widget.TextView; 10 11 import com.example.nanchen.retrofitdemo.R; 12 import com.squareup.picasso.Picasso; 13 14 import java.util.Collection; 15 import java.util.List; 16 17 /** 18 * Created by 南塵 on 16-7-15. 19 */ 20 public class MyAdapter extends BaseAdapter { 21 22 private Context context; 23 private List<Cook> list; 24 25 public MyAdapter(Context context, List<Cook> list) { 26 this.context = context; 27 this.list = list; 28 } 29 30 @Override 31 public int getCount() { 32 if (list != null){ 33 return list.size(); 34 } 35 return 0; 36 } 37 38 @Override 39 public Object getItem(int position) { 40 return list.get(position); 41 } 42 43 @Override 44 public long getItemId(int position) { 45 return position; 46 } 47 48 @Override 49 public View getView(int position, View convertView, ViewGroup parent) { 50 if (convertView == null){ 51 convertView = LayoutInflater.from(context).inflate(R.layout.list_item,parent,false); 52 convertView.setTag(new ViewHolder(convertView)); 53 } 54 ViewHolder holder = (ViewHolder) convertView.getTag(); 55 Cook cook = list.get(position); 56 holder.tv_title.setText(cook.getName()); 57 holder.tv_info.setText(cook.getDescription()); 58 //使用同樣開發團隊的Picasso支持包進行圖片加載,由于接口中返回的img路徑不是全的,所以需要加上網站前綴 59 Picasso.with(context).load("http://tnfs.tngou.net/img"+cook.getImg()).into(holder.iv); 60 return convertView; 61 } 62 63 public void addAll(Collection<? extends Cook> collection){ 64 list.addAll(collection); 65 notifyDataSetChanged(); 66 } 67 68 public static class ViewHolder{ 69 private final ImageView iv; 70 private final TextView tv_title; 71 private final TextView tv_info; 72 73 public ViewHolder(View item){ 74 iv = ((ImageView) item.findViewById(R.id.item_iv)); 75 tv_title = ((TextView) item.findViewById(R.id.item_title)); 76 tv_info = ((TextView) item.findViewById(R.id.item_info)); 77 } 78 } 79 }

?

8)再看看Activity的代碼

?

1 package com.example.nanchen.retrofitdemo; 2 3 import android.os.Bundle; 4 import android.support.v7.app.AppCompatActivity; 5 import android.widget.ListView; 6 7 import com.example.nanchen.retrofitdemo.json.Cook; 8 import com.example.nanchen.retrofitdemo.json.MyAdapter; 9 import com.example.nanchen.retrofitdemo.json.Tngou; 10 11 import java.util.List; 12 13 import retrofit2.Call; 14 import retrofit2.Callback; 15 import retrofit2.Response; 16 import retrofit2.Retrofit; 17 import retrofit2.converter.gson.GsonConverterFactory; 18 19 public class RetrofitJsonActivity extends AppCompatActivity implements Callback<Tngou> { 20 21 22 private ListView lv; 23 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.activity_retrofit_json); 28 29 Retrofit retrofit = new Retrofit.Builder().baseUrl("http://www.tngou.net") 30 .addConverterFactory(GsonConverterFactory.create()).build(); 31 Service service = retrofit.create(Service.class); 32 Call<Tngou> call = service.getList("cook",0, 1, 20); 33 call.enqueue(this); 34 lv = (ListView) findViewById(R.id.json_lv); 35 36 } 37 38 @Override 39 public void onResponse(Call<Tngou> call, Response<Tngou> response) { 40 List<Cook> list = response.body().getList(); 41 lv.setAdapter(new MyAdapter(this,list)); 42 } 43 44 @Override 45 public void onFailure(Call<Tngou> call, Throwable t) { 46 47 } 48 }

最后上一波運行圖

?

?

?

?

2016年8月1日補充

————————————————————————————————————————————————

下面帶來一些2.0版本后需要注意的問題。

1)Retrofit ?2.0版本后趨向于在baseUrl中以“/”結尾,@Url不要以“/”開頭,這樣更專業。額,其實你還可以把整個地址放在接口中去,這樣baseUrl就忽略了。

1 Retrofit retrofit = new Retrofit.Builder().baseUrl("http://www.tngou.net/") 2 .addConverterFactory(GsonConverterFactory.create()).build();

2)Retrofit的事務可以在之后立即取消,只需要調用call.cancel()即可,好簡單哈哈。

3)官方提供了好幾種ConverterFactory,適合你的才是最好的,自己去選擇吧~

Gson:?com.squareup.retrofit:converter-gson

Jackson:?com.squareup.retrofit:converter-jackson

Moshi:?com.squareup.retrofit:converter-moshi

Protobuf:?com.squareup.retrofit:converter-protobuf

Wire:?com.squareup.retrofit:converter-wire

Simple XML:?com.squareup.retrofit:converter-simplexml

4)額,你還可以選擇實現Converter.Factory接口來自定義一個converter,啦啦啦。

5)oh,no,遇到服務器返回的時間格式很奇葩怎么辦?哈哈,其實你完全可以通過GsonBuilder().create()創建一個gson對象作為Converter的參數來實現自定義Gson對象呀。

1 //需要使用的時候放到GsonConverterFactory.create(gson)中作為參數即可。 2 Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create(); 3 4 5 6 Retrofit retrofit = new Retrofit.Builder().baseUrl("http://www.tngou.net/") 7 .addConverterFactory(GsonConverterFactory.create(gson)).build();

6)之前有的小伙伴會問為什么我們在Demo中用call.enqueue而沒有用execute,這是因為我們一般都選擇用enqueue,這樣會默認在異步線程中執行,少寫一個線程,何樂而不為呢?

7)額,之前Demo沒有對Retrofit 2.0 的注解方式進行完善的整理,這里給大家帶來一些更詳細的東西。

8)首先帶來http的請求方法:

我們一般常用的就是GET請求和POST請求,當然你或許會用到http的其他注解方式,值得注意的是HTTP注解方式可以涵蓋上面的任意一種注解。

而它有三個屬性:method,path,hasBody。

9)再帶來標記類

額,上面的這個表單請求,我相信在post請求中用的不少吧,你值得嘗試。

10)當然就少不了我們的參數類咯,圖片來源于網絡。

這里值得注意的是:

{占位符}和path都盡量出現在Url的path部分,url中的參數使用Query和QueryMap代替,保證接口定義的簡潔。

另外,Query,Field和Part都支持數組和實現了Iterable接口的類型,如List,Set等,方便向后臺傳遞數組。

好了,這個強大的Retrofit就補充到這里了,大家可以自行補充。

?

轉載于:https://www.cnblogs.com/liushilin/p/5680135.html

總結

以上是生活随笔為你收集整理的android快捷开发之Retrofit网络加载框架的简单使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩一级片网址 | 91免费观看网站 | 亚洲第3页 | 91麻豆国产福利精品 | 狠狠躁18三区二区一区传媒剧情 | 黑人精品一区二区 | 国产精品视频一区二区三区 | 久久av一区二区三区 | 亚洲夜夜爱 | 亚洲一区二区三区视频 | 欧美做爰啪啪xxxⅹ性 | 久久精品综合网 | www.成人网.com | 性xxxx搡xxxxx搡欧美 | 国产一区二区三区毛片 | 欧美www在线观看 | 风韵丰满熟妇啪啪区老熟熟女 | 男人天堂五月天 | 1024国产视频 | 黑色丝袜吻戏亲胸摸腿 | 一二三在线视频 | 亚洲一区二区自拍偷拍 | 国产人妻一区二区三区四区五区六 | av作品在线 | 热久久久久久久 | 欧美午夜精品理论片 | 免费一级大片 | 红桃视频成人在线 | 久久久黄色片 | 正在播放一区 | 欧美精品欧美极品欧美激情 | 草久在线 | 麻豆蜜臀 | 日本免费无人高清 | 天堂网av中文字幕 | 私拍在线 | 一区二区欧美在线 | 精品乱码一区二区三四区视频 | 在线观看亚洲区 | av在线日韩 | 特级西西人体444www高清 | caoporen超碰| 亚欧色视频 | 偷拍一区二区三区 | 午夜影院毛片 | 60分钟| 91在线视频观看 | 亚洲欧洲日韩国产 | 911亚洲精选 | 中文字幕av一区二区三区 | 亚洲男人的天堂在线 | www四虎影院 | 天天摸天天做天天爽 | 日韩精品高清视频 | 久视频在线观看 | 欧美韩日一区二区 | 韩国无码av片在线观看网站 | 91黄色片 | 中文字幕在线观看线人 | 一级黄色大片免费 | 亚洲AV无码国产精品午夜字幕 | 日韩免费在线视频 | 夜夜操网站 | 亚洲逼图| 伊人快播 | 色屁屁一区二区三区视频 | 国产999在线观看 | 日韩视频免费在线 | 99r热| 全部免费毛片在线播放一个 | 日韩精品一区二区亚洲av性色 | 伊人久在线 | 秋霞网一区二区 | 欧美人一级淫片a免费播放 西方av在线 | 国产片自拍| αv在线 | 男女激情视频网站 | 丰满熟妇肥白一区二区在线 | 丰满少妇一区二区 | 久久久久久一区 | 日韩高清一二三区 | 三级三级久久三级久久18 | 日韩欧美黄 | 国产r级在线 | 黄在线观看免费 | 中文字幕日韩一级 | 亚洲天堂视频一区 | 中文av一区二区三区 | 国产cao| 特黄1级潘金莲 | 夜夜操夜夜爱 | 黄色自拍网站 | 天天狠天天插 | 天堂网av在线播放 | www.成人av.com | 天天激情 | 在线成人av | 精品少妇人妻av一区二区三区 | 国产噜噜噜噜噜久久久久久久久 |