您的位置:首页 > 理论基础 > 计算机网络

定义Retrofit 网络接口服务的包装类(基础类)

2016-08-23 17:31 483 查看
1、根据API返回的json数据来创建一个FamousInfo数据对象,我们可以利用AndroidStudio插件 GsonFormat 快速,方便的将json数据转为Java
对象。

FamousInfo


package test.ban.com.myapplication.bean;

import java.util.List;

/**
* Created by ban
*/
public class FamousInfo {

/**
* total : 227
* result : [{"famous_name":"车尔尼雪夫斯基","famous_saying":"非凡的单纯,非凡的明确\u2014\u2014这是天才的智慧的最可惊人的品质。"},{"famous_name":"约·德莱顿","famous_saying":"天才在社会生活中往往显得迟钝而"},{"famous_name":"雨果","famous_saying":"敢于冲撞命运才是天才"},{"famous_name":"卡莱尔","famous_saying":"所谓天才,就是比任何人都先抵挡痛苦的经验本领。"},{"famous_name":"林肯","famous_saying":"卓越的天才不屑走一条人家走过的路。他寻找迄今没有开拓过的地区。"},{"famous_name":"席勒","famous_saying":"产生天才的土壤比天才还要难找"},{"famous_name":"爱因斯坦","famous_saying":"任何天才不能在孤独的状态中发展"},{"famous_name":"民谚","famous_saying":"名人的古怪行为是天才的标志,凡人的古怪行为是神经出了毛病"},{"famous_name":"鲁迅","famous_saying":"哪里有天才,我是把别人喝咖啡的工夫都用在了工作上了。"},{"famous_name":"塞涅夫","famous_saying":"没有某些发狂的劲头,就没有天才。"},{"famous_name":"狄德罗","famous_saying":"精神的浩瀚想象的活跃心灵的勤奋:就是天才。"},{"famous_name":"爱默生","famous_saying":"平凡的人希望,天才的人创造。"},{"famous_name":"契诃夫","famous_saying":"真正的天才是常常隐藏在群众里面,绝不挤向人前去露脸的。"},{"famous_name":"别林斯基","famous_saying":"任何天才,不经过艰苦不断的劳动,不经过最使空想家头疼和懊恼的最初纯物质和机械的劳动,就无法精通任何种类的艺术。"},{"famous_name":"杨格","famous_saying":"我愿意以天才比美德,以学问比财富。如美德越少的人,越需要财富,天才越低的人,越需要学问。"},{"famous_name":"巴尔扎克","famous_saying":"职业尽管不同,但天才的品德并无分别。"},{"famous_name":"恩格斯","famous_saying":"逆境使天才脱颖而出,顺境会埋没"},{"famous_name":"巴尔扎克","famous_saying":"破坏的人和建设的人,两者都是意志的现象:一个是准备工作,另一个是完成工作;前者好像是一个恶的天才,后者似乎是一个善的天才;对这一个给予光荣,对另一个给予忘却。恶者哇啦哇啦,把庸俗的人们从梦里惊醒,对他佩服得五体投地,可是善者却一直默不作声。"},{"famous_name":"培根","famous_saying":"如果孩子确有某种超群的天才,那当然应该扶植发展。但就一般情况说,下面这句格言很有用的:\u201c长期的训练会通过适应化难为易。\u201d"},{"famous_name":"爱迪生","famous_saying":"天才是百分之一的灵感,百分之九十九的血汗。"}]
* error_code : 0
* reason : Succes
*/

private int total;
private int error_code;
private String reason;
/**
* famous_name : 车尔尼雪夫斯基
* famous_saying : 非凡的单纯,非凡的明确——这是天才的智慧的最可惊人的品质。
*/

private List<ResultEntity> result;

public void setTotal(int total) {
this.total = total;
}

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

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

public void setResult(List<ResultEntity> result) {
this.result = result;
}

public int getTotal() {
return total;
}

public int getError_code() {
return error_code;
}

public String getReason() {
return reason;
}

public List<ResultEntity> getResult() {
return result;
}

public static class ResultEntity {
private String famous_name;
private String famous_saying;

public void setFamous_name(String famous_name) {
this.famous_name = famous_name;
}

public void setFamous_saying(String famous_saying) {
this.famous_saying = famous_saying;
}

public String getFamous_name() {
return famous_name;
}

public String getFamous_saying() {
return famous_saying;
}
}
}

