網絡框架 Retrofit(三)

簡單實現Retrofit(替代Okhttp)

1.定義注解參數

@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Field {String value();
}
復制代碼
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface Get {String value() default "";
}
復制代碼
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface Post {String value() default "";
}
復制代碼

2.實現回調接口Call和Callback MyCall .class

public interface MyCall {//執行網絡請求(同步:在當前網絡)String execute() throws Exception;//在子線程請求網絡void enqueue(MyCallback callback);
}
復制代碼

MyCallback .class

/*** 網絡請求回調接口*/
public interface MyCallback {void onResponse( String response);void onFailure( Exception e);
}
復制代碼

SystemHttpCall .class

/*** Created by Xionghu on 2017/8/14.* Desc: 具體的實現類發送請求*/public class SystemHttpCall implements MyCall {private MyServiceMethod serviceMethod;public SystemHttpCall(MyServiceMethod serviceMethod) {this.serviceMethod = serviceMethod;}@Overridepublic String execute() throws Exception {if (serviceMethod.isPost()) {return HttpUtils.post(serviceMethod.baseUrl(), serviceMethod.getParam());} else {return HttpUtils.get(serviceMethod.baseUrl());}}@Overridepublic void enqueue(MyCallback callback) {HttpTask httpTask = new HttpTask(this, callback);httpTask.execute();}public class HttpTask extends AsyncTask<Void, Void, String> {private SystemHttpCall httpCall;private MyCallback callback;private HttpTask(SystemHttpCall httpCall, MyCallback callback) {this.httpCall = httpCall;this.callback = callback;}@Overrideprotected String doInBackground(Void... params) {try {return httpCall.execute();} catch (Exception e) {e.printStackTrace();}return null;}@Overrideprotected void onPostExecute(String result) {if (this.callback != null) {if (result != null) {this.callback.onResponse(result);} else {this.callback.onFailure(new Exception("網絡異常!"));}}}}
}
復制代碼

3.解析注解方法獲取相應參數

