Retrofit在项目中的实战应用

来源:互联网 发布:怎样进注册表优化电脑 编辑:程序博客网 时间:2024/04/29 16:58
我们项目网络处理用的就是Retrofit框架,今天就先研究下如何使用(知其然),就应用层面做了解,后续再研究其所以然,准备用例子一个一个的分析
每个函数都必须带有 HTTP 注解来表明请求方式和请求的URL路径。类库中有5个HTTP注解:  GET ,  POST ,  PUT ,  DELETE , 和  HEAD。 注解中的参数为请求的相对URL路径。
先看看项目这一块的包结构

我们以其中一个为例:
这是我司服务端给的wiki
时间段内 设备下单一模块数据

 增加请求参数 expectPoint

URL

v1/mobile/device/{deviceid}/module/{moduleid}/history?start={starttime}&end={endtime}&expectPoint=200

ResoureCode

S100056

Method

GET

Parameters

{deviecid} = 设备id

{moduleId} = 模块id

{starttime} = 开始时间

{endtime} = 结束时间

{expectPoint} = 预期点数 可省略 (省略 服务端默认300)

Request JSON

Return JSON

{
"datalist" : [ {
"timestamp" : 1428940813000,
"value" : "1154.917114"
}, {
"timestamp" : 1428940843000,
"value" : "1154.631104"
}, {
"timestamp" : 1428940873000,
"value" : "1154.249634"
},
...
...
{
"timestamp" : 1429014570000,
"value" : "843.251648"
}, {
"timestamp" : 1429014600000,
"value" : "842.870178"
}, {
"timestamp" : 1429014630000,
"value" : "842.774841"
}, {
"timestamp" : 1429014660000,
"value" : "842.584106"
}, {
"timestamp" : 1429014690000,
"value" : "842.488708"
} ],
"unitName" : "毫米",
"mid" : 1169,
"unitSymbol" : "mm"
}

 
首先需要写一个接口, 接口里有很多这样的代码块
 @Headers({"X-Lngtop-Resource-Code:S100056", "X-Lngtop-Application-Id:" + C.NETWORK_APPID})    @GET("/v1/mobile/device/{deviceid}/module/{moduleid}/history")    void getDeviceModuleData(@Header("X-Lngtop-Session-Token") String token,                             @Path("deviceid") String deviceid,                             @Path("moduleid") String moduleid,                             @Query("start")String start ,                             @Query("end")String end,                             @Query("expectPoint")String expectPoint,                             Callback<LTModuleChartData> callback);
