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