[关闭]
@wuseal 2019-03-21T05:07:42.000000Z 字数 5649 阅读 533

叮咚Android工程接口请求功能改造

工具 叮咚


先梳理下之前做后台接口API请求的使用方式

第一步

先修改TpClient类,添加一个执行API请求的入口方法,如下

  1. public final void doApiRequest(RequestCmd requestCmd) {
  2. CommonRestCallManager.commonRestCall(CommonRestCallType.RequestType, requestCmd);
  3. }

第二步

修改CommonRestCallType类添加一个请求API的类型整型常量,且注意不能与之前已经有类型的值重复

  1. public static final int RequestType = 3205;

想像下,如果常量类型已经有很多,且值的定义并没有明确的规定和范围限定,那么定义这个类型值冲突的可能性还是有的,而且每次都得过滤下之前定义过的类型,保证唯一才行,费心有费心

第三步

定义并实现RequestCmd类,其实这个类型的定义是请求参数的代表类,但是在这里,每一个API请求都得定义一个这样的类

  1. public class RequestCmd extends DTRestCallBase {
  2. private String paramKey1 = "key1";
  3. private String paramKey2 = "key2";
  4. private String paramValue1 = "value1";
  5. private String paramValue2 = "value2";
  6. public String getParamKey1() {
  7. return paramKey1;
  8. }
  9. public void setParamKey1(String paramKey1) {
  10. this.paramKey1 = paramKey1;
  11. }
  12. public String getParamKey2() {
  13. return paramKey2;
  14. }
  15. public void setParamKey2(String paramKey2) {
  16. this.paramKey2 = paramKey2;
  17. }
  18. public String getParamValue1() {
  19. return paramValue1;
  20. }
  21. public void setParamValue1(String paramValue1) {
  22. this.paramValue1 = paramValue1;
  23. }
  24. public String getParamValue2() {
  25. return paramValue2;
  26. }
  27. public void setParamValue2(String paramValue2) {
  28. this.paramValue2 = paramValue2;
  29. }
  30. }

第四步

