Retrofit在项目中的实战应用

时间:2022-09-08 17:48:28
我们项目网络处理用的就是Retrofit框架,今天就先研究下如何使用(知其然),就应用层面做了解,后续再研究其所以然,准备用例子一个一个的分析
每个函数都必须带有 HTTP 注解来表明请求方式和请求的URL路径。类库中有5个HTTP注解:   GET ,   POST ,   PUT ,   DELETE , 和   HEAD。 注解中的参数为请求的相对URL路径。
先看看项目这一块的包结构

Retrofit在项目中的实战应用

我们以其中一个为例:
这是我司服务端给的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 = new RestAdapter . Builder (). setEndpoint ( DEBUG_API_URL ). setClient ( new OkClient ( 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
Method DELETE
Parameters

id = 设置ID

Request JSON

ResoureCode D100042
Return 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/