FamousInfoReq

package test.ban.com.myapplication.bean;

import java.io.Serializable;

/**
* Created by ban
*/
public class FamousInfoReq implements Serializable{
public String apiKey;
public String keyword; //关键字
public int page;  //请求页数,默认page=1
public int rows;   //返回记录条数,默认rows=20,最大50

public String getApiKey() {
return apiKey;
}

public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}

public String getKeyword() {
return keyword;
}

public void setKeyword(String keyword) {
this.keyword = keyword;
}

public int getPage() {
return page;
}

public void setPage(int page) {
this.page = page;
}

public int getRows() {
return rows;
}

public void setRows(int rows) {
this.rows = rows;
}
}

2、创建一个接口,返回 Call;如下:

package test.ban.com.myapplication.netApi;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Query;
import test.ban.com.myapplication.bean.FamousInfo;

/**
* Created by ban
* 这里我们使用的是Retrofit 提供注解的方式来定义接口的
* @get后面我们填写需要访问对应的接口地址
* @Header用来添加Header
* @Query用来添加查询关键字
*/
public interface FamousService {
@GET("/avatardata/mingrenmingyan/lookup")
Call<FamousInfo> getFamousResult(@Header("apiKey") String apiKey,
@Query("keyword") String keyword,
@Query("page") int page,
@Query("rows") int rows);
}

3、定义Retrofit 网络接口服务的包装类 (基础类)

package test.ban.com.myapplication.utils;/**
* Created by apple on 16/8/23.
*/

import android.content.Context;

import retrofit2.GsonConverterFactory;
import retrofit2.Retrofit;

/**
* 定义Retrofit 网络接口服务的包装类
* 作者:ban on 16/8/23 15:55
*/
public class RetrofitWrapper {

private static RetrofitWrapper instance;
private Context mContext;
private Retrofit mRetrofit;

private RetrofitWrapper(){
//创建retrofit
mRetrofit = new Retrofit.Builder().baseUrl(Constant.BASEURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}

/**
* 单例模式 获取唯一的网络接口服务的包装类RetrofitWrapper
* @return
*/
public static RetrofitWrapper getInstance(){
if(instance == null){
synchronized (RetrofitWrapper.class){
if (instance == null) {
instance = new RetrofitWrapper();
}
}
}
return instance;
}

/**
* 抽取一层 在创建retrofit时,只需要传入不同的service(对应创建不同的接口),即可完成创建不同的retrofit,
* =====================================例子如下: ============================================
* FamousService mFamousService = RetrofitWrapper.getInstance().create(FamousService.class);
* =========================================================================================
* @param service
* @param <T>
* @return
*/
public <T> T create(final Class<T> service){
return mRetrofit.create(service);
}

}


4、网络服务的包装类定义好了之后,在定义一个访问的Model

package test.ban.com.myapplication.model;/**
* Created by apple on 16/8/23.
*/

import android.content.Context;

import retrofit2.Call;
import test.ban.com.myapplication.bean.FamousInfo;
import test.ban.com.myapplication.bean.FamousInfoReq;
import test.ban.com.myapplication.netApi.FamousService;
import test.ban.com.myapplication.utils.RetrofitWrapper;

/**
* 网络服务的包装类定义好了之后,在定义一个访问的Model。
* 即:定义了相对应的外层方法。底层的包装类不会改变,只会根据不同的类做响应的事情。
* 作者:ban on 16/8/23 16:02
*/
public class FamousInfoModel {

private static FamousInfoModel sFamousInfoModel;
private FamousService mFamousService;

public static FamousInfoModel getInstance(Context context){
if(sFamousInfoModel == null){
sFamousInfoModel = new FamousInfoModel(context);
}
return sFamousInfoModel;
}

private FamousInfoModel (Context context){
mFamousService  = RetrofitWrapper.getInstance().create(FamousService.class);

}

public Call<FamousInfo> queryLookUp(FamousInfoReq famousInfoReq){
Call<FamousInfo> infoCall = mFamousService.getFamousResult(famousInfoReq.apiKey,
famousInfoReq.keyword,famousInfoReq.page,famousInfoReq.rows);
return infoCall;
}
}


5、使用

package test.ban.com.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import test.ban.com.myapplication.bean.FamousInfo;
import test.ban.com.myapplication.bean.FamousInfoReq;
import test.ban.com.myapplication.model.FamousInfoModel;
import test.ban.com.myapplication.utils.Constant;

public class MainActivity extends AppCompatActivity {

public final String TAG = this.getClass().getName();
private FamousInfoModel mfamousInfoModel;
private EditText mEditKeyWord;
private ImageButton mSerachBtn;
private TextView mTxtContent;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mfamousInfoModel = FamousInfoModel.getInstance(getApplicationContext());
initView();
initParams();
initEvent();
}

/**
* 初始化View
*/
private void initView() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// setSupportActionBar(toolbar);
mEditKeyWord = (EditText) findViewById(R.id.edit_keyword);
mSerachBtn = (ImageButton) findViewById(R.id.button_search);
mTxtContent = (TextView) findViewById(R.id.txt_content);

}