public class MyServiceMethod {private Builder builder;public MyServiceMethod(Builder builder) {this.builder = builder;}public boolean isPost() {return this.builder.isPost;}public Map<String, Object> getParam() {return this.builder.paramMap;}public String baseUrl() {StringBuffer buffer = new StringBuffer(this.builder.retrofit.getBaseUrl() + this.builder.relativeUrl);if (!isPost()) {// 如果你不是Post請求,是get請求,需要拼接參數地址if (this.builder.paramMap != null) {Set<String> keySet = this.builder.paramMap.keySet();if (keySet.size() > 0) {buffer.append("?");}for (String key : keySet) {Object value = this.builder.paramMap.get(key);buffer.append(key);buffer.append("=");buffer.append(value);buffer.append("&");}buffer.deleteCharAt(buffer.length() - 1);}}return buffer.toString();}static final class Builder {final MyRetrofit retrofit;final Method method;final Annotation[] methodAnnotations;final Annotation[][] parameterAnnotationsArray;String relativeUrl;// 參數集合Map<String, Object> paramMap;Object[] args;boolean isPost;public Builder(MyRetrofit retrofit, Method method, Object[] args) {this.retrofit = retrofit;this.method = method;// 方法注解列表(相當于我們的LoginService中的: @POST和@FormUrlEncoded......)this.methodAnnotations = method.getAnnotations();// 方法參數注解列表(相當于我們的LoginService中的: @Field......)this.parameterAnnotationsArray = method.getParameterAnnotations();this.args = args;this.paramMap = new HashMap<String, Object>();}public MyServiceMethod build() {// 循環遍歷方法注解列表for (Annotation annotation : methodAnnotations) {parseMethodAnnotation(annotation);}int parameterCount = parameterAnnotationsArray.length;for (int p = 0; p < parameterCount; p++) {Annotation[] parameterAnnotations = parameterAnnotationsArray[p];parseParameterAnnotation(p, parameterAnnotations);}return new MyServiceMethod(this);}/*** 解析方法注解** @param annotation*/public void parseMethodAnnotation(Annotation annotation) {// 首先判斷注解類型(解析目的:獲取接口名稱,用于拼接地址)if (annotation instanceof Get) {this.relativeUrl = ((Get) annotation).value();isPost = false;} else if (annotation instanceof Post) {this.relativeUrl = ((Post) annotation).value();isPost = true;}}/*** 解析參數注解** @param p* @param parameterAnnotations*/private void parseParameterAnnotation(int p,Annotation[] parameterAnnotations) {// 方法參數值Object value = args[p];// 遍歷方法參數注解for (Annotation annotation : parameterAnnotations) {// 首先需要判斷該注解的類型if (annotation instanceof Field) {Field field = (Field) annotation;// 參數的名稱(接口參數名稱,服務器接口規定的)String key = field.value();paramMap.put(key, value);}}}}
}
復制代碼

4.定義MyRetrofit框架

public class MyRetrofit {// 緩存方法(為了避免重復加載方法注解,從而耗費性能)private final Map<Method, MyServiceMethod> serviceMethodCache = new LinkedHashMap<Method, MyServiceMethod>();public String getBaseUrl() {return baseUrl;}public void setBaseUrl(String baseUrl) {this.baseUrl = baseUrl;}private String baseUrl;private MyRetrofit(String baseUrl){this.baseUrl = baseUrl;}public <T> T create(Class<T> service){//動態代理實現return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {MyServiceMethod serviceMethod = loadServiceMethod(method, args);SystemHttpCall httpCall = new SystemHttpCall(serviceMethod);return httpCall;}});}// 第一步:解析方法(說白了解析方法注解和方法參數注解)// 第二步:實現網絡請求protected MyServiceMethod loadServiceMethod(Method method, Object[] args) {MyServiceMethod result;synchronized (serviceMethodCache) {result = serviceMethodCache.get(method);if (result == null) {result = new MyServiceMethod.Builder(this, method, args).build();serviceMethodCache.put(method, result);}}return result;}public static final class Builder{private String baseUrl;public Builder baseUrl(String baseUrl){this.baseUrl = baseUrl;return this;}public MyRetrofit build(){if(baseUrl == null){throw new IllegalStateException("Base URL required.");}return new MyRetrofit(baseUrl);}}}
復制代碼

5.具體實現網絡請求類 定義接口方法類

public interface MyRetrofitLoginService {
@Post("user/login?platform=android&city_id=101&type=pwd&channel=baiduxi&version=3.2.0&os_version=6.0.1&device_id=866622020797175")MyCall login(@Field("mobile") String name, @Field("password") String pwd);
}
復制代碼

簡單封裝請求工具類

public class MyRetrofitTest {private static String URL_SERVER = "http://api.cloud.test.haocaisong.cn/v2.0/";public static void login(String name, String pwd, final SimpleSystemLogin.OnHttpResultListener onHttpResultListener) {MyRetrofit myRetrofit = new MyRetrofit.Builder().baseUrl(URL_SERVER).build();MyRetrofitLoginService loginService = myRetrofit.create(MyRetrofitLoginService.class);MyCall myCall = loginService.login(name,pwd);myCall.enqueue(new MyCallback() {@Overridepublic void onResponse(String response) {onHttpResultListener.onHttpResult(response);}@Overridepublic void onFailure(Exception e) {}});}
}
復制代碼

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/539612.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539612.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539612.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Tomcat提示“XDB 的服務器 localhost 要求用戶名和密碼”

在地址欄輸入http://localhost:8080/&#xff08;8080是TOMCAT的端口號)測試&#xff0c;系統提示“XDB 的服務器 localhost 要求用戶名和密碼”&#xff0c;并彈出輸入用戶、密碼的窗口&#xff0c;查看代碼沒問題&#xff0c;不解&#xff0c;上網上查資料&#xff0c;是因為…

java jqgrid json格式_jqGrid 數據之 Json

Json數據需要定義jsonReader來跟服務器端返回的數據做對應&#xff0c;其默認值&#xff1a; jsonReader : { root: "rows", page: "page", total: "total", records: "records", repeatitems: true, c…

django 中靜態文件項目加載問題

問題描述&#xff1a; django項目中創建了多個app后&#xff0c;每個app中都有對應的static靜態文件。整個項目運行時這些靜態文件的加載就是一個問題&#xff0c;因為整個項目我只參與了一部分&#xff0c;項目部署之類的并沒有參與。我寫的部分的js代碼遇到點問題&#xff0c…

Erlang/OTP設計原則(文檔翻譯)

http://erlang.org/doc/design_principles/des_princ.html 圖和代碼皆源自以上鏈接中Erlang官方文檔&#xff0c;翻譯時的版本為20.1。 這個設計原則&#xff0c;其實是說用戶在設計系統的時候應遵循的標準和規范。閱讀前我一直以為寫的是作者在設計 Erlang/OTP 框架時的一些原…

存儲過程的參數可以使用sql的函數

系統已做成存儲過程&#xff0c;調用方法如下&#xff1a; crh_entry(yyyymmdd,起始時間,結束時間); 示例1&#xff1a;進行2016年4月10日10時到12時的測試&#xff0c;應寫為&#xff1a; exec crh_entry(20160410,10,11); 示例2&#xff1a;進行2016年4月8日14時到15時的…

java如何實例化集合_如何在java中實例化一個Queue對象?

Queue是一個接口&#xff0c;這意味著你不能直接構造一個Queue 。最好的select是構造一個已經實現Queue接口的類&#xff0c;如下所示&#xff1a; AbstractQueue &#xff0c; ArrayBlockingQueue &#xff0c; ConcurrentLinkedQueue &#xff0c; DelayQueue &#xff0c; D…

leetcode 121 股票買賣問題系列

描述&#xff1a; 給一些列數字&#xff0c;表示每條股票的價格&#xff0c;如果可以買賣一次&#xff08;不能同一天買和賣&#xff09;&#xff0c;求最大利益&#xff08;即差最大&#xff09;。 其他三道問題是&#xff0c;如果能買賣無限次&#xff0c;買賣兩次&#xff0…

Mybatis-jar-lib

csdn的下載好像和我有仇&#xff0c;上傳資源不斷提示&#xff1a;請您先登錄 下載&#xff1a;http://pan.baidu.com/s/1pL2BAzT asm-3.3.1.jar cglib-2.2.2.jar commons-logging-1.1.1.jar mybatis-3.1.1.jar ----以上mybatis的--- log4j-1.2.16.jar ----以上log4j日志--…

java使用隊列實現棧思路_算法面試:隊列實現棧的方案

聲明&#xff1a;碼字不易&#xff0c;轉載請注明出處&#xff0c;歡迎文章下方討論交流。前言&#xff1a;Java數據結構與算法專題會不定時更新&#xff0c;歡迎各位讀者監督。本篇介紹的是如何用兩個隊列實現棧的問題。這道題作為上一篇文章算法面試&#xff1a;棧實現隊列的…

Uber如何使用go語言創建高效的查詢服務

在2015年初我們創建了一個微服務&#xff0c;它只做一件事&#xff08;也確實做得很好&#xff09;就是地理圍欄查詢。一年后它成了Uber高頻查詢&#xff08;QPS&#xff09;服務&#xff0c;本次要講的故事就是我們為什么創建這個服務&#xff0c;以及編程語言新秀Go如何幫我們…

centos7:塔建pure_ftpd虛擬用戶

2019獨角獸企業重金招聘Python工程師標準>>> 1.下載pure_ftpd&#xff0c;上傳服務器,目錄路徑:/usr/local/src/ 下載地址:https://pan.baidu.com/s/1kWe8FAn 2.安裝pure_ftpd cd /usr/local/srctar -xjf pure-ftpd-1.0.36.tar.bz2cd pure-ftpd-1.0.36./configure -…

java.lang.module_如何修復“java.lang.module.FindException:module java.se.ee not found”錯誤

我正在嘗試打包我的kivy應用程序(python3)&#xff0c;但是當我運行命令buildozer -v android debug時&#xff0c;看到這個錯誤# Cwd /home/javier/.buildozer/android/platform/android-sdkError occurred during initialization of boot layerjava.lang.module.FindExceptio…

寒武紀芯片——有自己的SDK,支持tf、caffe、MXNet

寒武紀芯片產品中心>智能處理器IP智能處理器IP MLU智能芯片 軟件開發環境 Cambricon-1A 高性能硬件架構及軟件支持兼容Caffe、Tensorflow、MXnet等主流AI開發平臺&#xff0c;已多次成功流片 國際上首個成功商用的深度學習處理器IP產品&#xff0c;可廣泛應用于計算機視覺、…

maven ssm框架 mysql_SSM框架(IDEA+Spring+SpringMVC+Maven+Mybatis+MySQL)

【實例簡介】SSM框架(IDEASpringSpringMVCMavenMybatisMySQL),搭建SSM框架&#xff0c;利用mybatis-plus插件自動生成數據庫相關代碼。【實例截圖】【核心代碼】0d399d99-f108-4aaa-9c81-35b505c86e8a└── SSMManager├── pom.xml├── sql│ └── test.sql└── src…

spring框架的引入

spring框架給程序開發帶來了春天&#xff0c;在很多項目里&#xff0c;可能不用struts&#xff0c;不用hibernate&#xff0c;但往往都有spring。 why&#xff1f; 因為每個項目都會涉及到對象的創建和對象之間的依賴。 一、傳統的MVC開發 mvc的項目框架結構&#xff1a;Enti…

Java編程作業體會_Java作業的幾點總結感想

本次博客主要是總結近幾次作業&#xff0c;交流一下自己的感受。本次作業主要是對近幾次Java課程的鞏固作業&#xff0c;第一次作業主要是一些基礎的題目&#xff0c;包括選擇循環等一些基本語句&#xff0c;其目的在于掌握java一些基本知識&#xff0c;感受出Java與其他語言有…

基于百度語音識別API的Python語音識別小程序

一、功能概述 實現語音為文字&#xff0c;可以擴展到多種場景進行工作&#xff0c;這里只實現其基本的語言接收及轉換功能。 在語言錄入時&#xff0c;根據語言內容的多少與停頓時間&#xff0c;自動截取音頻進行轉換。 工作示例&#xff1a; 二、軟件環境 操作系統&#xff1a…

spring專業術語了解

組件/框架設計 侵入式設計 引入了框架&#xff0c;對現有的類的結構有影響&#xff1b;即需要實現或繼承某些特定類。 例如&#xff1a;Struts框架 非侵入式設計 引入了框架&#xff0c;對現有的類結構沒有影響。 例如&#xff1a;Hibernate框架 / Spring框架 控制反轉: In…

java修改ldap用戶密碼_LDAP 用戶更改自己的密碼

LDAP中采用了ACL的權限控制。在/etc/openldap/slapd.conf文件中&#xff1a;## See slapd.conf(5) for details on configuration options.# This file should NOT be world readable.#include/etc/openldap/schema/corba.schemainclude/etc/openldap/schema/core.schemainclud…

Spring第三篇【Core模塊之對象依賴】

tags: Spring 前言 在Spring的第二篇中主要講解了Spring Core模塊的使用IOC容器創建對象的問題&#xff0c;Spring Core模塊主要是解決對象的創建和對象之間的依賴關系&#xff0c;因此本博文主要講解如何使用IOC容器來解決對象之間的依賴關系&#xff01; 回顧以前對象依賴 我…