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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/286996.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打开计算机无法显示工具栏,任务栏不显示打开的窗口怎么办教程

我们在使用电脑的时候&#xff0c;打开很多程序的时候&#xff0c;会最小化某些窗口&#xff0c;只留在用的窗口&#xff0c;而最小化都是缩小为一个图标放入屏幕下方的任务栏的&#xff0c;但有时候不知道为什么任务栏不显示打开的窗口了&#xff0c;这时候也就无法直接用鼠标…

ArcGIS 10.6提取道路中心线的两种方法经典教程

我们工作中碰到的道路数据通常为面状,需要提取道路中心线,本文讲解ArcGIS10.6中从面状道路数据中提取道路中心线的两种常用经典方法。 方法一:使用ArcGIS 10.6提供的提取道路中心线工具 本实验中使用到面状数据如下所示: 首先,将面状数据转为线状数据。 转完之后,道路尽头…

衡量计算机浮点数操作性能,计算机系统基础:计算机性能评价知识笔记

1、计算机性能常用的性能评测方法1.1 时钟频率计算机的时钟频率可以反映出机器的运行速度。一般主频越高&#xff0c;速度越快。1.2 指令执行速度加法指令执行速度是衡量计算机性能指标的重要指标之一。1.3 等效指令速度法随着计算机指令系统发展&#xff0c;种类越来越多&…

python 写游戏好简单啊,我用键盘可以随意控制角色了【python 游戏实战 04】

前言 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新&#xff0c;包括别的语言以及实战都将使用对话的方式进行教学&#xff0c;基础编程语言教学适用于零基础小白&#xff0c;之后实战课程也将会逐步更新…

树形表的平行查询设计

本文由网友长空X投稿&#xff0c;欢迎转载、分享原文作者&#xff1a;长空X&#xff08;CSDN同名“长空X“&#xff0c;CkTools的作者&#xff0c;github: https://github.com/hjkl950217&#xff09;原文链接&#xff1a;https://www.cnblogs.com/gtxck/articles/16293295.htm…

Ubuntu 16.04安装SQLite Browser操作SQLite数据库

安装&#xff1a; sudo apt-get install sqlitebrowser 启动&#xff1a;

(13)python 字典 2 分钟速解

本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新&#xff0c;包括别的语言以及实战都将使用对话的方式进行教学&#xff0c;基础编程语言教学适用于零基础小白&#xff0c;之后实战课程也将会逐步更新。 若…

计算机绘画作品 星空,关于近期绘画作品《星空系列》的自述:

《星空系列》是一个很偶然的念想下产生的&#xff0c;但又绝非偶然。最开初的点是高一刚开始学画的时候&#xff0c;高中的老师给我们免费提供油画材料给我们练习&#xff0c;那时候我并没有“安分”地练习高考绘画&#xff0c;总想做一些关于自己想法的作品&#xff0c;那时候…

BootStrap导航栏的使用

默认的导航栏 创建一个默认的导航栏的步骤如下&#xff1a; 向 <nav> 标签添加 class .navbar、.navbar-default。向上面的元素添加 role"navigation"&#xff0c;有助于增加可访问性。向 <div> 元素添加一个标题 class .navbar-header&#xff0c;内部包…

安装SQL Server 2005时,出现“SQL Server 服务无法启动。……”提示的解决方法

安装SQL Server 2005时&#xff0c;出现“SQL Server 服务无法启动。……”提示的解决方法上午在自己XP SP3电脑上安装SQL Server 2005时出现如下提示&#xff1a; 根据这一情况&#xff0c;我把自己的解题步骤写下来和大家分享&#xff0c;虽然简单了些&#xff0c;可是安装的…

.NET MAUI 正式发布,再见了 Xamarin.Forms

David Ortinau 在dotnet 团队博客上发表了一篇文章《Introducing .NET MAUI – One Codebase, Many Platforms》&#xff0c;在这篇文章里宣布了MAUI的正式发布。https://github.com/dotnet/maui/releases/tag/6.0.312 https://devblogs.microsoft.com/dotnet/introducing-dotn…

利用SQL注入获取服务器最高权限

单位有台数据库服务器&#xff08;windows 2000 操作系统&#xff0c;sql server 2000&#xff09;前段时间莫名其妙的被***了跑到机房&#xff0c;通过PE进去一看&#xff0c;发现多了一个账户&#xff08;SQLDEBUG)。并且administrator账户被禁用了看看数据没少&#xff0c;也…

3分钟搞定 C++ if else 语句 05

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。系列教程将会…

Android之封装倒计时页面

1 、需求 多个页面需要用到显示定时器页面,页面里面时间会一秒一秒减少,页面布局如下,开了定时器,如果其它页面也打开会使用之前的页面里面显示的时间,也就是说在有效范围内,时间不刷新。 2 、关键点 使用Android自带的倒计时类CountDownTimer CountDownTimer mCount…

1小时学会不打代码制作一个网页精美简历(1)

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。系列教程将会在…

分部方法 partial

当有如下这样类似的情况出现的时候&#xff0c;可以有更好的优化方式来处理&#xff0c;那就是分部方法 1 class PartOld2 {3 string name;4 5 public virtual void OnChangeName(string str)6 {7 }8 9 public string Name 10…

一文讲透为Power Automate for Desktop (PAD) 实现自定义模块

今天写了一篇长文&#xff0c;《一文讲透为Power Automate for Desktop (PAD) 实现自定义模块 - 附完整代码》&#xff0c;有兴趣的同学点击 “阅读原文” 参考 &#xff0c;文章地址是 https://www.cnblogs.com/chenxizhang/p/16287195.html 微软的PAD是RPA的一种&#xff0…

软件自动化测试的主要目的,功能测试的目的是什么

从功能测试到自动化测试&#xff1f;从常见的自动化测试过程开始&#xff01;在项目的启动阶段功能测试 目的&#xff0c;我们必须阐明为什么要进行自动化&#xff0c;并选择合适的项目进行自动化测试. 1.为什么要进行自动化&#xff1f;在开始自动化测试之前&#xff0c;我们需…

基于Google Earth Pro做数字化,并在ArcGIS中转为Shapefile图层

在精度满足要求的前提下,可以基于Google Earth Pro做数字化,并在ArcGIS中转为Shapefile图层,然后经行投影转换,得到最终的shp数据。主要步骤包括:新建多边形、导出多边形、格式转换,投影转换等。 一. 新建多边形 命名为皇城水库范围,设置线条和面的样式/颜色,并在影像上…

1小时,不会代码的我如何完成 网易云音乐 大作业网页制作?(IVX 第2篇)

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。系列教程将会在…