/**
* 初始化参数
*/
private FamousInfoReq initParams() {
FamousInfoReq mFamousInfoReq = null;
mFamousInfoReq = new FamousInfoReq();
mFamousInfoReq.apiKey = Constant.APIKEY;
mFamousInfoReq.keyword = mEditKeyWord.getText().toString();
mFamousInfoReq.page = 3;
mFamousInfoReq.rows = 30;
return mFamousInfoReq;
}

/**
* 使用分为四步:
* <p>
* -- 创建Retrofit对象
* -- 创建访问API的请求
* -- 发送请求
* -- 处理结果
* <p>
* 主要代码如下:
*/
public void initEvent() {
mSerachBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Call<FamousInfo> famousInfoCall = mfamousInfoModel.queryLookUp(initParams());

famousInfoCall.enqueue(new Callback<FamousInfo>() {
@Override
public void onResponse(Call<FamousInfo> call, Response<FamousInfo> response) {
if (response.isSuccess()) {
FamousInfo info = response.body();
if (info != null) {
List<FamousInfo.ResultEntity> entity = info.getResult();
mTxtContent.setText("1、" + entity.get(0).getFamous_saying() +
"\n---" + entity.get(0).getFamous_name() + "\n 2、"
+ entity.get(1).getFamous_saying() + "\n---" + entity
.get
(1).getFamous_name());
}
}
}

@Override
public void onFailure(Call<FamousInfo> call, Throwable t) {
Toast.makeText(MainActivity.this, "onFaile-retrofit", Toast.LENGTH_SHORT)
.show();
}
});
}
});
}
}

其它用到的类等

package test.ban.com.myapplication.utils;

/**
* Created by ban
*/
public class Constant {
public  static String BASEURL="http://apis.baidu.com"; //服务器地址
public  static String APIKEY="4c4f0c3c49e09d5578ae0ba49fa84a97";
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

<include layout="@layout/content_main" />

</android.support.design.widget.CoordinatorLayout>


content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".ui.activity.MainActivity"
tools:showIn="@layout/activity_main">

<RelativeLayout
android:id="@+id/search_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:gravity="center_vertical"
android:orientation="horizontal">

<EditText
android:id="@+id/edit_keyword"
android:layout_width="match_parent"
android:layout_height="50dp"
android:paddingLeft="10dp"
android:layout_toLeftOf="@+id/button_search"
android:layout_weight="1"
android:hint="请输入名人名言的关键字"
android:textColorHint="#FFFFFF"
android:textColor="#ffffff" />

<ImageButton
android:id="@+id/button_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="15dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:src="@mipmap/ic_search_white_36dp" />
</RelativeLayout>
<RelativeLayout
android:layout_below="@id/search_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/txt_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</RelativeLayout>

</RelativeLayout>

ic_search_white_36dp.png
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