修改RestCallEncoderFactory类,并在如下方法体里进行修改

  1. public static RestCallEncoder createRestCallEncoder(int commonRestCallType, DTRestCallBase restCallBase) {
  2. switch (commonRestCallType) {
  3. case CommonRestCallType.CREATE_GIAP_ORDER:
  4. return new CreateGIAPOrderEncoder(restCallBase);
  5. case CommonRestCallType.GET_INVITE_LINK:
  6. return new GetInviteLinkEncoder(restCallBase);
  7. ...

在switch case条件判断里添加如下代码

  1. case CommonRestCallType.RequestType:
  2. return new RequestCmdEncode(restCallBase);

第五步

定义并实现RequestCmdEncode类

  1. class RequestCmdEncode extends RestCallEncoder {
  2. private RequestCmd requestCmd;
  3. public RequestCmdEncode(DTRestCallBase restCallCmd) {
  4. super(restCallCmd);
  5. requestCmd = (RequestCmd) restCallCmd;
  6. }
  7. @Override
  8. public DTCommonRestCallCmd encode() {
  9. DTCommonRestCallCmd cmd = super.encode();
  10. cmd.setCommandTag(CommonRestCallType.RequestType);
  11. cmd.setApiName("/router/path");
  12. StringBuffer sb = new StringBuffer();
  13. sb.append("&");
  14. sb.append(requestCmd.getParamKey1());
  15. sb.append("=");
  16. sb.append(requestCmd.getParamValue1());
  17. sb.append("&");
  18. sb.append(requestCmd.getParamKey2());
  19. sb.append("=");
  20. sb.append(requestCmd.getParamValue2());
  21. cmd.setApiParams(sb.toString());
  22. return cmd;
  23. }
  24. }

第六步

修改RestCallDecoderFactory类,并在createRestCallDecoder方法体的switch case条件判断里再增加如下代码:

  1. ...
  2. case CommonRestCallType.RequestType:
  3. return new RequestCmdDecoder(commonRestCallBase.responseData, commonRestCallBase.getCommandCookie());
  4. ...

第七步

定义并实现RequestCmdDecoder类型

  1. class RequestCmdDecoder extends RestCallDecoder {
  2. public RequestCmdDecoder(String responseData, int commandCookie) {
  3. super(responseData, commandCookie);
  4. mRestCallResponse=new RequestResponse();
  5. }
  6. @Override
  7. protected void decodeResponseData(JSONObject jsonObj) {
  8. try {
  9. if (mRestCallResponse.getErrCode() == 0) {
  10. mRestCallResponse.setResult(jsonObj.getInt("Result"));
  11. ((RequestResponse)mRestCallResponse).data1=jsonObj.optString("data1");
  12. ((RequestResponse)mRestCallResponse).data2=jsonObj.optInt("data2");
  13. ((RequestResponse)mRestCallResponse).data3=jsonObj.optString("data3");
  14. } else {
  15. mRestCallResponse.setResult(jsonObj.optInt("Result"));
  16. mRestCallResponse.setErrorCode(jsonObj.optInt("ErrCode"));
  17. mRestCallResponse.setReason(jsonObj.optString("Reason"));
  18. }
  19. } catch (JSONException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. @Override
  24. public void onRestCallResponse() {
  25. TpClient.getInstance().onRequestDemoResponse((RequestResponse)mRestCallResponse);
  26. }
  27. }

第八步

定义并实现RequestResponse类型

  1. class RequestResponse extends me.dingtone.app.im.datatype.DTRestCallBase {
  2. public String data1;
  3. public int data2;
  4. public String data3;
  5. }

第九步

再次修改TpClient类,添加onRequestDemoResponse方法

  1. public void onRequestDemoResponse(RequestResponse mRestCallResponse) {
  2. mTpEventHandler.onRequestDemoResponse(response);
  3. }

第十步

修改TpEventHandler类,并添加onRequestDemoResponse方法

  1. public void onRequestDemoResponse(RequestResponse mRestCallResponse) {
  2. ServiceMgr.getInstance().handleResponse(DTRESTCALL_TYPE.DTRESTCALL_TYPE_DEMO_REQUEST, mRestCallResponse);
  3. }

第十一步

修改DTRESTCALL_TYPE类并添加DTRESTCALL_TYPE_DEMO_REQUEST常量类,并保证其值为唯一性

  1. public final static int DTRESTCALL_TYPE_WALLET_POINT_ADD = 0x1520;
  2. public static final int DTRESTCALL_TYPE_DEMO_REQUEST = 0x1521;

好了,十一步完成,我们现在可以开始正式去使用这个接口请求返回数据的功能了

第十二步

在要使用API请求的在地方,调用之前声明的调用API请求执行的触发方法,一般在Activity里的onCreate()方法里里执行如下代码

  1. RequestCmd cmd = new RequestCmd();
  2. cmd.setParamKey1("key1");
  3. cmd.setParamKey2("key2");
  4. cmd.setParamValue1("value1");
  5. cmd.setParamValue2("value2");
  6. TpClient.getInstance().doApiRequest(cmd);

第十三步

请求了API,总要的回调的地方吧,在要使用API请求的在地方,比如在Activity内去请求一个接口的数据,那需要在Activity内去注册一下当前的请求响应回调的实例。

  1. UIMgr.getInstance().registerActivityEvent(DTRESTCALL_TYPE.DTRESTCALL_TYPE_DEMO_REQUEST, this);

第十四步

让当前的Activity实现me.dingtone.app.im.manager.Event接口,记住,实现的接口只有handleEvent可用,另一个接口方法handleRefreshUI暂时没有用。handleEvent方法就是表示后台API接口请求完成后会回调的方法。

  1. @Override
  2. public void handleEvent(int evtType, Object obj) {
  3. if (evtType == DTRESTCALL_TYPE.DTRESTCALL_TYPE_DEMO_REQUEST) {
  4. RequestResponse response = (RequestResponse) obj;
  5. //r接下来就可以使用API返回的数据进行界面的渲染等工作了
  6. String data1 = response.data1;
  7. }
  8. ...

好了,现有的RestCall请求就是这样添加一个新的接口的使用的,我的一句感受,WTF,这能忍受?Oh, I can't!
接下来,看看改造后的样子。

改造后的后台接口API请求的使用方式

改造后的请求方式非常简单,只需要使用一个工具类即可:DtHttpUtil, 新功能在dev_4_6_0分支后可用

  1. public void testDtHttpUtil() {
  2. DtRequestParams params = new DtRequestParams();
  3. params.add("key1", "value1");
  4. params.add("key2", "value2");
  5. DtHttpUtil.INSTANCE.edgeRequest("/router/path1", params, new DtRequestCallBack<DtBaseModel<MyData>>() {
  6. @Override
  7. public void onRequestSuccessful(DtBaseModel<MyData> response) {
  8. MyData myData = response.getData();
  9. //接下来去使用数据进行界面的渲染等工作了
  10. String data1 = myData.data1;
  11. }
  12. });
  13. }

用到的类都是现有的,除了要返回的MyData这个数据类,需要自己定义实现
定义实现如下:

  1. class MyData {
  2. public String data1;
  3. public String data2;
  4. public String data3;
  5. }
  1. {
  2. "ErrCode":0,
  3. "Reason":"",
  4. "Result":1,
  5. "data":{
  6. "data1":"111",
  7. "data2":"111",
  8. "data3":"111"
  9. }
  10. }

如有疑问请@seal.wu@dingtone.me

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注