可以看到有很多的注解
@Headers()是头操作 
你可以设置使用@Headers注释静态头的方法
一:
@GET里面是URL 
getDeviceModuleData 是方法名 它里面都是这方法的参数
看看每个参数 第一个参数是@Header 这个是就是一个token 用来识别的 项目中都一样不变
第二个@Path 代表参数 这参数在GET请求的URL里有 在{}里
第三个@Query 也是参数 最后是callback 是回调函数 泛型里的实体类是这个接口中返回的json字符串对应的实体类
这是在接口里写的 然后在LTNetworkClient里写
public static void getDeviceModuleData(String deviceid,                                           String moduleid, String start,                                           String end, Callback<LTModuleChartData> callback) {        getProductClient().getDeviceModuleData(LSApp.mUserData.user_token, deviceid, moduleid,                start, end, "200 ", callback);    }
看看这个LTNetworkClient最开始写的什么
public class LTNetworkClient {    static public class LTErrorHandler implements ErrorHandler {        @Override        public Throwable handleError(RetrofitError cause) {            LTUtils.errorPerformance(LSBaseFragmentActivity.mCurAct,cause);            return new UnauthorizedException(cause);        }        private class UnauthorizedException extends Throwable {            public UnauthorizedException(RetrofitError cause) {            }        }    }    public static  String DEBUG_API_URL = BuildConfig.API_URL;    private static final Boolean debug = BuildConfig.DEBUG;    static private LTNetworkProductIF mProductClient;    static private LTNetworkProductIF getProductClient() {        if (mProductClient == null) {            mProductClient = getRestAdapter().create(LTNetworkProductIF.class);        }        return mProductClient;    }    private static RestAdapter getRestAdapter() {        final OkHttpClient okHttpClient = new OkHttpClient();        okHttpClient.setReadTimeout(20, TimeUnit.SECONDS);        okHttpClient.setConnectTimeout(20, TimeUnit.SECONDS);        RestAdapter restAdapter = new RestAdapter.Builder().                setEndpoint(DEBUG_API_URL).                setClient(new OkClient(okHttpClient)).                        build();        if (debug) {            restAdapter.setLogLevel(RestAdapter.LogLevel.FULL);        }        return restAdapter;    }public static void getDeviceModuleData(String deviceid,String moduleid, String start,String end, Callback<LTModuleChartData> callback) {        getProductClient().getDeviceModuleData(LSApp.mUserData.user_token, deviceid, moduleid,                start, end, "200 ", callback);    }}
可以看到先初始化了 LTNetworkProductIF 然后有getRestAdapter().create(LTNetworkProductIF.class); getRestAdapter() 里有RestAdapter restAdapter=newRestAdapter.Builder().setEndpoint(DEBUG_API_URL).setClient(newOkClient(okHttpClient)).build(); 返回了一个restAdapter至此准备工作已经处理好看看怎么使用 根据getDeviceModuleData这个方法可以看出我们需要传5个参数
LTNetworkClient.getDeviceModuleData(getIntent().getStringExtra("id"),                getIntent().getStringExtra("moduleid"),                (System.currentTimeMillis() - mCurTerm) + "",                System.currentTimeMillis() + "",                new Callback<LTModuleChartData>() {                    @Override                    public void failure(RetrofitError arg0) {                        dissmissHud();                        showNetworkError();                    }                    @Override                    public void success(LTModuleChartData arg0,                                        Response arg1) {                        dissmissHud();                        if (arg0 != null) {                            mChartData = null;                            System.gc();                            mChartData = arg0;                            reloadData();                        }                    }                });
这是基于GET的请求的一个完整的请求过程
二:
在来看看@POST的请求
对应的wiki

设置量程

设置量程目前40001~400004可设置

40001:压力

40002:液位

40003:出口压力

40004:保留字段

 

URL

/v1/mobile/adrange

ResoureCode

C100051

Method

POST

Parameters

Request JSON

{
"devices":["A84FAF0741BC414BB57CB540ABCFEE5C"],
"modules":[
{"name":"40001","min":"0","max":"1000"},
{"name":"40002","min":"0","max":"2000"}
]
}

Return JSON

 

{
"cmds" : [ {
"cmdid" : 96,
"deviceid" : "A84FAF0741BC414BB57CB540ABCFEE5C"
} ]
}

 

在接口里写的
@Headers({"X-Lngtop-Resource-Code:C100051", "X-Lngtop-Application-Id:" + C.NETWORK_APPID})    @POST("/v1/mobile/adrange")    void setModuleRange(@Header("X-Lngtop-Session-Token") String token,                        @Body RangeData rangeData,                        Callback<LTRangeBackData> callback);
这里我们看到了注解@Body  对应wili是请求的Request JSON 
而这个实体类RangeData 是直接写在LTNetworkProductIF里
  static public class RangeData {        public ArrayList<String> devices = new ArrayList<String>();        public ArrayList<ModuleRangeData> modules = new ArrayList<ModuleRangeData>();        public RangeData(String deviceId, ArrayList<ModuleRangeData> modules) {            this.devices.clear();            this.devices.add(deviceId);            this.modules = modules;        }        static public class ModuleRangeData {            public String name;            public String min;            public String max;        }    }
在LTNetworkClient里
public static void setModuleRange(LTNetworkProductIF.RangeData rangeData,                                      Callback<LTRangeBackData> callback) {        getProductClient().setModuleRange(LSApp.mUserData.user_token, rangeData, callback);    }
直接到用的地方就好
LTNetworkProductIF.RangeData rangeData= new LTNetworkProductIF.RangeData(deviceId, modules);                showNormalHud();                LTNetworkClient.setModuleRange(rangeData, new Callback<LTRangeBackData>() {                    @Override                    public void success(LTRangeBackData ltRangeBackData, Response response) {                        dissmissHud();                        if (ltRangeBackData.code.equalsIgnoreCase("0")) {                            //省略                        }                    }                    @Override                    public void failure(RetrofitError error) {                        dissmissHud();                    }                });
三:
@PUT
修改 抄表

URL

/v1/mobile/monthpay/enterprise/{id}/product/{id}

ResoureCode

U100061

Method

PUT

Parameters

{
"flow": 888,
"remark": "xxxxxx",
"flowMeterId": 3
}

Request JSON

 

Return JSON

{
"ticket" : "base64code",
"code" : 0
}



@Headers({"X-Lngtop-Resource-Code:U100061","X-Lngtop-Application-Id:"+ C.NETWORK_APPID})    @PUT("/v1/mobile/monthpay/enterprise/{id}/product/{productid}")    void setChangeTask(@Header("X-Lngtop-Session-Token") String token,                       @Path("id") String id, @Path("productid") String productid,                       @Body ChangeFlow changeFlow,Callback<LTMonthChangeData> callback);

static class ChangeFlow {        final String flow;        final String remark;        final String flowMeterId;        public ChangeFlow(String flow, String remark ,String flowMeterId) {            this.flow = flow;            this.remark = remark;            this.flowMeterId = flowMeterId;        }

/**     * 修改 抄表     */    public static void setChangeTask(String id, String productid, String flow, String flowid, String remark, Callback<LTMonthChangeData> callback) {        getMonthClient().setChangeTask(LSApp.mUserData.user_token, id, productid, new LTNetworkMonthIF.ChangeFlow(flow, remark, flowid), callback);    }

使用
LTNetworkClient.setChangeTask(monthPayClientData.id, monthPayClientData.productid, mQuantity                .getText().toString(), monthPayClientData.flowMeterId, mRemark.getText().toString(), new Callback<LTMonthChangeData>() {            @Override            public void success(LTMonthChangeData ltMonthChangeData, Response response) {                dissmissHud();                if (ltMonthChangeData.code != null && ltMonthChangeData.code.equalsIgnoreCase("0")) {               //省略            }            @Override            public void failure(RetrofitError error) {                dissmissHud();                LTUtils.errorPerformance(LSSalerUpdateAct.this, error);            }        });

四:
@DELETE

删除消息设置

URL

http://xxxxxx/xxx-api/v1/mobile/messagepush/{id}

MethodDELETEParameters

id = 设置ID

Request JSON

ResoureCodeD100042Return JSON

{
code: 0
}


@Headers({"X-Lngtop-Resource-Code:D100042", "X-Lngtop-Application-Id:" + C.NETWORK_APPID})    @DELETE("/v1/mobile/messagepush/{id}")    void deleteModuleAlarmList(@Header("X-Lngtop-Session-Token") String token,                            @Path("id") String id,                            Callback<LTCodeData> callback);

public static void deleteModuleAlarmList(String id, Callback<LTCodeData> callback) {        getProductClient().deleteModuleAlarmList(LSApp.mUserData.user_token, id, callback);    }

LTNetworkClient.deleteModuleAlarmList(mCurAlarm.id,new Callback<LTCodeData>() {                    @Override                    public void success(LTCodeData ltCodeData, Response response) {                        deleteSet();                    }                    @Override                    public void failure(RetrofitError error) {                    }                });            }        });
四大请求方式都介绍完了,很好用的网络请求框架.
附官方文档链接,如果对你有帮助,请点个赞或者来个好评
http://square.github.io/retrofit/

2 0