├── README.md ├── libs ├── AsyncHttpHelp-1.0.jar ├── AsyncHttpHelp-2.0.jar ├── AsyncHttpHelp-2.1.jar └── AsyncHttpHelp-3.0.2.jar └── src └── main ├── .gitignore ├── asynchttphelp.iml ├── build.gradle ├── libs ├── okhttp-3.6.0.jar └── okio-1.11.0.jar ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── luoxudong │ └── app │ └── asynchttp │ └── ExampleInstrumentedTest.java ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── luoxudong │ │ └── app │ │ └── asynchttp │ │ ├── AsyncHttpClient.java │ │ ├── AsyncHttpConst.java │ │ ├── AsyncHttpTask.java │ │ ├── AsyncHttpUtil.java │ │ ├── ContentType.java │ │ ├── builder │ │ ├── DownloadFileBuilder.java │ │ ├── GetBuilder.java │ │ ├── PostBuilder.java │ │ ├── PostBytesBuilder.java │ │ ├── PostFormBuilder.java │ │ ├── PostJsonBuilder.java │ │ ├── RequestBuilder.java │ │ └── UploadFileBuilder.java │ │ ├── callable │ │ ├── DownloadRequestCallable.java │ │ ├── JsonRequestCallable.java │ │ ├── RequestCallable.java │ │ ├── StringRequestCallable.java │ │ └── UploadRequestCallable.java │ │ ├── cookie │ │ ├── ClearableCookieJar.java │ │ ├── PersistentCookieJar.java │ │ ├── cache │ │ │ ├── CookieCache.java │ │ │ ├── IdentifiableCookie.java │ │ │ └── SetCookieCache.java │ │ └── persistence │ │ │ ├── CookiePersistor.java │ │ │ ├── SerializableCookie.java │ │ │ └── SharedPrefsCookiePersistor.java │ │ ├── exception │ │ ├── AsyncHttpException.java │ │ └── AsyncHttpExceptionCode.java │ │ ├── handler │ │ ├── DownloadFileResponseHandler.java │ │ ├── JsonResponseHandler.java │ │ ├── ResponseHandler.java │ │ ├── StringResponseHandler.java │ │ └── UploadFileResponseHandler.java │ │ ├── https │ │ ├── MySslSocketFactory.java │ │ ├── MyTrustManager.java │ │ ├── SSLParams.java │ │ ├── UnSafeHostnameVerifier.java │ │ └── UnSafeTrustManager.java │ │ ├── interceptor │ │ ├── JsonRequestInterceptor.java │ │ ├── JsonResponseInterceptor.java │ │ └── UserAgentInterceptor.java │ │ ├── model │ │ └── FileWrapper.java │ │ ├── request │ │ ├── AsyncHttpRequest.java │ │ ├── DownloadFileRequest.java │ │ ├── GetRequest.java │ │ ├── PostBytesRequest.java │ │ ├── PostFormRequest.java │ │ ├── PostJsonRequest.java │ │ ├── PostRequest.java │ │ └── UploadFileRequest.java │ │ └── utils │ │ └── AsyncHttpLog.java └── res │ └── values │ └── strings.xml └── test └── java └── com └── luoxudong └── app └── asynchttp └── ExampleUnitTest.java /README.md: -------------------------------------------------------------------------------- 1 | # AsyncHttpHelp # 2 | 3 | 由于Android 6.0系统不在自带HttpClient,AsyncHttpHelp也跟着升级了,AsyncHttpHelp 3.0开始基于OkHttp封装,sdk已经集成OkHttp 3.4.1源码。 4 | 5 | ## 优点 ## 6 | 1. 功能齐全,提供常用的http网络访问接口。 7 | 2. 轻量级,无任何第三方库依赖,库大小为90K左右。 8 | 3. 定制化,自定义json解析库,支持请求参数,返回内容预处理。 9 | 4. 易用性,简单易用,只需几行代码即可完成请求,可随意设置cookie、http头部等信息。 10 | 11 | ## 功能 ## 12 | 1. 普通get请求 13 | 2. 普通post请求 14 | 3. Form表单提交数据 15 | 4. byte数组格式数据传输 16 | 5. json格式内容传输(json字符串自动转java对象,java对象自动转json字符串,支持自定义json解析库) 17 | 6. 普通文件上传/下载 18 | 7. 断点上传/下载 19 | 8. 自定义cookie、http头部信息等 20 | 9. 自定义https证书 21 | 10. 支持取消请求 22 | 11. 请求内容,返回内容预处理 23 | 12. 设置请求结果是否在UI线程执行 24 | 13. 更多。。。 25 | 26 | ## 使用说明 ## 27 | 28 | > Get请求 29 | 30 | long id = AsyncHttpUtil.get() 31 | .url(url) 32 | .addHeaderParams(heads) 33 | .addCookie("sign", String.valueOf(System.currentTimeMillis())) 34 | .userAgent(userAgent) 35 | .tag("tag") 36 | .mainThread(true) 37 | .build().request(new StringRequestCallable() { 38 | 39 | @Override 40 | public void onFailed(int errorCode, String errorMsg) { 41 | Toast.makeText(GetRequestActivity.this, getId() + "请求失败" + errorMsg, Toast.LENGTH_SHORT).show(); 42 | } 43 | 44 | @Override 45 | public void onSuccess(String responseInfo) { 46 | Toast.makeText(GetRequestActivity.this, getId() + "请求成功" + responseInfo, Toast.LENGTH_SHORT).show();; 47 | } 48 | }); 49 | 50 | > Post请求 51 | 52 | long id = AsyncHttpUtil.post() 53 | .url(url) 54 | .addHeaderParams(heads) 55 | .addCookie("sign", String.valueOf(System.currentTimeMillis())) 56 | .userAgent(userAgent) 57 | .body("body内容") 58 | .tag("tag") 59 | .mainThread(true) 60 | .build().request(new StringRequestCallable() { 61 | 62 | @Override 63 | public void onFailed(int errorCode, String errorMsg) { 64 | Toast.makeText(GetRequestActivity.this, getId() + "请求失败" + errorMsg, Toast.LENGTH_SHORT).show(); 65 | } 66 | 67 | @Override 68 | public void onSuccess(String responseInfo) { 69 | Toast.makeText(GetRequestActivity.this, getId() + "请求成功" + responseInfo, Toast.LENGTH_SHORT).show();; 70 | } 71 | }); 72 | 73 | > Post表单 74 | 75 | long id = AsyncHttpUtil.postForm() 76 | .url(url) 77 | .addHeaderParams(heads) 78 | .addCookie("sign", String.valueOf(System.currentTimeMillis())) 79 | .userAgent(userAgent) 80 | .addFormParam("key1", "value1") 81 | .addFormParam("key2", "value2") 82 | .tag("tag") 83 | .mainThread(true) 84 | .build().request(new StringRequestCallable() { 85 | 86 | @Override 87 | public void onFailed(int errorCode, String errorMsg) { 88 | Toast.makeText(GetRequestActivity.this, getId() + "请求失败" + errorMsg, Toast.LENGTH_SHORT).show(); 89 | } 90 | 91 | @Override 92 | public void onSuccess(String responseInfo) { 93 | Toast.makeText(GetRequestActivity.this, getId() + "请求成功" + responseInfo, Toast.LENGTH_SHORT).show();; 94 | } 95 | }); 96 | 97 | > Post字节数组 98 | 99 | long id = AsyncHttpUtil.postBytes() 100 | .url(url) 101 | .addHeaderParams(heads) 102 | .addCookie("sign", String.valueOf(System.currentTimeMillis())) 103 | .userAgent(userAgent) 104 | .buffer(new byte[]{1,2,3,4,5}) 105 | .tag("tag") 106 | .mainThread(true) 107 | .build().request(new RequestCallable() { 108 | 109 | @Override 110 | public void onFailed(int errorCode, String errorMsg) { 111 | Toast.makeText(GetRequestActivity.this, getId() + "请求失败" + errorMsg, Toast.LENGTH_SHORT).show(); 112 | } 113 | 114 | @Override 115 | public void onSuccess(byte[] buffer) { 116 | Toast.makeText(GetRequestActivity.this, getId() + "请求成功" + buffer, Toast.LENGTH_SHORT).show();; 117 | } 118 | }); 119 | 120 | 121 | 正在整理中。。。 122 | 123 | **如有疑问可联系作者:hi@luoxudong.com或者rohsuton@gmail.com** -------------------------------------------------------------------------------- /libs/AsyncHttpHelp-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohsuton/AsyncHttpHelp/0940a118ec7beb5a627f2d804b46f4e1e535b0f9/libs/AsyncHttpHelp-1.0.jar -------------------------------------------------------------------------------- /libs/AsyncHttpHelp-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohsuton/AsyncHttpHelp/0940a118ec7beb5a627f2d804b46f4e1e535b0f9/libs/AsyncHttpHelp-2.0.jar -------------------------------------------------------------------------------- /libs/AsyncHttpHelp-2.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohsuton/AsyncHttpHelp/0940a118ec7beb5a627f2d804b46f4e1e535b0f9/libs/AsyncHttpHelp-2.1.jar -------------------------------------------------------------------------------- /libs/AsyncHttpHelp-3.0.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohsuton/AsyncHttpHelp/0940a118ec7beb5a627f2d804b46f4e1e535b0f9/libs/AsyncHttpHelp-3.0.2.jar -------------------------------------------------------------------------------- /src/main/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /src/main/asynchttphelp.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /src/main/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | minSdkVersion 14 9 | targetSdkVersion 22 10 | versionCode 1 11 | versionName "1.0" 12 | 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | compile fileTree(dir: 'libs', include: ['*.jar']) 26 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 27 | exclude group: 'com.android.support', module: 'support-annotations' 28 | }) 29 | //compile 'com.android.support:appcompat-v7:22.0.1' 30 | testCompile 'junit:junit:4.12' 31 | } 32 | 33 | //Copy类型 34 | task AsyncHttpHelpJar(type: proguard.gradle.ProGuardTask, dependsOn: "build") { 35 | //删除存在的 36 | delete 'build/libs/AsyncHttpHelp.jar' 37 | // 未混淆的jar 38 | injars 'build/intermediates/bundles/release/classes.jar' 39 | // 混淆后的jar路径 40 | outjars 'build/libs/AsyncHttpHelp.jar' 41 | // 混淆 42 | configuration 'proguard-rules.pro' 43 | } 44 | 45 | //AsyncHttpHelpJar.dependsOn(build) 46 | //在终端执行生成JAR包 47 | // gradlew AsyncHttpHelpJar -------------------------------------------------------------------------------- /src/main/libs/okhttp-3.6.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohsuton/AsyncHttpHelp/0940a118ec7beb5a627f2d804b46f4e1e535b0f9/src/main/libs/okhttp-3.6.0.jar -------------------------------------------------------------------------------- /src/main/libs/okio-1.11.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohsuton/AsyncHttpHelp/0940a118ec7beb5a627f2d804b46f4e1e535b0f9/src/main/libs/okio-1.11.0.jar -------------------------------------------------------------------------------- /src/main/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in E:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | 20 | -dontshrink #不压缩输入的类文件 21 | -dontoptimize #优化log不能有这个配置 22 | -optimizationpasses 5 23 | -dontusemixedcaseclassnames #混淆时不会产生形形色色的类名 24 | -dontskipnonpubliclibraryclasses #指定不去忽略非公共的库类 25 | -dontpreverify 26 | -verbose 27 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 28 | 29 | -keepattributes Exceptions, Signature, InnerClasses 30 | -keepattributes *Annotation* 31 | -keepattributes SourceFile,LineNumberTable 32 | 33 | -dontwarn okhttp3.** 34 | -dontwarn okio.** 35 | 36 | -keepclassmembers enum * { 37 | public static **[] values(); 38 | public static ** valueOf(java.lang.String); 39 | } 40 | 41 | -keepclassmembers class * implements java.io.Serializable { 42 | static final long serialVersionUID; 43 | private static final java.io.ObjectStreamField[] serialPersistentFields; 44 | private void writeObject(java.io.ObjectOutputStream); 45 | private void readObject(java.io.ObjectInputStream); 46 | java.lang.Object writeReplace(); 47 | java.lang.Object readResolve(); 48 | } 49 | 50 | -keepclasseswithmembers class * { 51 | public (android.content.Context); 52 | } 53 | 54 | -keep public class com.luoxudong.app.asynchttp.builder.** { 55 | *; 56 | } 57 | 58 | -keep public class com.luoxudong.app.asynchttp.callable.** { 59 | *; 60 | } 61 | 62 | -keep public class com.luoxudong.app.asynchttp.interceptor.** { 63 | *; 64 | } 65 | 66 | -keep public class com.luoxudong.app.asynchttp.model.** { 67 | *; 68 | } 69 | 70 | -keep public class com.luoxudong.app.asynchttp.AsyncHttpUtil { 71 | *; 72 | } 73 | 74 | -keep public class com.luoxudong.app.asynchttp.ContentType { 75 | *; 76 | } 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/main/src/androidTest/java/com/luoxudong/app/asynchttp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.luoxudong.app.asynchttp; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.luoxudong.app.asynchttp.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/AsyncHttpClient.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: AsyncHttpClient.java 3 | * Description: AsyncHttpClient类 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午3:49:02 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp; 11 | 12 | import android.text.TextUtils; 13 | 14 | import com.luoxudong.app.asynchttp.cookie.PersistentCookieJar; 15 | import com.luoxudong.app.asynchttp.cookie.cache.SetCookieCache; 16 | import com.luoxudong.app.asynchttp.https.MySslSocketFactory; 17 | import com.luoxudong.app.asynchttp.https.SSLParams; 18 | import com.luoxudong.app.asynchttp.https.UnSafeHostnameVerifier; 19 | import com.luoxudong.app.asynchttp.interceptor.UserAgentInterceptor; 20 | 21 | import java.io.InputStream; 22 | import java.io.UnsupportedEncodingException; 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import java.util.concurrent.TimeUnit; 26 | 27 | import javax.net.ssl.SSLSocketFactory; 28 | import javax.net.ssl.X509TrustManager; 29 | 30 | import okhttp3.CookieJar; 31 | import okhttp3.OkHttpClient; 32 | 33 | /** 34 | * ClassName: AsyncHttpClient 35 | * Description:AsyncHttpClient类 36 | * Create by: 罗旭东 37 | * Date: 2015年7月13日 下午3:49:02 38 | */ 39 | public class AsyncHttpClient { 40 | private static final String TAG = AsyncHttpClient.class.getSimpleName(); 41 | /** mOkHttpClient对象 */ 42 | private OkHttpClient mOkHttpClient = null; 43 | /** 全局mSslSocketFactory */ 44 | private SSLSocketFactory mSslSocketFactory = null; 45 | /** 全局mTrustManager */ 46 | private X509TrustManager mTrustManager = null; 47 | /** 全局cookie */ 48 | private CookieJar mCookieJar = null; 49 | /** 全局userAgent */ 50 | private String mUserAgent = null; 51 | 52 | public AsyncHttpClient() { 53 | //SSLParams sslParams = new MySslSocketFactory().getSslSocketFactory(null, null, null); 54 | mOkHttpClient = new OkHttpClient.Builder() 55 | .connectTimeout(AsyncHttpConst.DEFAULT_CONNECT_TIMEOUT, TimeUnit.MILLISECONDS) 56 | .readTimeout(AsyncHttpConst.DEFAULT_SO_TIMEOUT, TimeUnit.MILLISECONDS) 57 | .writeTimeout(AsyncHttpConst.DEFAULT_SO_TIMEOUT, TimeUnit.MILLISECONDS) 58 | .addInterceptor(new UserAgentInterceptor()) 59 | .cookieJar(new PersistentCookieJar(new SetCookieCache(), null)) 60 | //.sslSocketFactory(sslParams.getSSLSocketFactory(), sslParams.getTrustManager()) 61 | //.hostnameVerifier(new UnSafeHostnameVerifier()) 62 | .build(); 63 | } 64 | 65 | public AsyncHttpClient sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager) { 66 | mSslSocketFactory = sslSocketFactory; 67 | mTrustManager = trustManager; 68 | return this; 69 | } 70 | 71 | public void setSslSocketFactory(String[] cerDatas) { 72 | try { 73 | List cerList = new ArrayList(); 74 | InputStream[] cerStreams = null; 75 | if (cerDatas != null && cerDatas.length > 0) { 76 | for (String cer : cerDatas) { 77 | InputStream is = new java.io.ByteArrayInputStream(cer.getBytes("UTF-8")); 78 | cerList.add(is); 79 | } 80 | cerStreams = cerList.toArray(new InputStream[cerList.size()]); 81 | } 82 | setSslSocketFactory(cerStreams); 83 | } catch (UnsupportedEncodingException e) { 84 | 85 | } 86 | } 87 | public void setSslSocketFactory(InputStream[] cerStreams) { 88 | SSLParams sslParams = new MySslSocketFactory().getSslSocketFactory(cerStreams, null, null); 89 | sslSocketFactory(sslParams.getSSLSocketFactory(), sslParams.getTrustManager()).build(); 90 | } 91 | 92 | public AsyncHttpClient cookieJar(CookieJar cookieJar) { 93 | mCookieJar = cookieJar; 94 | return this; 95 | } 96 | 97 | public AsyncHttpClient userAgent(String userAgent) { 98 | mUserAgent = userAgent; 99 | return this; 100 | } 101 | 102 | public void build() { 103 | OkHttpClient.Builder builder = getOkHttpClient().newBuilder(); 104 | 105 | if (mSslSocketFactory != null && mTrustManager != null) { 106 | builder.sslSocketFactory(mSslSocketFactory, mTrustManager); 107 | } 108 | 109 | builder.hostnameVerifier(new UnSafeHostnameVerifier()); 110 | 111 | if (mCookieJar != null) { 112 | builder.cookieJar(mCookieJar); 113 | } 114 | 115 | if (!TextUtils.isEmpty(mUserAgent)) { 116 | builder.addInterceptor(new UserAgentInterceptor(mUserAgent)); 117 | } 118 | mOkHttpClient = builder.build(); 119 | } 120 | 121 | public OkHttpClient getOkHttpClient() { 122 | return mOkHttpClient; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/AsyncHttpConst.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: AsyncHttpConst.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午3:49:49 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp; 11 | 12 | import android.os.Build; 13 | 14 | /** 15 | * ClassName: AsyncHttpConst 16 | * Description:http常量信息 17 | * Create by: 罗旭东 18 | * Date: 2015年7月13日 下午3:49:49 19 | */ 20 | public class AsyncHttpConst { 21 | public static final String TAG_LOG = "AsyncHttpHelp"; 22 | public static final int MAX_CONNECTIONS = 50;//创建socket上线 23 | public static final int MAX_PER_ROUTE = 30;//最大并发连接数 24 | public static final int DEFAULT_SO_TIMEOUT = 30 * 1000;//读数据超时时间 25 | public static final int DEFAULT_CONNECT_TIMEOUT = 30 * 1000;//连接超时时间 26 | public static final int DEFAULT_MAX_RETRIES = 0;//请求失败时重复请求次数 27 | public static final int DEFAULT_SOCKET_BUFFER_SIZE = 8192; 28 | public static final String HEADER_CONTENT_TYPE_JSON = "application/json"; 29 | public static final String HEADER_CONTENT_TYPE_TEXT = "text/plain"; 30 | public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding"; 31 | public static final String ENCODING_GZIP = "gzip"; 32 | public static final String HEADER_RANGE = "range"; 33 | public static final String HTTP_ENCODING = "UTF-8"; 34 | public static final String HEADER_COOKIE = "Cookie"; 35 | public static final String HEADER_USER_AGENT = "User-Agent"; 36 | public static final long TRANSFER_MAX_SIZE = 1024 * 1024 * 1024; 37 | public static long TRANSFER_REFRESH_TIME_INTERVAL = 1000;//传输刷新时间间隔(毫秒) 38 | public static String sUserAgent = "Mozilla/5.0 (Linux; Android " + Build.VERSION.RELEASE + "; " + Build.MODEL + " Build/KTU84P) AppleWebKit/537.36 hi@luoxudong.com"; 39 | } 40 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/AsyncHttpTask.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: AsyncHttpTask.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午5:01:39 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp; 11 | 12 | import android.text.TextUtils; 13 | 14 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 15 | import com.luoxudong.app.asynchttp.exception.AsyncHttpException; 16 | import com.luoxudong.app.asynchttp.exception.AsyncHttpExceptionCode; 17 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 18 | import com.luoxudong.app.asynchttp.interceptor.UserAgentInterceptor; 19 | import com.luoxudong.app.asynchttp.request.AsyncHttpRequest; 20 | 21 | import java.io.IOException; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | import java.util.Map; 25 | import java.util.concurrent.ExecutorService; 26 | import java.util.concurrent.Executors; 27 | import java.util.concurrent.TimeUnit; 28 | 29 | import javax.net.ssl.SSLHandshakeException; 30 | 31 | import okhttp3.Call; 32 | import okhttp3.Callback; 33 | import okhttp3.Cookie; 34 | import okhttp3.CookieJar; 35 | import okhttp3.OkHttpClient; 36 | import okhttp3.OkHttpClient.Builder; 37 | import okhttp3.Request; 38 | import okhttp3.Response; 39 | 40 | /** 41 | * ClassName: AsyncHttpTask 42 | * Description:发送http请求 43 | * Create by: 罗旭东 44 | * Date: 2015年7月13日 下午5:01:39 45 | */ 46 | public class AsyncHttpTask { 47 | private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool(); 48 | /** 请求 */ 49 | private AsyncHttpRequest mHttpRequest = null; 50 | 51 | /** 返回结果处理类 */ 52 | private ResponseHandler mResponseHandler = null; 53 | 54 | /** 回调 */ 55 | private Call mCall = null; 56 | 57 | /** 请求 */ 58 | private Request mRequest = null; 59 | 60 | public AsyncHttpTask(AsyncHttpRequest request) { 61 | mHttpRequest = request; 62 | } 63 | 64 | /** 65 | * 异步请求 66 | * @param callable 67 | */ 68 | public long request(final RequestCallable callable) { 69 | initCallable(callable); 70 | EXECUTOR_SERVICE.execute(new Runnable() { 71 | @Override 72 | public void run() { 73 | try { 74 | mResponseHandler.sendStartMessage();//开始 75 | Response response = mCall.execute(); 76 | mResponseHandler.sendFinishMessage();//结束 77 | //请求数据成功 78 | mResponseHandler.onResponseSucess(response); 79 | } catch (IOException e) { 80 | mResponseHandler.sendFinishMessage();//结束 81 | if (e instanceof SSLHandshakeException) { 82 | mResponseHandler.sendFailureMessage(AsyncHttpExceptionCode.sslException.getErrorCode(), e); 83 | } else { 84 | mResponseHandler.sendFailureMessage(AsyncHttpExceptionCode.httpResponseException.getErrorCode(), e); 85 | } 86 | } 87 | 88 | } 89 | }); 90 | 91 | 92 | /*try { 93 | initCallable(callable); 94 | mResponseHandler.sendStartMessage();//开始 95 | mCall.enqueue(new Callback() { 96 | @Override 97 | public void onResponse(Call call, Response response) throws IOException { 98 | if (call.isCanceled()) { 99 | mResponseHandler.sendCancelMessage(); 100 | return; 101 | } 102 | 103 | //请求数据成功 104 | mResponseHandler.onResponseSucess(response); 105 | } 106 | 107 | @Override 108 | public void onFailure(Call call, IOException e) { 109 | if (e instanceof SSLHandshakeException) { 110 | mResponseHandler.sendFailureMessage(AsyncHttpExceptionCode.sslException.getErrorCode(), e); 111 | } else { 112 | mResponseHandler.sendFailureMessage(AsyncHttpExceptionCode.httpResponseException.getErrorCode(), e); 113 | } 114 | } 115 | }); 116 | } catch (AsyncHttpException e){ 117 | mResponseHandler.sendFailureMessage(e.getExceptionCode(), e); 118 | }*/ 119 | 120 | return mHttpRequest.getId(); 121 | } 122 | 123 | /** 124 | * 同步请求 125 | * @return 126 | */ 127 | public Response request() throws IOException { 128 | Response response = null; 129 | initCallable(null); 130 | 131 | mResponseHandler.sendStartMessage();//开始 132 | response = mCall.execute(); 133 | mResponseHandler.sendFinishMessage();//结束 134 | return response; 135 | } 136 | 137 | /** 138 | * 构建回调 139 | * @param callable 140 | * @return 141 | */ 142 | private Call initCallable(RequestCallable callable) throws AsyncHttpException { 143 | mResponseHandler = mHttpRequest.buildResponseHandler(callable); 144 | 145 | if (mHttpRequest.getAsyncHttpException() != null) { 146 | throw mHttpRequest.getAsyncHttpException(); 147 | } 148 | 149 | mRequest = mHttpRequest.buildRequest(callable); 150 | mResponseHandler.setMainThread(mHttpRequest.isMainThread()); 151 | 152 | //重设httpclient配置 153 | OkHttpClient okHttpClient = null; 154 | if (mHttpRequest.getAsyncHttpClient() == null) {//如果没有配置http实例则使用默认的 155 | okHttpClient = AsyncHttpUtil.getHttpClient().getOkHttpClient(); 156 | } else { 157 | okHttpClient = mHttpRequest.getAsyncHttpClient().getOkHttpClient(); 158 | } 159 | 160 | if (callable != null) { 161 | callable.setId(mHttpRequest.getId()); 162 | } 163 | 164 | int connTimeout = mHttpRequest.getConnectTimeout(); 165 | int readTimeout = mHttpRequest.getReadTimeout(); 166 | int writeTimeout = mHttpRequest.getWriteTimeout(); 167 | String userAgent = mHttpRequest.getUserAgent(); 168 | Map cookies = mHttpRequest.getCookies(); 169 | 170 | if (connTimeout > 0 || readTimeout > 0 || writeTimeout > 0 || !TextUtils.isEmpty(userAgent) || cookies != null) { 171 | //重新配置 172 | Builder builder = okHttpClient.newBuilder(); 173 | 174 | if (connTimeout > 0) { 175 | builder = builder.connectTimeout(connTimeout, TimeUnit.MILLISECONDS); 176 | } 177 | 178 | if (readTimeout > 0) { 179 | builder = builder.readTimeout(readTimeout, TimeUnit.MILLISECONDS); 180 | } 181 | 182 | if (writeTimeout > 0) { 183 | builder = builder.writeTimeout(writeTimeout, TimeUnit.MILLISECONDS); 184 | } 185 | 186 | if (!TextUtils.isEmpty(userAgent)) { 187 | builder = builder.addInterceptor(new UserAgentInterceptor(userAgent)); 188 | } 189 | 190 | okHttpClient = builder.build(); 191 | CookieJar cookieJar = okHttpClient.cookieJar(); 192 | 193 | //自定义cookie 194 | if (cookies != null) { 195 | List cookieList = new ArrayList(); 196 | for (String key : cookies.keySet()) { 197 | cookieList.add(Cookie.parse(mRequest.url(), key + "=" + cookies.get(key))); 198 | } 199 | 200 | cookieJar.saveFromResponse(mRequest.url(), cookieList); 201 | } 202 | } 203 | 204 | mCall = okHttpClient.newCall(mRequest); 205 | return mCall; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/AsyncHttpUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: AsyncHttpUtil.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年10月13日 下午2:57:44 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp; 11 | 12 | import com.luoxudong.app.asynchttp.builder.DownloadFileBuilder; 13 | import com.luoxudong.app.asynchttp.builder.GetBuilder; 14 | import com.luoxudong.app.asynchttp.builder.PostBuilder; 15 | import com.luoxudong.app.asynchttp.builder.PostBytesBuilder; 16 | import com.luoxudong.app.asynchttp.builder.PostFormBuilder; 17 | import com.luoxudong.app.asynchttp.builder.PostJsonBuilder; 18 | import com.luoxudong.app.asynchttp.builder.UploadFileBuilder; 19 | import com.luoxudong.app.asynchttp.https.MySslSocketFactory; 20 | import com.luoxudong.app.asynchttp.https.SSLParams; 21 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 22 | 23 | import java.io.InputStream; 24 | import java.io.UnsupportedEncodingException; 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | 28 | import okhttp3.Call; 29 | 30 | /** 31 | *
 32 |  * ClassName: AsyncHttpUtil
 33 |  * Description:http请求工具类
 34 |  * Create by: 罗旭东
 35 |  * Date: 2016年10月13日 下午2:57:44
 36 |  * 
37 | */ 38 | public class AsyncHttpUtil { 39 | /** 全局使用同一个AsyncHttpClient对象 */ 40 | private static AsyncHttpClient mHttpClient = new AsyncHttpClient(); 41 | 42 | public static long sStartTime = System.nanoTime(); 43 | 44 | /** 45 | * 普通get请求 46 | * @return 47 | */ 48 | public static GetBuilder get() { 49 | return new GetBuilder(); 50 | } 51 | 52 | /** 53 | * 普通post请求 54 | * @return 55 | */ 56 | public static PostBuilder post() { 57 | return new PostBuilder(); 58 | } 59 | 60 | /** 61 | * form表单形式的提交请求 62 | * @return 63 | */ 64 | public static PostFormBuilder postForm() { 65 | return new PostFormBuilder(); 66 | } 67 | 68 | /** 69 | * 已json对象的方式的请求 70 | * @return 71 | */ 72 | public static PostJsonBuilder postJson() { 73 | return new PostJsonBuilder(); 74 | } 75 | 76 | /** 77 | * 数据内容为byte数组的请求 78 | * @return 79 | */ 80 | public static PostBytesBuilder postBytes() { 81 | return new PostBytesBuilder(); 82 | } 83 | 84 | /** 85 | * 文件上传 86 | * @return 87 | */ 88 | public static UploadFileBuilder uploadFile() { 89 | return new UploadFileBuilder(); 90 | } 91 | 92 | /** 93 | * 文件下载 94 | * @return 95 | */ 96 | public static DownloadFileBuilder downloadFile() { 97 | return new DownloadFileBuilder(); 98 | } 99 | 100 | /** 101 | * 显示日志 102 | */ 103 | public static void enableLog() { 104 | AsyncHttpLog.enableLog(); 105 | } 106 | 107 | /** 108 | * 创建一个新的http客户端 109 | * @return 110 | */ 111 | public static AsyncHttpClient newAsyncHttpClient() { 112 | return new AsyncHttpClient(); 113 | } 114 | 115 | /** 116 | * 增加证书 117 | * @param cerDatas 证书字符串 118 | */ 119 | public static void setSslSocketFactory(String[] cerDatas) { 120 | setSslSocketFactory(getHttpClient(), cerDatas); 121 | } 122 | 123 | public static void setSslSocketFactory(AsyncHttpClient asyncHttpClients, String[] cerDatas) { 124 | if (asyncHttpClients == null) { 125 | return; 126 | } 127 | asyncHttpClients.setSslSocketFactory(cerDatas); 128 | } 129 | 130 | /** 131 | * 增加证书 132 | * @param cerStreams 证书数据流 133 | */ 134 | public static void setSslSocketFactory(InputStream[] cerStreams) { 135 | setSslSocketFactory(getHttpClient(), cerStreams); 136 | } 137 | 138 | public static void setSslSocketFactory(AsyncHttpClient asyncHttpClients,InputStream[] cerStreams) { 139 | if (asyncHttpClients == null) { 140 | return; 141 | } 142 | 143 | asyncHttpClients.setSslSocketFactory(cerStreams); 144 | } 145 | 146 | /** 147 | * 信任所有证书,不安全 148 | */ 149 | public static void setNoSafeSslSocketFactory() { 150 | setSslSocketFactory((String[])null); 151 | } 152 | 153 | public static void setNoSafeSslSocketFactory(AsyncHttpClient asyncHttpClients) { 154 | if (asyncHttpClients == null) { 155 | return; 156 | } 157 | 158 | setSslSocketFactory(asyncHttpClients, (String[])null); 159 | } 160 | 161 | /** 162 | * 设置UA 163 | * @param userAgent 164 | */ 165 | public static void setUserAgent(String userAgent) { 166 | setUserAgent(getHttpClient(), userAgent); 167 | } 168 | 169 | public static void setUserAgent(AsyncHttpClient asyncHttpClients,String userAgent) { 170 | if (asyncHttpClients == null) { 171 | return; 172 | } 173 | 174 | asyncHttpClients.userAgent(userAgent).build(); 175 | } 176 | 177 | /** 178 | * 隐藏日志 179 | */ 180 | public static void disableLog() { 181 | AsyncHttpLog.disableLog(); 182 | } 183 | 184 | /** 185 | * 根据tag中断请求 186 | * @param tag 187 | */ 188 | public static void cancelTag(String tag) { 189 | AsyncHttpClient asyncHttpClient = getHttpClient(); 190 | for (Call call : asyncHttpClient.getOkHttpClient().dispatcher().queuedCalls()) { 191 | if (tag.equals(call.request().tag())) { 192 | call.cancel(); 193 | } 194 | } 195 | 196 | for (Call call : asyncHttpClient.getOkHttpClient().dispatcher().runningCalls()) { 197 | if (tag.equals(call.request().tag())) { 198 | call.cancel(); 199 | } 200 | } 201 | } 202 | 203 | /** 204 | * 中断所有请求 205 | */ 206 | public static void cancelAll() { 207 | AsyncHttpClient asyncHttpClient = getHttpClient(); 208 | for (Call call : asyncHttpClient.getOkHttpClient().dispatcher().queuedCalls()) { 209 | call.cancel(); 210 | } 211 | 212 | for (Call call : asyncHttpClient.getOkHttpClient().dispatcher().runningCalls()) { 213 | call.cancel(); 214 | } 215 | } 216 | 217 | private AsyncHttpUtil(AsyncHttpClient httpClient) { 218 | if (httpClient == null) { 219 | mHttpClient = new AsyncHttpClient(); 220 | } else { 221 | mHttpClient = httpClient; 222 | } 223 | } 224 | 225 | /** 226 | * 获取HttpClient 227 | * @return 228 | */ 229 | public static AsyncHttpClient getHttpClient() { 230 | if (mHttpClient == null) { 231 | synchronized (AsyncHttpUtil.class) { 232 | if (mHttpClient == null) { 233 | mHttpClient = new AsyncHttpClient(); 234 | } 235 | } 236 | } 237 | 238 | return mHttpClient; 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/ContentType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: ContentType.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年11月22日 下午3:48:48 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp; 11 | 12 | /** 13 | *
14 |  * ClassName: ContentType
15 |  * Description:请求内容枚举类型
16 |  * Create by: 罗旭东
17 |  * Date: 2016年11月22日 下午3:48:48
18 |  * 
19 | */ 20 | public enum ContentType { 21 | text("text/plain;charset=utf-8"), 22 | html("text/html;charset=utf-8"), 23 | octetStream("application/octet-stream"); 24 | 25 | private String value = null; 26 | 27 | ContentType(String value) { 28 | this.value = value; 29 | } 30 | 31 | public String getValue() { 32 | return value; 33 | } 34 | 35 | public void setValue(String value) { 36 | this.value = value; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/builder/DownloadFileBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: DownloadFileBuilder.java 3 | * Description: 下载文件的构建类 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年12月29日 上午10:58:18 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.builder; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.request.DownloadFileRequest; 14 | import com.luoxudong.app.asynchttp.request.PostBytesRequest; 15 | 16 | /** 17 | *
18 |  * ClassName: DownloadFileBuilder
19 |  * Description:下载文件的构建类,支持文件断点下载
20 |  * Create by: 罗旭东
21 |  * Date: 2016年12月29日 上午10:58:18
22 |  * 
23 | */ 24 | public class DownloadFileBuilder extends RequestBuilder { 25 | /** 断点下载起始位置 */ 26 | private long mOffset = 0; 27 | /** 下载文件大小 */ 28 | private long mLength = 0; 29 | /** 下载文件保存路径 */ 30 | private String mFileDir = null; 31 | /** 下载文件名 */ 32 | private String mFileName = null; 33 | 34 | @Override 35 | public AsyncHttpTask build() { 36 | DownloadFileRequest request = new DownloadFileRequest(this); 37 | request.setFileDir(mFileDir); 38 | request.setFileName(mFileName); 39 | request.setLength(mLength); 40 | request.setOffset(mOffset); 41 | 42 | initRequest(request);//初始化request 43 | return request.build(); 44 | } 45 | 46 | /** 47 | * 设置下载起始位置,默认从文件开始位置下载 48 | * @param offset 起始位置 49 | * @return 50 | */ 51 | public DownloadFileBuilder offset(long offset) { 52 | mOffset = offset; 53 | return this; 54 | } 55 | 56 | /** 57 | * 设置本次下载数据大小,默认下载整个文件 58 | * @param length 下载数据大小 59 | * @return 60 | */ 61 | public DownloadFileBuilder length(long length) { 62 | mLength = length; 63 | return this; 64 | } 65 | 66 | /** 67 | * 设置下载文件保存的目录 68 | * @param fileDir 下载文件保存的目录 69 | * @return 70 | */ 71 | public DownloadFileBuilder fileDir(String fileDir) { 72 | mFileDir = fileDir; 73 | return this; 74 | } 75 | 76 | /** 77 | * 设置下载文件本地名称 78 | * @param fileName 文件名 79 | * @return 80 | */ 81 | public DownloadFileBuilder fileName(String fileName) { 82 | mFileName = fileName; 83 | return this; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/builder/GetBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: GetBuilder.java 3 | * Description: get请求Builder 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年10月13日 下午2:54:16 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.builder; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 14 | import com.luoxudong.app.asynchttp.request.GetRequest; 15 | 16 | /** 17 | *
18 |  * ClassName: GetBuilder
19 |  * Description:get请求Builder,支持返回内容为json对象
20 |  * Create by: 罗旭东
21 |  * Date: 2016年10月13日 下午2:54:16
22 |  * 
23 | */ 24 | public class GetBuilder extends RequestBuilder { 25 | /** 返回数据拦截器 */ 26 | private JsonResponseInterceptor mResponseInterceptor = null; 27 | /** 返回的json对象类型 */ 28 | private Class mResponseClazz = null; 29 | 30 | @Override 31 | public AsyncHttpTask build() { 32 | GetRequest request = new GetRequest(this); 33 | request.setResponseClazz(mResponseClazz); 34 | request.setResponseInterceptor(mResponseInterceptor); 35 | 36 | initRequest(request);//初始化request 37 | return request.build(); 38 | } 39 | 40 | /** 41 | * 设置返回json数据拦截器,拦截返回数据预处理,可以设置自定义json解析库 42 | * @param responseInterceptor 返回结果拦截器 43 | * @return 44 | */ 45 | public GetBuilder responseInterceptor(JsonResponseInterceptor responseInterceptor) { 46 | mResponseInterceptor = responseInterceptor; 47 | return this; 48 | } 49 | 50 | /** 51 | * 设置返回json的java类型 52 | * @param responseClazz 类型 53 | * @return 54 | */ 55 | public GetBuilder responseClazz(Class responseClazz) { 56 | mResponseClazz = responseClazz; 57 | return this; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/builder/PostBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: PostBuilder.java 3 | * Description: 普通Post请求构建类 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年10月13日 下午6:04:02 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.builder; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 14 | import com.luoxudong.app.asynchttp.request.PostRequest; 15 | 16 | /** 17 | *
18 |  * ClassName: PostBuilder
19 |  * Description:普通Post请求构建类,支持返回参数为json对象
20 |  * Create by: 罗旭东
21 |  * Date: 2016年10月13日 下午6:04:02
22 |  * 
23 | */ 24 | public class PostBuilder extends RequestBuilder { 25 | /** 请求body体内容 */ 26 | protected String mBody = null; 27 | /** 请求内容类型 */ 28 | protected String mContentType = null; 29 | /** 返回数据拦截器 */ 30 | private JsonResponseInterceptor mResponseInterceptor = null; 31 | /** 返回的json对象类型 */ 32 | private Class mResponseClazz = null; 33 | 34 | @Override 35 | public AsyncHttpTask build() { 36 | PostRequest request = new PostRequest(this); 37 | request.setResponseInterceptor(mResponseInterceptor); 38 | request.setResponseClazz(mResponseClazz); 39 | request.setBody(mBody); 40 | request.setContentType(mContentType); 41 | 42 | initRequest(request);//初始化request 43 | return request.build(); 44 | } 45 | 46 | /** 47 | * 设置请求内容 48 | * @param body http请求体 49 | * @return 50 | */ 51 | public PostBuilder body(String body) { 52 | mBody = body; 53 | return this; 54 | } 55 | 56 | /** 57 | * 设置请求内容类型 58 | * @param contentType 内容类型 59 | * @return 60 | */ 61 | public PostBuilder contentType(String contentType) { 62 | mContentType = contentType; 63 | return this; 64 | } 65 | 66 | /** 67 | * 设置返回json数据拦截器,拦截返回数据预处理,可以设置自定义json解析库 68 | * @param responseInterceptor 返回结果拦截器 69 | * @return 70 | */ 71 | public PostBuilder responseInterceptor(JsonResponseInterceptor responseInterceptor) { 72 | mResponseInterceptor = responseInterceptor; 73 | return this; 74 | } 75 | 76 | /** 77 | * 设置返回json的java类型 78 | * @param responseClazz 类型 79 | * @return 80 | */ 81 | public PostBuilder responseClazz(Class responseClazz) { 82 | mResponseClazz = responseClazz; 83 | return this; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/builder/PostBytesBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: PostBytesBuilder.java 3 | * Description: 传输字节数组的构建类 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年12月29日 下午2:27:57 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.builder; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.model.FileWrapper; 14 | import com.luoxudong.app.asynchttp.request.PostBytesRequest; 15 | 16 | /** 17 | *
18 |  * ClassName: PostBytesBuilder
19 |  * Description:传输字节数组的构建类,请求内容和返回内容都为字节数组
20 |  * Create by: 罗旭东
21 |  * Date: 2016年12月29日 下午2:27:57
22 |  * 
23 | */ 24 | public class PostBytesBuilder extends RequestBuilder { 25 | /** 请求内容字节数组 */ 26 | private byte[] mBuffer = null; 27 | 28 | public PostBytesBuilder() { 29 | init(); 30 | } 31 | 32 | @Override 33 | public AsyncHttpTask build() { 34 | PostBytesRequest request = new PostBytesRequest(this); 35 | request.setBuffer(mBuffer); 36 | 37 | initRequest(request);//初始化request 38 | return request.build(); 39 | } 40 | 41 | /** 42 | * 设置请求byte数组 43 | * @param buffer byte数组 44 | * @return 45 | */ 46 | public PostBytesBuilder buffer(byte[] buffer) { 47 | mBuffer = buffer; 48 | return this; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/builder/PostFormBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: PostFormBuilder.java 3 | * Description: Post提交form表单的构建类 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年11月23日 上午11:02:59 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.builder; 11 | 12 | import java.util.Map; 13 | import java.util.concurrent.ConcurrentHashMap; 14 | 15 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 16 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 17 | import com.luoxudong.app.asynchttp.request.PostFormRequest; 18 | 19 | /** 20 | *
21 |  * ClassName: PostFormBuilder
22 |  * Description:Post提交form表单的构建类,支持返回参数为json对象
23 |  * Create by: 罗旭东
24 |  * Date: 2016年11月23日 上午11:02:59
25 |  * 
26 | */ 27 | public class PostFormBuilder extends RequestBuilder { 28 | /** form表单内容 */ 29 | protected Map mFormMap = null; 30 | /** 返回数据拦截器 */ 31 | private JsonResponseInterceptor mResponseInterceptor = null; 32 | /** 返回的json对象类型 */ 33 | private Class mResponseClazz = null; 34 | 35 | public PostFormBuilder() { 36 | init(); 37 | } 38 | 39 | @Override 40 | protected void init() { 41 | super.init(); 42 | mFormMap = new ConcurrentHashMap(); 43 | } 44 | 45 | @Override 46 | public AsyncHttpTask build() { 47 | PostFormRequest request = new PostFormRequest(this); 48 | request.setResponseClazz(mResponseClazz); 49 | request.setResponseInterceptor(mResponseInterceptor); 50 | request.setFormMap(mFormMap); 51 | 52 | initRequest(request);//初始化request 53 | return request.build(); 54 | } 55 | 56 | /** 57 | * 添加form表单参数 58 | * @param key 键 59 | * @param value 键对应的值 60 | * @return 61 | */ 62 | public PostFormBuilder addFormParam(String key, String value) { 63 | mFormMap.put(key, value); 64 | return this; 65 | } 66 | 67 | /** 68 | * 批量添加form表单参数 69 | * @formParams form表单键值对应表 70 | * @return 71 | */ 72 | public PostFormBuilder addFormParams(Map formParams) { 73 | for(Map.Entry entry : formParams.entrySet()) { 74 | addFormParam(entry.getKey(), entry.getValue()); 75 | } 76 | return this; 77 | } 78 | 79 | /** 80 | * 设置返回json数据拦截器,拦截返回数据预处理,可以设置自定义json解析库 81 | * @param responseInterceptor 返回结果拦截器 82 | * @return 83 | */ 84 | public PostFormBuilder responseInterceptor(JsonResponseInterceptor responseInterceptor) { 85 | mResponseInterceptor = responseInterceptor; 86 | return this; 87 | } 88 | 89 | /** 90 | * 设置返回json的java类型 91 | * @param responseClazz 类型 92 | * @return 93 | */ 94 | public PostFormBuilder responseClazz(Class responseClazz) { 95 | mResponseClazz = responseClazz; 96 | return this; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/builder/PostJsonBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: PostJsonBuilder.java 3 | * Description: 请求内容和返回内容都为json对象的构建类 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年12月29日 下午4:17:36 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.builder; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.interceptor.JsonRequestInterceptor; 14 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 15 | import com.luoxudong.app.asynchttp.request.PostJsonRequest; 16 | 17 | /** 18 | *
19 |  * ClassName: PostJsonBuilder
20 |  * Description:请求内容和返回内容都为json对象的构建类
21 |  * Create by: 罗旭东
22 |  * Date: 2016年12月29日 下午4:17:36
23 |  * 
24 | */ 25 | public class PostJsonBuilder extends RequestBuilder { 26 | /** 请求对象 */ 27 | private Object mReqObj = null; 28 | /** 请求数据拦截器 */ 29 | private JsonRequestInterceptor mRequestInterceptor = null; 30 | /** 返回数据拦截器 */ 31 | private JsonResponseInterceptor mResponseInterceptor = null; 32 | /** 返回的json对象类型 */ 33 | private Class mResponseClazz = null; 34 | 35 | @Override 36 | public AsyncHttpTask build() { 37 | PostJsonRequest request = new PostJsonRequest(this); 38 | request.setResponseInterceptor(mResponseInterceptor); 39 | request.setResponseClazz(mResponseClazz); 40 | request.setReqObj(mReqObj); 41 | request.setRequestInterceptor(mRequestInterceptor); 42 | 43 | initRequest(request);//初始化request 44 | return request.build(); 45 | } 46 | 47 | public PostJsonBuilder reqObj(Object reqObj) { 48 | mReqObj = reqObj; 49 | return this; 50 | } 51 | 52 | /** 53 | * 设置请求对象拦截器,可以设置自定义json解析库 54 | * @param requestInterceptor 请求参数拦截器 55 | * @return 56 | */ 57 | public PostJsonBuilder requestInterceptor(JsonRequestInterceptor requestInterceptor) { 58 | mRequestInterceptor = requestInterceptor; 59 | return this; 60 | } 61 | 62 | /** 63 | * 设置返回json数据拦截器,拦截返回数据预处理,可以设置自定义json解析库 64 | * @param responseInterceptor 返回结果拦截器 65 | * @return 66 | */ 67 | public PostJsonBuilder responseInterceptor(JsonResponseInterceptor responseInterceptor) { 68 | mResponseInterceptor = responseInterceptor; 69 | return this; 70 | } 71 | 72 | /** 73 | * 设置返回json的java类型 74 | * @param responseClazz 类型 75 | * @return 76 | */ 77 | public PostJsonBuilder responseClazz(Class responseClazz) { 78 | mResponseClazz = responseClazz; 79 | return this; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/builder/RequestBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: RequestBuilder.java 3 | * Description: 通用请求参数构造类 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年10月13日 下午2:53:32 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.builder; 11 | 12 | import android.text.TextUtils; 13 | 14 | import com.luoxudong.app.asynchttp.AsyncHttpClient; 15 | import com.luoxudong.app.asynchttp.AsyncHttpConst; 16 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 17 | import com.luoxudong.app.asynchttp.request.AsyncHttpRequest; 18 | 19 | import java.util.Map; 20 | import java.util.concurrent.ConcurrentHashMap; 21 | 22 | 23 | /** 24 | *
 25 |  * ClassName: RequestBuilder
 26 |  * Description:通用请求参数构造类
 27 |  * Create by: 罗旭东
 28 |  * Date: 2016年10月13日 下午2:53:32
 29 |  * 
30 | */ 31 | public abstract class RequestBuilder> { 32 | /** http请求实例 */ 33 | private AsyncHttpClient mAsyncHttpClient = null; 34 | /** URL */ 35 | protected String mUrl = null; 36 | /** tag标签 */ 37 | protected String mTag = null; 38 | /** 是否在主线程中执行 */ 39 | protected boolean mMainThread = false; 40 | /** url参数 */ 41 | protected Map mUrlParams = null; 42 | /** http头参数 */ 43 | protected Map mHeaderParams = null; 44 | /** Cookie内容 */ 45 | protected Map mCookies = null; 46 | /** 自定义连接超时时间 */ 47 | protected int mConnectTimeout = 0; 48 | /** 读取数据超时时间 */ 49 | protected int mReadTimeout = 0; 50 | /** 写数据超时时间 */ 51 | protected int mWriteTimeout = 0; 52 | /** userAgent */ 53 | protected String mUserAgent = null; 54 | 55 | public RequestBuilder() { 56 | init(); 57 | } 58 | 59 | protected void init(){ 60 | mUrlParams = new ConcurrentHashMap(); 61 | mHeaderParams = new ConcurrentHashMap(); 62 | mCookies = new ConcurrentHashMap(); 63 | } 64 | 65 | protected void initRequest(AsyncHttpRequest request) { 66 | request.setAsyncHttpClient(mAsyncHttpClient); 67 | request.setUrl(mUrl); 68 | request.setMainThread(mMainThread); 69 | request.setTag(mTag); 70 | request.setUrlParams(mUrlParams); 71 | request.setHeaderParams(mHeaderParams); 72 | request.setCookies(mCookies); 73 | request.setUserAgent(mUserAgent); 74 | request.setConnectTimeout(mConnectTimeout); 75 | request.setReadTimeout(mReadTimeout); 76 | request.setWriteTimeout(mWriteTimeout); 77 | } 78 | 79 | public T asyncHttpClient(AsyncHttpClient asyncHttpClient) { 80 | mAsyncHttpClient = asyncHttpClient; 81 | return (T)this; 82 | } 83 | public T url(String url) { 84 | mUrl = url; 85 | return (T)this; 86 | } 87 | 88 | public T tag(String tag) { 89 | mTag = tag; 90 | return (T)this; 91 | } 92 | 93 | public T mainThread(boolean mainThread) { 94 | mMainThread = mainThread; 95 | return (T)this; 96 | } 97 | 98 | /** 99 | * 添加url参数 100 | * @param urlParams 101 | */ 102 | public T addUrlParams(Map urlParams) { 103 | if (urlParams != null) { 104 | for(Map.Entry entry : urlParams.entrySet()) { 105 | addUrlParam(entry.getKey(), entry.getValue()); 106 | } 107 | } 108 | 109 | return (T)this; 110 | } 111 | 112 | /** 113 | * 添加参数到map中 114 | * @param key 115 | * @param value 116 | */ 117 | public T addUrlParam(String key, String value){ 118 | if(key != null && value != null) { 119 | mUrlParams.put(key, value); 120 | } 121 | 122 | return (T)this; 123 | } 124 | 125 | /** 126 | * 添加header参数 127 | * @param headerParams 128 | */ 129 | public T addHeaderParams(Map headerParams){ 130 | if (headerParams != null) { 131 | for(Map.Entry entry : headerParams.entrySet()) { 132 | addHeaderParam(entry.getKey(), entry.getValue()); 133 | } 134 | } 135 | 136 | return (T)this; 137 | } 138 | 139 | /** 140 | * 添加header参数 141 | * @param key 142 | * @param value 143 | */ 144 | public T addHeaderParam(String key, String value){ 145 | if(key != null && value != null) { 146 | if (AsyncHttpConst.HEADER_COOKIE.equals(key)){//提取cookie值 147 | String[] cookieValues = value.split(","); 148 | 149 | for (String cookieValue : cookieValues){ 150 | if (!TextUtils.isEmpty(cookieValue)){ 151 | String[] values = cookieValue.split("="); 152 | if (values.length > 1){ 153 | addCookie(values[0], values[1]); 154 | } 155 | 156 | } 157 | } 158 | } 159 | mHeaderParams.put(key, value); 160 | } 161 | 162 | return (T)this; 163 | } 164 | 165 | /** 166 | * 设置cookie 167 | * @param cookies 168 | */ 169 | public T addCookies(Map cookies){ 170 | for(Map.Entry entry : cookies.entrySet()) { 171 | addCookie(entry.getKey(), entry.getValue()); 172 | } 173 | 174 | return (T)this; 175 | } 176 | 177 | /** 178 | * 设置cookie 179 | * @param key 180 | * @param value 181 | */ 182 | public T addCookie(String key, String value){ 183 | if(key != null && value != null) { 184 | mCookies.put(key, value); 185 | } 186 | 187 | return (T)this; 188 | } 189 | 190 | /** 191 | * 设置连接超时时间 192 | * @param connectTimeout 连接超时时间(毫秒) 193 | * @return 194 | */ 195 | public T connectTimeout(int connectTimeout) { 196 | mConnectTimeout = connectTimeout; 197 | return (T)this; 198 | } 199 | 200 | /** 201 | * 设置读取数据超时时间 202 | * @param readTimeout 读取数据超时时间(毫秒) 203 | * @return 204 | */ 205 | public T readTimeout(int readTimeout) { 206 | mReadTimeout = readTimeout; 207 | return (T)this; 208 | } 209 | 210 | /** 211 | * 设置写数据超时时间 212 | * @param writeTimeout 写数据超时时间(毫秒) 213 | * @return 214 | */ 215 | public T writeTimeout(int writeTimeout) { 216 | mWriteTimeout = writeTimeout; 217 | return (T)this; 218 | } 219 | 220 | /** 221 | * 对每个请求自定义User-Agent 222 | * @param userAgent User-Agent 223 | * @return 224 | */ 225 | public T userAgent(String userAgent) { 226 | mUserAgent = userAgent; 227 | return (T)this; 228 | } 229 | 230 | public abstract AsyncHttpTask build(); 231 | } 232 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/builder/UploadFileBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: UploadFileBuilder.java 3 | * Description: 上传文件构建类 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年11月23日 下午5:13:21 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.builder; 11 | 12 | import java.io.File; 13 | import java.util.Map; 14 | import java.util.concurrent.ConcurrentHashMap; 15 | 16 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 17 | import com.luoxudong.app.asynchttp.model.FileWrapper; 18 | import com.luoxudong.app.asynchttp.request.UploadFileRequest; 19 | 20 | /** 21 | *
22 |  * ClassName: UploadFileBuilder
23 |  * Description:上传文件构建类,支持多文件断点上传下载
24 |  * Create by: 罗旭东
25 |  * Date: 2016年11月23日 下午5:13:21
26 |  * 
27 | */ 28 | public class UploadFileBuilder extends RequestBuilder { 29 | /** form表单内容 */ 30 | protected Map mFormMap = null; 31 | /** 上传文件参数 */ 32 | private Map mFileMap = null; 33 | 34 | public UploadFileBuilder() { 35 | init(); 36 | } 37 | 38 | @Override 39 | protected void init() { 40 | super.init(); 41 | mFormMap = new ConcurrentHashMap(); 42 | mFileMap = new ConcurrentHashMap(); 43 | } 44 | 45 | @Override 46 | public AsyncHttpTask build() { 47 | UploadFileRequest request = new UploadFileRequest(this); 48 | request.setFormMap(mFormMap); 49 | request.setFileMap(mFileMap); 50 | 51 | initRequest(request);//初始化request 52 | return request.build(); 53 | } 54 | 55 | public UploadFileBuilder addFormParam(String key, String value) { 56 | mFormMap.put(key, value); 57 | return this; 58 | } 59 | 60 | public UploadFileBuilder addFormParams(Map formParams) { 61 | for(Map.Entry entry : formParams.entrySet()) { 62 | addFormParam(entry.getKey(), entry.getValue()); 63 | } 64 | return this; 65 | } 66 | 67 | public UploadFileBuilder addFile(String key, File file) { 68 | FileWrapper fileWrapper = new FileWrapper(); 69 | fileWrapper.setFile(file); 70 | fileWrapper.setBlockSize(file.length()); 71 | addFile(key, fileWrapper); 72 | return this; 73 | } 74 | 75 | public UploadFileBuilder addFile(String key, FileWrapper value) { 76 | mFileMap.put(key, value); 77 | return this; 78 | } 79 | 80 | public UploadFileBuilder addFiles(Map fileParams) { 81 | for(Map.Entry entry : fileParams.entrySet()) { 82 | addFile(entry.getKey(), entry.getValue()); 83 | } 84 | return this; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/callable/DownloadRequestCallable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: DownloadRequestCallable.java 3 | * Description: 下载文件文件回调 4 | * Copyright: Copyright (c) 2013 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 7 | * Date: 2015年7月17日 下午2:27:30 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.callable; 11 | 12 | /** 13 | * ClassName: DownloadRequestCallable 14 | * Description:下载文件文件回调 15 | * Create by: 16 | * Date: 2015年7月17日 下午2:27:30 17 | */ 18 | public abstract class DownloadRequestCallable extends RequestCallable { 19 | /** 20 | * 开始下载 21 | */ 22 | public void onStartTransfer(){}; 23 | 24 | /** 25 | * 下载中 26 | * @param totalLength 本次下载文件大小 27 | * @param transferedLength 已下载文件大小 28 | */ 29 | public void onTransfering(long totalLength, long transferedLength){}; 30 | 31 | /** 32 | * 下载成功 33 | */ 34 | public void onSuccess(){}; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/callable/JsonRequestCallable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: JsonRequestCallable.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午3:30:59 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.callable; 11 | 12 | 13 | /** 14 | *
15 |  * ClassName: JsonRequestCallable
16 |  * Description:http普通json请求回调,回调方法在UI线程中运行
17 |  * Create by: 罗旭东
18 |  * Date: 2015年7月13日 下午3:30:59
19 |  * 
20 | */ 21 | public abstract class JsonRequestCallable extends StringRequestCallable { 22 | /** 23 | * 返回普通json对象 24 | * @param responseInfo json对象 25 | */ 26 | public abstract void onSuccess(M responseInfo); 27 | 28 | /** 29 | * 返回内容为字符串 30 | * @param responseBody 字符串内容 31 | */ 32 | public void onSuccess(String responseBody) {}; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/callable/RequestCallable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: RequestCallable.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午3:21:52 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.callable; 11 | 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | /** 16 | *
17 |  * ClassName: RequestCallable
18 |  * Description:基础回调类,回调方法在UI线程中运行
19 |  * Create by: 罗旭东
20 |  * Date: 2015年7月13日 下午3:21:52
21 |  * 
22 | */ 23 | public abstract class RequestCallable { 24 | /** 请求ID */ 25 | protected long mId = 0; 26 | 27 | /** 28 | * 开始请求 29 | */ 30 | public void onStart(){}; 31 | 32 | /** 33 | * 请求结束 34 | */ 35 | public void onFinish(){}; 36 | 37 | /** 38 | * 取消请求 39 | */ 40 | public void onCancel(){}; 41 | 42 | /** 43 | * 返回成功 44 | * @param headers 返回的http头部信息 45 | */ 46 | public void onSuccess(Map> headers){}; 47 | 48 | 49 | /** 50 | * 请求成功 51 | * @param buffer byte数组 52 | */ 53 | public void onSuccess(byte[] buffer){}; 54 | 55 | /** 56 | * 操作失败回调 57 | * @param errorCode 错误码 58 | * @param errorMsg 错误信息 59 | */ 60 | public abstract void onFailed(int errorCode, String errorMsg); 61 | 62 | public long getId() { 63 | return mId; 64 | } 65 | 66 | public void setId(long id) { 67 | mId = id; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/callable/StringRequestCallable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: StringRequestCallable.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年12月30日 下午2:50:36 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.callable; 11 | 12 | /** 13 | *
14 |  * ClassName: StringRequestCallable
15 |  * Description:请求结果为普通字符串的回调类
16 |  * Create by: 罗旭东
17 |  * Date: 2016年12月30日 下午2:50:36
18 |  * 
19 | */ 20 | public abstract class StringRequestCallable extends RequestCallable { 21 | /** 22 | * 请求成功 23 | * @param responseBody 普通字符串内容 24 | */ 25 | public abstract void onSuccess(String responseBody); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/callable/UploadRequestCallable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: UploadRequestCallable.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 7 | * Date: 2015年7月17日 下午6:24:58 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.callable; 11 | 12 | /** 13 | * ClassName: UploadRequestCallable 14 | * Description:TODO(这里用一句话描述这个类的作用) 15 | * Create by: 16 | * Date: 2015年7月17日 下午6:24:58 17 | */ 18 | public abstract class UploadRequestCallable extends StringRequestCallable { 19 | /** 20 | * 开始上传 21 | */ 22 | public void onStartTransfer(){}; 23 | 24 | /** 25 | * 上传中 26 | * @param fileName 当前传输的文件名 27 | * @param totalLength 当前上传文件总大小 28 | * @param transferedLength 当前文件已上传大小 29 | */ 30 | public void onTransfering(String fileName, long totalLength, long transferedLength){}; 31 | 32 | /** 33 | * 上传成功 34 | * @param fileName 35 | */ 36 | public void onTransferSuc(String fileName){}; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/cookie/ClearableCookieJar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Francisco José Montiel Navarro. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.luoxudong.app.asynchttp.cookie; 18 | 19 | import okhttp3.CookieJar; 20 | 21 | /** 22 | * This interface extends {@link CookieJar} and adds methods to clear the cookies. 23 | */ 24 | public interface ClearableCookieJar extends CookieJar { 25 | 26 | /** 27 | * Clear all the session cookies while maintaining the persisted ones. 28 | */ 29 | void clearSession(); 30 | 31 | /** 32 | * Clear all the cookies from persistence and from the cache. 33 | */ 34 | void clear(); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/cookie/PersistentCookieJar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Francisco José Montiel Navarro. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.luoxudong.app.asynchttp.cookie; 18 | 19 | import com.luoxudong.app.asynchttp.cookie.cache.CookieCache; 20 | import com.luoxudong.app.asynchttp.cookie.persistence.CookiePersistor; 21 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 22 | 23 | import java.util.ArrayList; 24 | import java.util.Iterator; 25 | import java.util.List; 26 | 27 | import okhttp3.Cookie; 28 | import okhttp3.HttpUrl; 29 | 30 | public class PersistentCookieJar implements ClearableCookieJar { 31 | 32 | private CookieCache cache; 33 | private CookiePersistor persistor; 34 | 35 | public PersistentCookieJar(CookieCache cache, CookiePersistor persistor) { 36 | this.cache = cache; 37 | this.persistor = persistor; 38 | 39 | if (persistor != null) { 40 | this.cache.addAll(persistor.loadAll()); 41 | } 42 | } 43 | 44 | @Override 45 | synchronized public void saveFromResponse(HttpUrl url, List cookies) { 46 | List cookiesToRemove = new ArrayList<>(); 47 | if (cookies != null) {//删除重复的 48 | for (Cookie cookie : cookies) { 49 | for (Iterator it = cache.iterator(); it.hasNext(); ) { 50 | Cookie currentCookie = it.next(); 51 | 52 | if (currentCookie.matches(url) && cookie.name().equalsIgnoreCase(currentCookie.name())) { 53 | cookiesToRemove.add(currentCookie); 54 | it.remove(); 55 | } 56 | } 57 | } 58 | } 59 | 60 | cache.addAll(cookies); 61 | 62 | 63 | if (persistor != null) { 64 | persistor.removeAll(cookiesToRemove); 65 | persistor.saveAll(filterPersistentCookies(cookies)); 66 | } 67 | } 68 | 69 | private static List filterPersistentCookies(List cookies) { 70 | List persistentCookies = new ArrayList<>(); 71 | 72 | for (Cookie cookie : cookies) { 73 | if (cookie.persistent()) { 74 | persistentCookies.add(cookie); 75 | } 76 | } 77 | return persistentCookies; 78 | } 79 | 80 | @Override 81 | synchronized public List loadForRequest(HttpUrl url) { 82 | List cookiesToRemove = new ArrayList<>(); 83 | List validCookies = new ArrayList<>(); 84 | 85 | for (Iterator it = cache.iterator(); it.hasNext(); ) { 86 | Cookie currentCookie = it.next(); 87 | 88 | if (isCookieExpired(currentCookie)) { 89 | cookiesToRemove.add(currentCookie); 90 | it.remove(); 91 | } else if (currentCookie.matches(url)) { 92 | validCookies.add(currentCookie); 93 | } 94 | } 95 | 96 | if (persistor != null) { 97 | persistor.removeAll(cookiesToRemove); 98 | } 99 | 100 | return validCookies; 101 | } 102 | 103 | private static boolean isCookieExpired(Cookie cookie) { 104 | return cookie.expiresAt() < System.currentTimeMillis(); 105 | } 106 | 107 | @Override 108 | synchronized public void clearSession() { 109 | cache.clear(); 110 | 111 | if (persistor != null) { 112 | cache.addAll(persistor.loadAll()); 113 | } 114 | } 115 | 116 | @Override 117 | synchronized public void clear() { 118 | cache.clear(); 119 | 120 | if (persistor != null) { 121 | persistor.clear(); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/cookie/cache/CookieCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Francisco José Montiel Navarro. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.luoxudong.app.asynchttp.cookie.cache; 18 | 19 | import java.util.Collection; 20 | 21 | import okhttp3.Cookie; 22 | 23 | /** 24 | * A CookieCache handles the volatile cookie session storage. 25 | */ 26 | public interface CookieCache extends Iterable { 27 | 28 | /** 29 | * Add all the new cookies to the session, existing cookies will be overwritten. 30 | * 31 | * @param cookies 32 | */ 33 | void addAll(Collection cookies); 34 | 35 | /** 36 | * Clear all the cookies from the session. 37 | */ 38 | void clear(); 39 | } 40 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/cookie/cache/IdentifiableCookie.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Francisco José Montiel Navarro. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.luoxudong.app.asynchttp.cookie.cache; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Collection; 21 | import java.util.List; 22 | 23 | import okhttp3.Cookie; 24 | 25 | /** 26 | * This class decorates a Cookie to re-implements equals() and hashcode() methods in order to identify 27 | * the cookie by the following attributes: name, domain, path, secure & hostOnly.

28 | * 29 | * This new behaviour will be useful in determining when an already existing cookie in session must be overwritten. 30 | */ 31 | class IdentifiableCookie { 32 | 33 | private Cookie cookie; 34 | 35 | static List decorateAll(Collection cookies) { 36 | List identifiableCookies = new ArrayList<>(cookies.size()); 37 | for (Cookie cookie : cookies) { 38 | identifiableCookies.add(new IdentifiableCookie(cookie)); 39 | } 40 | return identifiableCookies; 41 | } 42 | 43 | IdentifiableCookie(Cookie cookie) { 44 | this.cookie = cookie; 45 | } 46 | 47 | Cookie getCookie() { 48 | return cookie; 49 | } 50 | 51 | @Override 52 | public boolean equals(Object other) { 53 | if (!(other instanceof IdentifiableCookie)) return false; 54 | IdentifiableCookie that = (IdentifiableCookie) other; 55 | return that.cookie.name().equals(this.cookie.name()) 56 | && that.cookie.domain().equals(this.cookie.domain()) 57 | && that.cookie.path().equals(this.cookie.path()) 58 | && that.cookie.secure() == this.cookie.secure() 59 | && that.cookie.hostOnly() == this.cookie.hostOnly(); 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | int hash = 17; 65 | hash = 31 * hash + cookie.name().hashCode(); 66 | hash = 31 * hash + cookie.domain().hashCode(); 67 | hash = 31 * hash + cookie.path().hashCode(); 68 | hash = 31 * hash + (cookie.secure() ? 0 : 1); 69 | hash = 31 * hash + (cookie.hostOnly() ? 0 : 1); 70 | return hash; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/cookie/cache/SetCookieCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Francisco José Montiel Navarro. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.luoxudong.app.asynchttp.cookie.cache; 18 | 19 | import java.util.Collection; 20 | import java.util.HashSet; 21 | import java.util.Iterator; 22 | import java.util.Set; 23 | 24 | import okhttp3.Cookie; 25 | 26 | public class SetCookieCache implements CookieCache { 27 | 28 | private Set cookies; 29 | 30 | public SetCookieCache() { 31 | cookies = new HashSet<>(); 32 | } 33 | 34 | @Override 35 | public void addAll(Collection newCookies) { 36 | for (IdentifiableCookie cookie : IdentifiableCookie.decorateAll(newCookies)) { 37 | this.cookies.remove(cookie); 38 | this.cookies.add(cookie); 39 | } 40 | } 41 | 42 | @Override 43 | public void clear() { 44 | cookies.clear(); 45 | } 46 | 47 | @Override 48 | public Iterator iterator() { 49 | return new SetCookieCacheIterator(); 50 | } 51 | 52 | private class SetCookieCacheIterator implements Iterator { 53 | 54 | private Iterator iterator; 55 | 56 | public SetCookieCacheIterator() { 57 | iterator = cookies.iterator(); 58 | } 59 | 60 | @Override 61 | public boolean hasNext() { 62 | return iterator.hasNext(); 63 | } 64 | 65 | @Override 66 | public Cookie next() { 67 | return iterator.next().getCookie(); 68 | } 69 | 70 | @Override 71 | public void remove() { 72 | try { 73 | iterator.remove(); 74 | } catch (Exception e) { 75 | e.printStackTrace(); 76 | } 77 | 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/cookie/persistence/CookiePersistor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Francisco José Montiel Navarro. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.luoxudong.app.asynchttp.cookie.persistence; 18 | 19 | import java.util.Collection; 20 | import java.util.List; 21 | 22 | import okhttp3.Cookie; 23 | 24 | /** 25 | * A CookiePersistor handles the persistent cookie storage. 26 | */ 27 | public interface CookiePersistor { 28 | 29 | List loadAll(); 30 | 31 | /** 32 | * Persist all cookies, existing cookies will be overwritten. 33 | * 34 | * @param cookies cookies persist 35 | */ 36 | void saveAll(Collection cookies); 37 | 38 | /** 39 | * Removes indicated cookies from persistence. 40 | * 41 | * @param cookies cookies to remove from persistence 42 | */ 43 | void removeAll(Collection cookies); 44 | 45 | /** 46 | * Clear all cookies from persistence. 47 | */ 48 | void clear(); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/cookie/persistence/SerializableCookie.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Francisco José Montiel Navarro. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.luoxudong.app.asynchttp.cookie.persistence; 18 | 19 | import android.util.Log; 20 | 21 | import java.io.ByteArrayInputStream; 22 | import java.io.ByteArrayOutputStream; 23 | import java.io.IOException; 24 | import java.io.ObjectInputStream; 25 | import java.io.ObjectOutputStream; 26 | import java.io.Serializable; 27 | 28 | import okhttp3.Cookie; 29 | 30 | public class SerializableCookie implements Serializable { 31 | private static final String TAG = SerializableCookie.class.getSimpleName(); 32 | 33 | private static final long serialVersionUID = -8594045714036645534L; 34 | 35 | private transient Cookie cookie; 36 | 37 | public String encode(Cookie cookie) { 38 | this.cookie = cookie; 39 | 40 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 41 | ObjectOutputStream objectOutputStream = null; 42 | 43 | try { 44 | objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); 45 | objectOutputStream.writeObject(this); 46 | } catch (IOException e) { 47 | Log.d(TAG, "IOException in encodeCookie", e); 48 | return null; 49 | } finally { 50 | if (objectOutputStream != null) { 51 | try { 52 | // Closing a ByteArrayOutputStream has no effect, it can be used later (and is used in the return statement) 53 | objectOutputStream.close(); 54 | } catch (IOException e) { 55 | Log.d(TAG, "Stream not closed in encodeCookie", e); 56 | } 57 | } 58 | } 59 | 60 | return byteArrayToHexString(byteArrayOutputStream.toByteArray()); 61 | } 62 | 63 | /** 64 | * Using some super basic byte array <-> hex conversions so we don't 65 | * have to rely on any large Base64 libraries. Can be overridden if you 66 | * like! 67 | * 68 | * @param bytes byte array to be converted 69 | * @return string containing hex values 70 | */ 71 | private static String byteArrayToHexString(byte[] bytes) { 72 | StringBuilder sb = new StringBuilder(bytes.length * 2); 73 | for (byte element : bytes) { 74 | int v = element & 0xff; 75 | if (v < 16) { 76 | sb.append('0'); 77 | } 78 | sb.append(Integer.toHexString(v)); 79 | } 80 | return sb.toString(); 81 | } 82 | 83 | public Cookie decode(String encodedCookie) { 84 | 85 | byte[] bytes = hexStringToByteArray(encodedCookie); 86 | ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( 87 | bytes); 88 | 89 | Cookie cookie = null; 90 | ObjectInputStream objectInputStream = null; 91 | try { 92 | objectInputStream = new ObjectInputStream(byteArrayInputStream); 93 | cookie = ((SerializableCookie) objectInputStream.readObject()).cookie; 94 | } catch (IOException e) { 95 | Log.d(TAG, "IOException in decodeCookie", e); 96 | } catch (ClassNotFoundException e) { 97 | Log.d(TAG, "ClassNotFoundException in decodeCookie", e); 98 | } finally { 99 | if (objectInputStream != null) { 100 | try { 101 | objectInputStream.close(); 102 | } catch (IOException e) { 103 | Log.d(TAG, "Stream not closed in decodeCookie", e); 104 | } 105 | } 106 | } 107 | return cookie; 108 | } 109 | 110 | /** 111 | * Converts hex values from strings to byte array 112 | * 113 | * @param hexString string of hex-encoded values 114 | * @return decoded byte array 115 | */ 116 | private static byte[] hexStringToByteArray(String hexString) { 117 | int len = hexString.length(); 118 | byte[] data = new byte[len / 2]; 119 | for (int i = 0; i < len; i += 2) { 120 | data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character 121 | .digit(hexString.charAt(i + 1), 16)); 122 | } 123 | return data; 124 | } 125 | 126 | private static long NON_VALID_EXPIRES_AT = -1L; 127 | 128 | private void writeObject(ObjectOutputStream out) throws IOException { 129 | out.writeObject(cookie.name()); 130 | out.writeObject(cookie.value()); 131 | out.writeLong(cookie.persistent() ? cookie.expiresAt() : NON_VALID_EXPIRES_AT); 132 | out.writeObject(cookie.domain()); 133 | out.writeObject(cookie.path()); 134 | out.writeBoolean(cookie.secure()); 135 | out.writeBoolean(cookie.httpOnly()); 136 | out.writeBoolean(cookie.hostOnly()); 137 | } 138 | 139 | private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 140 | Cookie.Builder builder = new Cookie.Builder(); 141 | 142 | builder.name((String) in.readObject()); 143 | 144 | builder.value((String) in.readObject()); 145 | 146 | long expiresAt = in.readLong(); 147 | if (expiresAt != NON_VALID_EXPIRES_AT) { 148 | builder.expiresAt(expiresAt); 149 | } 150 | 151 | final String domain = (String) in.readObject(); 152 | builder.domain(domain); 153 | 154 | builder.path((String) in.readObject()); 155 | 156 | if (in.readBoolean()) 157 | builder.secure(); 158 | 159 | if (in.readBoolean()) 160 | builder.httpOnly(); 161 | 162 | if (in.readBoolean()) 163 | builder.hostOnlyDomain(domain); 164 | 165 | cookie = builder.build(); 166 | } 167 | 168 | } -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/cookie/persistence/SharedPrefsCookiePersistor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Francisco José Montiel Navarro. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.luoxudong.app.asynchttp.cookie.persistence; 18 | 19 | import android.annotation.SuppressLint; 20 | import android.content.Context; 21 | import android.content.SharedPreferences; 22 | 23 | import java.util.ArrayList; 24 | import java.util.Collection; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | import okhttp3.Cookie; 29 | 30 | @SuppressLint("CommitPrefEdits") 31 | public class SharedPrefsCookiePersistor implements CookiePersistor { 32 | 33 | private final SharedPreferences sharedPreferences; 34 | 35 | public SharedPrefsCookiePersistor(Context context) { 36 | this(context.getSharedPreferences("CookiePersistence", Context.MODE_PRIVATE)); 37 | } 38 | 39 | public SharedPrefsCookiePersistor(SharedPreferences sharedPreferences) { 40 | this.sharedPreferences = sharedPreferences; 41 | } 42 | 43 | @Override 44 | public List loadAll() { 45 | List cookies = new ArrayList<>(sharedPreferences.getAll().size()); 46 | 47 | for (Map.Entry entry : sharedPreferences.getAll().entrySet()) { 48 | String serializedCookie = (String) entry.getValue(); 49 | Cookie cookie = new SerializableCookie().decode(serializedCookie); 50 | if (cookie != null) { 51 | cookies.add(cookie); 52 | } 53 | } 54 | return cookies; 55 | } 56 | 57 | @Override 58 | public void saveAll(Collection cookies) { 59 | SharedPreferences.Editor editor = sharedPreferences.edit(); 60 | for (Cookie cookie : cookies) { 61 | editor.putString(createCookieKey(cookie), new SerializableCookie().encode(cookie)); 62 | } 63 | editor.commit(); 64 | } 65 | 66 | @Override 67 | public void removeAll(Collection cookies) { 68 | SharedPreferences.Editor editor = sharedPreferences.edit(); 69 | for (Cookie cookie : cookies) { 70 | editor.remove(createCookieKey(cookie)); 71 | } 72 | editor.commit(); 73 | } 74 | 75 | private static String createCookieKey(Cookie cookie) { 76 | return (cookie.secure() ? "https" : "http") + "://" + cookie.domain() + cookie.path() + "|" + cookie.name(); 77 | } 78 | 79 | @Override 80 | public void clear() { 81 | sharedPreferences.edit().clear().commit(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/exception/AsyncHttpException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: AsyncHttpException.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午3:13:42 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.exception; 11 | 12 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 13 | 14 | /** 15 | * ClassName: AsyncHttpException 16 | * Description:HTTP网络连接异常处理类 17 | * Create by: 罗旭东 18 | * Date: 2015年7月13日 下午3:13:42 19 | */ 20 | public class AsyncHttpException extends RuntimeException { 21 | private static final String TAG = AsyncHttpException.class.getName(); 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | private int exceptionCode = -1; 26 | 27 | public AsyncHttpException(String message) { 28 | super(message); 29 | AsyncHttpLog.e(TAG, message); 30 | } 31 | 32 | public AsyncHttpException(String message, Throwable throwable) 33 | { 34 | super(message, throwable); 35 | AsyncHttpLog.e(TAG, message); 36 | } 37 | 38 | public AsyncHttpException(int exceptionCode, Throwable throwable) 39 | { 40 | super(throwable.toString(), throwable); 41 | setExceptionCode(exceptionCode); 42 | AsyncHttpLog.e(TAG, exceptionCode + ""); 43 | 44 | } 45 | 46 | public AsyncHttpException(int exceptionCode, String message) 47 | { 48 | super(message); 49 | setExceptionCode(exceptionCode); 50 | AsyncHttpLog.e(TAG, exceptionCode + ""); 51 | 52 | } 53 | 54 | public int getExceptionCode() { 55 | return exceptionCode; 56 | } 57 | 58 | public void setExceptionCode(int exceptionCode) { 59 | this.exceptionCode = exceptionCode; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/exception/AsyncHttpExceptionCode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: AsyncHttpExceptionCode.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午3:14:26 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.exception; 11 | 12 | /** 13 | * ClassName: AsyncHttpExceptionCode 14 | * Description:异常错误码 15 | * Create by: 罗旭东 16 | * Date: 2015年7月13日 下午3:14:26 17 | */ 18 | public enum AsyncHttpExceptionCode { 19 | success(0),//正常情况 20 | defaultExceptionCode(-10000 - 1),//默认异常码 21 | objectNullCode(-10000 - 2),//对象为空 22 | jsonParseException(-10000 - 3),//json解析错误 23 | jsonResponseException(-10000 - 4),//json网路请求返回异常 24 | httpRequestException(-10000 - 5),//http请求异常 25 | httpResponseException(-10000 - 6),//http请求返回异常 26 | unknownHostException(-10000 - 7),//无法解析主机 27 | httpSocketException(-10000 - 8),//socket异常 28 | socketTimeoutException(-10000 - 9),//socket超时 29 | invalidJsonString(-10000 - 10),//无效的json字符串 30 | sslPeerUnverifiedException(-10000 - 11),//不支持ssl协议 31 | buildRequestError(-10000 - 12),//构建请求异常 32 | serviceAddrError(-10000 - 13),//服务器地址错误 33 | connectTimeoutException(-10000 - 14),//连接超时 34 | invalidDownloadLength(-10000 - 15),//下载文件长度错误 35 | urlIsNull(-10000 - 16),//url为空 36 | sslException(-10000 - 17);//ssl证书握手失败 37 | 38 | private AsyncHttpExceptionCode(int errorCode) 39 | { 40 | this.errorCode = errorCode; 41 | } 42 | 43 | private int errorCode = -1; 44 | 45 | public int getErrorCode() { 46 | return errorCode; 47 | } 48 | 49 | public void setErrorCode(int errorCode) { 50 | this.errorCode = errorCode; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/handler/DownloadFileResponseHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | *

  3 |  * Title: DownloadFileResponseHandler.java
  4 |  * Description: 下载请求结果回调
  5 |  * Copyright: Copyright (c) 2014-2016 gjfax.com
  6 |  * Company: 广金所
  7 |  * Author: 罗旭东 (hi@luoxudong.com)
  8 |  * Date: 2017/1/24 11:58
  9 |  * Version: 1.0
 10 |  * 
11 | */ 12 | package com.luoxudong.app.asynchttp.handler; 13 | 14 | import android.os.Message; 15 | 16 | import com.luoxudong.app.asynchttp.AsyncHttpConst; 17 | import com.luoxudong.app.asynchttp.callable.DownloadRequestCallable; 18 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 19 | import com.luoxudong.app.asynchttp.exception.AsyncHttpException; 20 | import com.luoxudong.app.asynchttp.exception.AsyncHttpExceptionCode; 21 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 22 | 23 | import java.io.File; 24 | import java.io.FileNotFoundException; 25 | import java.io.FileOutputStream; 26 | import java.io.IOException; 27 | import java.io.InputStream; 28 | import java.io.RandomAccessFile; 29 | 30 | import okhttp3.Response; 31 | 32 | /** 33 | *
 34 |  * Class: DownloadFileResponseHandler
 35 |  * Description: 下载请求结果回调
 36 |  * Author: 罗旭东 (hi@luoxudong.com)
 37 |  * Date: 2017/1/24 11:58
 38 |  * Version: 1.0
 39 |  * 
40 | */ 41 | public class DownloadFileResponseHandler extends ResponseHandler { 42 | private final String TAG = DownloadFileResponseHandler.class.getSimpleName(); 43 | 44 | /** 开始传输 */ 45 | protected static final int FILE_TRANSFER_START = 100; 46 | /** 传输中 */ 47 | protected static final int FILE_TRANSFERING = 101; 48 | /** 传输缓存大小 */ 49 | protected static final int BUFFER_SIZE = 200 * 1024; 50 | /** 断点下载起始位置 */ 51 | private long mOffset = 0; 52 | /** 下载文件保存路径 */ 53 | private String mFileDir = null; 54 | /** 下载文件名 */ 55 | private String mFileName = null; 56 | /** 每次下载bffer大小 */ 57 | private byte[] mBuffer = new byte[BUFFER_SIZE]; 58 | 59 | public DownloadFileResponseHandler(String fileDir, String fileName, long offset, RequestCallable callable) { 60 | super(callable); 61 | mFileDir = fileDir; 62 | mFileName = fileName; 63 | mOffset = offset; 64 | } 65 | 66 | @Override 67 | protected void parseResponse(Response response) { 68 | boolean isChunked = "chunked".equalsIgnoreCase(response.header("Transfer-Encoding")); 69 | 70 | sendStartTransferMessage();//开始下载 71 | 72 | if (isChunked) {//chunked编码,不支持断点下载 73 | normalDownload(response); 74 | } else {//支持断点下载 75 | breakpointDownload(response); 76 | } 77 | } 78 | 79 | @Override 80 | protected void onSuccess(byte[] buffer) { 81 | onSuccess(); 82 | } 83 | 84 | public void onSuccess() { 85 | if (mCallable != null && mCallable instanceof DownloadRequestCallable) { 86 | ((DownloadRequestCallable)mCallable).onSuccess(); 87 | } 88 | } 89 | 90 | /** 91 | * 开始下载 92 | */ 93 | protected void sendStartTransferMessage() { 94 | sendMessage(obtainMessage(FILE_TRANSFER_START, null)); 95 | } 96 | 97 | /** 98 | * 正在传输 99 | */ 100 | protected void sendTransferingMessage(long totalLength, long transferedLength) { 101 | sendMessage(obtainMessage(FILE_TRANSFERING, new long[]{totalLength, transferedLength})); 102 | } 103 | 104 | @Override 105 | protected void handlerMessageCustom(Message msg) { 106 | switch (msg.what) { 107 | case FILE_TRANSFER_START: 108 | if (mCallable != null && mCallable instanceof DownloadRequestCallable) { 109 | ((DownloadRequestCallable)mCallable).onStartTransfer(); 110 | } 111 | 112 | break; 113 | case FILE_TRANSFERING: 114 | if (mCallable != null && mCallable instanceof DownloadRequestCallable) { 115 | long[] param = (long[])msg.obj; 116 | ((DownloadRequestCallable)mCallable).onTransfering(param[0], param[1]); 117 | } 118 | break; 119 | default: 120 | break; 121 | } 122 | } 123 | 124 | /** 125 | * 普通下载 126 | * @param response 127 | */ 128 | private void normalDownload(Response response) { 129 | File localFile = new File(mFileDir, mFileName); 130 | int length = 0; 131 | long offset = 0; 132 | 133 | if (!localFile.getParentFile().exists()) {//文件夹不存在则创建文件夹 134 | localFile.getParentFile().mkdirs(); 135 | } else {//不支持断点下载,删除原来的文件 136 | localFile.delete(); 137 | } 138 | 139 | InputStream is = response.body().byteStream(); 140 | FileOutputStream out = null; 141 | 142 | try { 143 | out = new FileOutputStream(localFile); 144 | 145 | long timeStamp = System.currentTimeMillis(); 146 | while ((length = is.read(mBuffer)) != -1) { 147 | out.write(mBuffer, 0, length); 148 | offset += length; 149 | 150 | if ((System.currentTimeMillis() - timeStamp) >= AsyncHttpConst.TRANSFER_REFRESH_TIME_INTERVAL) { 151 | AsyncHttpLog.d(TAG, "下载进度:" + offset); 152 | sendTransferingMessage(offset + 1, offset); 153 | timeStamp = System.currentTimeMillis();// 每一秒调用一次 154 | } 155 | } 156 | 157 | sendTransferingMessage(offset, offset); 158 | sendSuccessMessage(response.headers(), null); 159 | 160 | } catch (IOException e) { 161 | sendFailureMessage(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), e); 162 | } finally { 163 | if (out != null) { 164 | try { 165 | out.close(); 166 | } catch (IOException e) { 167 | sendFailureMessage(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), e); 168 | } 169 | } 170 | } 171 | } 172 | 173 | /** 174 | * 断点下载 175 | * @param response 176 | */ 177 | private void breakpointDownload(Response response) { 178 | RandomAccessFile randomAccessFile = null; 179 | long totalLength = response.body().contentLength();//下载文件总长度 180 | InputStream is = response.body().byteStream(); 181 | 182 | File localFile = new File(mFileDir, mFileName); 183 | 184 | if (!localFile.getParentFile().exists()) {//文件夹不存在则创建文件夹 185 | localFile.getParentFile().mkdirs(); 186 | } 187 | 188 | if (localFile.exists() && localFile.length() != totalLength){//文件存在但大小不一致,则删除 189 | localFile.delete(); 190 | } 191 | 192 | try { 193 | boolean isNewFile = !localFile.exists(); 194 | randomAccessFile = new RandomAccessFile(localFile, "rw"); 195 | if (isNewFile) {//如果是新文件则指定文件大小 196 | randomAccessFile.setLength(totalLength); 197 | } 198 | 199 | downloading(response, randomAccessFile); 200 | } catch (FileNotFoundException e1) { 201 | sendFailureMessage(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), new AsyncHttpException("文件不存在!")); 202 | return; 203 | } catch (IOException e) { 204 | if (randomAccessFile != null) { 205 | try { 206 | randomAccessFile.close(); 207 | } catch (IOException e1) { 208 | e1.printStackTrace(); 209 | } 210 | } 211 | sendFailureMessage(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), new AsyncHttpException("IO异常!")); 212 | return; 213 | }finally{ 214 | if (randomAccessFile != null) { 215 | try { 216 | randomAccessFile.close(); 217 | } catch (IOException e) { 218 | 219 | } 220 | } 221 | } 222 | } 223 | 224 | /** 225 | * 开始下载 226 | * @param response 227 | * @param randomAccessFile 228 | * @throws IOException 229 | */ 230 | private void downloading(Response response, RandomAccessFile randomAccessFile) throws IOException { 231 | long offset = 0; 232 | int length = 0; 233 | InputStream is = response.body().byteStream(); 234 | long totalLength = response.body().contentLength();//下载文件总长度 235 | 236 | //支持断点下载 237 | if (response.code() == 206) { 238 | offset = mOffset; 239 | } 240 | 241 | randomAccessFile.seek(offset); 242 | 243 | long timeStamp = System.currentTimeMillis(); 244 | while (offset < totalLength && (length = is.read(mBuffer)) != -1) { 245 | offset += length; 246 | randomAccessFile.write(mBuffer, 0, length); 247 | 248 | if ((System.currentTimeMillis() - timeStamp) >= AsyncHttpConst.TRANSFER_REFRESH_TIME_INTERVAL || offset == totalLength) { 249 | AsyncHttpLog.d(TAG, "下载进度:" + offset + "/" + totalLength); 250 | sendTransferingMessage(totalLength, offset); 251 | timeStamp = System.currentTimeMillis();// 每一秒调用一次 252 | } 253 | } 254 | 255 | if (offset == totalLength) {//下载完成 256 | sendTransferingMessage(totalLength, totalLength); 257 | sendSuccessMessage(response.headers(), null); 258 | } else if (offset > totalLength) { 259 | sendFailureMessage(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), new AsyncHttpException("本地文件长度超过总长度!")); 260 | } 261 | } 262 | 263 | } 264 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/handler/JsonResponseHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: JsonResponseHandler.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年12月30日 下午3:28:02 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.handler; 11 | 12 | import java.io.UnsupportedEncodingException; 13 | 14 | import android.text.TextUtils; 15 | 16 | import com.luoxudong.app.asynchttp.AsyncHttpConst; 17 | import com.luoxudong.app.asynchttp.callable.JsonRequestCallable; 18 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 19 | import com.luoxudong.app.asynchttp.callable.StringRequestCallable; 20 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 21 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 22 | 23 | /** 24 | *
25 |  * ClassName: JsonResponseHandler
26 |  * Description:json结果请求回调
27 |  * Create by: 罗旭东
28 |  * Date: 2016年12月30日 下午3:28:02
29 |  * 
30 | */ 31 | public class JsonResponseHandler extends StringResponseHandler { 32 | private final String TAG = JsonResponseHandler.class.getSimpleName(); 33 | /** 返回json对应的映射类 */ 34 | private Class mResponseClazz = null; 35 | /** 返回结果拦截器,可以自定义json解析器 */ 36 | private JsonResponseInterceptor mResponseInterceptor = null; 37 | 38 | public JsonResponseHandler(Class responseClazz, JsonResponseInterceptor responseInterceptor, RequestCallable callable) { 39 | super(callable); 40 | mResponseClazz = responseClazz; 41 | mResponseInterceptor = responseInterceptor; 42 | } 43 | 44 | protected void onSuccess(String responseBody) { 45 | if (mCallable != null && mCallable instanceof JsonRequestCallable) { 46 | Object rspObject = null; 47 | 48 | AsyncHttpLog.i(TAG, responseBody); 49 | 50 | if (!TextUtils.isEmpty(responseBody) && mResponseInterceptor != null) { 51 | rspObject = mResponseInterceptor.convertJsonToObj(responseBody, mResponseClazz); 52 | 53 | if (!mResponseInterceptor.checkResponse(rspObject)) {//结果校验为通过 54 | ((JsonRequestCallable)mCallable).onFailed(mResponseInterceptor.getErrorCode(), mResponseInterceptor.getErrorMsg()); 55 | return; 56 | } 57 | } 58 | 59 | ((JsonRequestCallable)mCallable).onSuccess(rspObject); 60 | } else { 61 | super.onSuccess(responseBody); 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/handler/ResponseHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: ResponseHandler.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午5:22:32 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.handler; 11 | 12 | import java.io.IOException; 13 | 14 | import okhttp3.Headers; 15 | import okhttp3.Response; 16 | import android.os.Handler; 17 | import android.os.Looper; 18 | import android.os.Message; 19 | 20 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 21 | import com.luoxudong.app.asynchttp.exception.AsyncHttpException; 22 | import com.luoxudong.app.asynchttp.exception.AsyncHttpExceptionCode; 23 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 24 | 25 | /** 26 | * ClassName: ResponseHandler 27 | * Description:处理请求返回结果 28 | * Create by: 罗旭东 29 | * Date: 2015年7月13日 下午5:22:32 30 | */ 31 | public class ResponseHandler { 32 | private static final String TAG = ResponseHandler.class.getSimpleName(); 33 | 34 | /** 请求成功 */ 35 | protected static final int SUCCESS_MESSAGE = 0; 36 | /** 请求失败 */ 37 | protected static final int FAILURE_MESSAGE = 1; 38 | /** 开始请求 */ 39 | protected static final int START_MESSAGE = 2; 40 | /** 请求完成 */ 41 | protected static final int FINISH_MESSAGE = 3; 42 | /** 中断请求 */ 43 | protected static final int CANCEL_MESSAGE = 4; 44 | /** 返回结果是否在主线程中执行 */ 45 | private boolean mMainThread = false; 46 | /** 请求回调 */ 47 | protected RequestCallable mCallable = null; 48 | 49 | private Handler mMainHandler = null; 50 | 51 | public ResponseHandler(RequestCallable callable) { 52 | mCallable = callable; 53 | // 检测当前线程是否有绑定looper,如果没有绑定则使用主线程的looper 54 | 55 | if (Looper.myLooper() != null) { 56 | mMainHandler = new Handler() { 57 | @Override 58 | public void handleMessage(Message msg) { 59 | ResponseHandler.this.handleMessage(msg); 60 | } 61 | }; 62 | } else { 63 | mMainHandler = new Handler(Looper.getMainLooper()) { 64 | @Override 65 | public void handleMessage(Message msg) { 66 | ResponseHandler.this.handleMessage(msg); 67 | } 68 | }; 69 | } 70 | 71 | } 72 | 73 | /** 74 | * 请求返回结果统一入口 75 | * @param response 76 | */ 77 | public void onResponseSucess(Response response) { 78 | if (!response.isSuccessful()) { 79 | sendFailureMessage(AsyncHttpExceptionCode.httpResponseException.getErrorCode(), new AsyncHttpException(response.message())); 80 | return; 81 | } 82 | 83 | parseResponse(response); 84 | 85 | } 86 | 87 | /** 88 | * 解析返回数据 89 | * @param response 90 | */ 91 | protected void parseResponse(Response response) { 92 | try { 93 | byte[] buffer = response.body().bytes(); 94 | Headers headers = response.headers(); 95 | response.close(); 96 | 97 | sendSuccessMessage(headers, buffer); 98 | } catch (IOException e) { 99 | sendFailureMessage(AsyncHttpExceptionCode.httpResponseException.getErrorCode(), e); 100 | } 101 | } 102 | 103 | public void sendSuccessMessage(Headers headers, byte[] buffer) { 104 | sendMessage(obtainMessage(SUCCESS_MESSAGE, new Object[]{ headers, buffer})); 105 | } 106 | 107 | public void sendFailureMessage(int errorCode, Throwable e) { 108 | sendMessage(obtainMessage(FAILURE_MESSAGE, new Object[]{errorCode, e})); 109 | } 110 | 111 | public void sendStartMessage() { 112 | sendMessage(obtainMessage(START_MESSAGE, null)); 113 | } 114 | 115 | public void sendFinishMessage() { 116 | sendMessage(obtainMessage(FINISH_MESSAGE, null)); 117 | } 118 | 119 | public void sendCancelMessage(){ 120 | sendMessage(obtainMessage(CANCEL_MESSAGE, null)); 121 | } 122 | 123 | protected void handleMessage(Message msg) { 124 | Object[] response; 125 | 126 | switch(msg.what) { 127 | case SUCCESS_MESSAGE: 128 | response = (Object[])msg.obj; 129 | handleSuccessMessage((Headers) response[0], (byte[])response[1]); 130 | break; 131 | case FAILURE_MESSAGE: 132 | response = (Object[])msg.obj; 133 | handleFailureMessage((Integer)response[0], (Throwable)response[1]); 134 | break; 135 | case START_MESSAGE: 136 | onStart(); 137 | break; 138 | case FINISH_MESSAGE: 139 | onFinish(); 140 | break; 141 | case CANCEL_MESSAGE: 142 | onCancel(); 143 | break; 144 | default: 145 | handlerMessageCustom(msg); 146 | break; 147 | } 148 | } 149 | 150 | protected void handleSuccessMessage(Headers headers, byte[] buffer) { 151 | if (mCallable != null) { 152 | mCallable.onSuccess(headers.toMultimap()); 153 | } 154 | 155 | onSuccess(buffer); 156 | } 157 | 158 | protected void handlerMessageCustom(Message msg) { 159 | 160 | } 161 | 162 | protected void onStart() { 163 | if (mCallable != null){ 164 | mCallable.onStart(); 165 | } 166 | } 167 | 168 | protected void onFinish() { 169 | if (mCallable != null){ 170 | mCallable.onFinish(); 171 | } 172 | } 173 | 174 | protected void onCancel() { 175 | if (mCallable != null){ 176 | mCallable.onCancel(); 177 | } 178 | } 179 | 180 | protected void onSuccess(byte[] buffer) { 181 | if (mCallable != null) { 182 | mCallable.onSuccess(buffer); 183 | } 184 | } 185 | 186 | protected void handleFailureMessage(int errorCode, Throwable e) { 187 | onFailure(errorCode, e); 188 | } 189 | 190 | protected void onFailure(int errorCode, Throwable e) { 191 | String errorMsg = e.getMessage(); 192 | AsyncHttpLog.e(TAG, "错误信息:" + errorMsg + "[" + errorCode + "]"); 193 | 194 | if (mCallable != null) { 195 | mCallable.onFailed(errorCode, errorMsg); 196 | } 197 | } 198 | 199 | protected void sendMessage(Message msg) { 200 | if(mMainHandler != null && mMainThread){//需要在主线程中执行 201 | mMainHandler.sendMessage(msg); 202 | } else { 203 | handleMessage(msg); 204 | } 205 | } 206 | 207 | protected Message obtainMessage(int responseMessage, Object response) { 208 | Message msg = null; 209 | if(mMainHandler != null){ 210 | msg = mMainHandler.obtainMessage(responseMessage, response); 211 | }else{ 212 | msg = Message.obtain(); 213 | msg.what = responseMessage; 214 | msg.obj = response; 215 | } 216 | return msg; 217 | } 218 | 219 | public void setMainThread(boolean mainThread) { 220 | mMainThread = mainThread; 221 | } 222 | 223 | } 224 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/handler/StringResponseHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: StringResponseHandler.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年11月22日 下午2:46:50 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.handler; 11 | 12 | import java.io.UnsupportedEncodingException; 13 | 14 | import com.luoxudong.app.asynchttp.AsyncHttpConst; 15 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 16 | import com.luoxudong.app.asynchttp.callable.StringRequestCallable; 17 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 18 | 19 | /** 20 | *
21 |  * ClassName: StringResponseHandler
22 |  * Description:返回结果为字符串类型的回调
23 |  * Create by: 罗旭东
24 |  * Date: 2016年11月22日 下午2:46:50
25 |  * 
26 | */ 27 | public class StringResponseHandler extends ResponseHandler { 28 | private final String TAG = StringResponseHandler.class.getSimpleName(); 29 | 30 | /** 31 | * @param callable 32 | */ 33 | public StringResponseHandler(RequestCallable callable) { 34 | super(callable); 35 | } 36 | 37 | @Override 38 | protected void onSuccess(byte[] buffer) { 39 | super.onSuccess(buffer); 40 | try { 41 | onSuccess(buffer == null ? null : new String(buffer, AsyncHttpConst.HTTP_ENCODING)); 42 | } catch (UnsupportedEncodingException e) { 43 | AsyncHttpLog.e(TAG, "不支持该编码"); 44 | } 45 | } 46 | 47 | protected void onSuccess(String responseBody) { 48 | AsyncHttpLog.i(TAG, responseBody); 49 | 50 | if (mCallable != null && mCallable instanceof StringRequestCallable) { 51 | ((StringRequestCallable)mCallable).onSuccess(responseBody); 52 | } else { 53 | AsyncHttpLog.w(TAG, "回调类型错误!"); 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/handler/UploadFileResponseHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | *
  3 |  * Title: UploadFileResponseHandler.java
  4 |  * Description:上传文件回调
  5 |  * Copyright: Copyright (c) 2014-2016 luoxudong.com
  6 |  * Company: 个人
  7 |  * Author: 罗旭东 (hi@luoxudong.com)
  8 |  * Date: 2017/1/13 17:27
  9 |  * Version: 1.0
 10 |  * 
11 | */ 12 | package com.luoxudong.app.asynchttp.handler; 13 | 14 | import android.os.Message; 15 | 16 | import com.luoxudong.app.asynchttp.AsyncHttpConst; 17 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 18 | import com.luoxudong.app.asynchttp.callable.UploadRequestCallable; 19 | import com.luoxudong.app.asynchttp.exception.AsyncHttpExceptionCode; 20 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 21 | 22 | import java.io.UnsupportedEncodingException; 23 | 24 | /** 25 | *
 26 |  * Class: UploadFileResponseHandler
 27 |  * Description: 上传文件回调
 28 |  * Author: 罗旭东 (hi@luoxudong.com)
 29 |  * Date: 2017/1/24 12:02
 30 |  * Version: 1.0
 31 |  * 
32 | */ 33 | public class UploadFileResponseHandler extends ResponseHandler { 34 | private final String TAG = UploadFileResponseHandler.class.getSimpleName(); 35 | 36 | /** 开始传输 */ 37 | protected static final int FILE_TRANSFER_START = 100; 38 | /** 传输中 */ 39 | protected static final int FILE_TRANSFERING = 101; 40 | /** 单个文件上传成功 */ 41 | protected static final int FILE_TRANSFER_SEC = 102; 42 | /** 传输缓存大小 */ 43 | protected static final int BUFFER_SIZE = 200 * 1024; 44 | 45 | public UploadFileResponseHandler(RequestCallable callable) { 46 | super(callable); 47 | } 48 | 49 | /** 50 | * 开始下载 51 | */ 52 | public void sendStartTransferMessage() { 53 | sendMessage(obtainMessage(FILE_TRANSFER_START, null)); 54 | } 55 | 56 | /** 57 | * 正在传输 58 | */ 59 | public void sendTransferingMessage(String fileName, long totalLength, long transferedLength) { 60 | sendMessage(obtainMessage(FILE_TRANSFERING, new Object[]{fileName, totalLength, transferedLength})); 61 | } 62 | 63 | public void sendTransferSucMessage(String fileName) { 64 | sendMessage(obtainMessage(FILE_TRANSFER_SEC, fileName)); 65 | } 66 | 67 | @Override 68 | protected void handlerMessageCustom(Message msg) { 69 | switch (msg.what) { 70 | case FILE_TRANSFER_START: 71 | if (mCallable != null && mCallable instanceof UploadRequestCallable) { 72 | ((UploadRequestCallable)mCallable).onStartTransfer(); 73 | } 74 | 75 | break; 76 | case FILE_TRANSFERING: 77 | if (mCallable != null && mCallable instanceof UploadRequestCallable) { 78 | Object[] param = (Object[])msg.obj; 79 | ((UploadRequestCallable)mCallable).onTransfering((String)param[0], (long)param[1], (long)param[2]); 80 | } 81 | break; 82 | case FILE_TRANSFER_SEC: 83 | if (mCallable != null && mCallable instanceof UploadRequestCallable) { 84 | ((UploadRequestCallable)mCallable).onTransferSuc((String)msg.obj); 85 | } 86 | break; 87 | default: 88 | break; 89 | } 90 | } 91 | 92 | @Override 93 | protected void onSuccess(byte[] buffer) { 94 | try { 95 | onSuccess(buffer == null ? null : new String(buffer, AsyncHttpConst.HTTP_ENCODING)); 96 | } catch (UnsupportedEncodingException e) { 97 | if (mCallable != null) { 98 | mCallable.onFailed(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), "不支持该编码!"); 99 | } 100 | } 101 | } 102 | 103 | protected void onSuccess(String responseBody) { 104 | AsyncHttpLog.i(TAG, responseBody); 105 | 106 | if (mCallable != null && mCallable instanceof UploadRequestCallable) { 107 | ((UploadRequestCallable)mCallable).onSuccess(responseBody); 108 | } else { 109 | AsyncHttpLog.w(TAG, "回调类型错误!"); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/https/MySslSocketFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | *
  3 |  * Title: MySslSocketFactory.java
  4 |  * Description: 获取自定义sslSocket类
  5 |  * Copyright: Copyright (c) 2014-2016 gjfax.com
  6 |  * Company: 广金所
  7 |  * Author: 罗旭东 (hi@luoxudong.com)
  8 |  * Date: 2017/1/24 12:03
  9 |  * Version: 1.0
 10 |  * 
11 | */ 12 | package com.luoxudong.app.asynchttp.https; 13 | 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.security.KeyManagementException; 17 | import java.security.KeyStore; 18 | import java.security.KeyStoreException; 19 | import java.security.NoSuchAlgorithmException; 20 | import java.security.UnrecoverableKeyException; 21 | import java.security.cert.CertificateException; 22 | import java.security.cert.CertificateFactory; 23 | 24 | import javax.net.ssl.KeyManager; 25 | import javax.net.ssl.KeyManagerFactory; 26 | import javax.net.ssl.SSLContext; 27 | import javax.net.ssl.TrustManager; 28 | import javax.net.ssl.TrustManagerFactory; 29 | import javax.net.ssl.X509TrustManager; 30 | 31 | /** 32 | *
 33 |  * Class: MySslSocketFactory
 34 |  * Description: 获取自定义sslsocket类
 35 |  * Author: 罗旭东 (hi@luoxudong.com)
 36 |  * Date: 2017/1/24 12:03
 37 |  * Version: 1.0
 38 |  * 
39 | */ 40 | public class MySslSocketFactory { 41 | public SSLParams getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password) { 42 | SSLParams sslParams = new SSLParams(); 43 | try { 44 | TrustManager[] trustManagers = prepareTrustManager(certificates); 45 | KeyManager[] keyManagers = prepareKeyManager(bksFile, password); 46 | SSLContext sslContext = SSLContext.getInstance("TLS"); 47 | X509TrustManager trustManager = null; 48 | if (trustManagers != null) { 49 | trustManager = new MyTrustManager(trustManagers); 50 | } else { 51 | trustManager = new UnSafeTrustManager(); 52 | } 53 | sslContext.init(keyManagers, new TrustManager[]{trustManager},null); 54 | sslParams.setSSLSocketFactory(sslContext.getSocketFactory()); 55 | sslParams.setTrustManager(trustManager); 56 | return sslParams; 57 | } catch (NoSuchAlgorithmException e) { 58 | throw new AssertionError(e); 59 | } catch (KeyManagementException e) { 60 | throw new AssertionError(e); 61 | } catch (KeyStoreException e) { 62 | throw new AssertionError(e); 63 | } 64 | } 65 | 66 | private TrustManager[] prepareTrustManager(InputStream... certificates) { 67 | if (certificates == null || certificates.length <= 0) { 68 | return null; 69 | } 70 | 71 | try { 72 | CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); 73 | KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 74 | keyStore.load(null); 75 | int index = 0; 76 | for (InputStream certificate : certificates) { 77 | String certificateAlias = Integer.toString(index++); 78 | keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate)); 79 | try { 80 | if (certificate != null){ 81 | certificate.close(); 82 | } 83 | } catch (IOException e) { 84 | } 85 | } 86 | TrustManagerFactory trustManagerFactory = null; 87 | 88 | trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 89 | trustManagerFactory.init(keyStore); 90 | 91 | TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); 92 | 93 | return trustManagers; 94 | } catch (NoSuchAlgorithmException e) { 95 | e.printStackTrace(); 96 | } catch (CertificateException e) { 97 | e.printStackTrace(); 98 | } catch (KeyStoreException e) { 99 | e.printStackTrace(); 100 | } catch (Exception e) { 101 | e.printStackTrace(); 102 | } 103 | return null; 104 | 105 | } 106 | 107 | private KeyManager[] prepareKeyManager(InputStream bksFile, String password) { 108 | try { 109 | if (bksFile == null || password == null) { 110 | return null; 111 | } 112 | 113 | KeyStore clientKeyStore = KeyStore.getInstance("BKS"); 114 | clientKeyStore.load(bksFile, password.toCharArray()); 115 | KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 116 | keyManagerFactory.init(clientKeyStore, password.toCharArray()); 117 | return keyManagerFactory.getKeyManagers(); 118 | 119 | } catch (KeyStoreException e) { 120 | e.printStackTrace(); 121 | } catch (NoSuchAlgorithmException e) { 122 | e.printStackTrace(); 123 | } catch (UnrecoverableKeyException e) { 124 | e.printStackTrace(); 125 | } catch (CertificateException e) { 126 | e.printStackTrace(); 127 | } catch (IOException e) { 128 | e.printStackTrace(); 129 | } catch (Exception e) { 130 | e.printStackTrace(); 131 | } 132 | return null; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/https/MyTrustManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | *
 3 |  * Title: MyTrustManager.java
 4 |  * Description: 信任证书管理类
 5 |  * Copyright: Copyright (c) 2014-2016 gjfax.com
 6 |  * Company: 广金所
 7 |  * Author: 罗旭东 (hi@luoxudong.com)
 8 |  * Date: 2017/1/24 12:03
 9 |  * Version: 1.0
10 |  * 
11 | */ 12 | package com.luoxudong.app.asynchttp.https; 13 | 14 | import android.util.Log; 15 | 16 | import java.security.KeyStore; 17 | import java.security.KeyStoreException; 18 | import java.security.NoSuchAlgorithmException; 19 | import java.security.cert.CertificateException; 20 | import java.security.cert.X509Certificate; 21 | 22 | import javax.net.ssl.TrustManager; 23 | import javax.net.ssl.TrustManagerFactory; 24 | import javax.net.ssl.X509TrustManager; 25 | 26 | /** 27 | *
28 |  * Class: MyTrustManager
29 |  * Description: 信任证书管理类
30 |  * Author: 罗旭东 (hi@luoxudong.com)
31 |  * Date: 2017/1/24 12:03
32 |  * Version: 1.0
33 |  * 
34 | */ 35 | public class MyTrustManager implements X509TrustManager { 36 | private X509TrustManager mDefaultTrustManager = null; 37 | private X509TrustManager mLocalTrustManager = null; 38 | 39 | public MyTrustManager(TrustManager[] trustManagers) throws NoSuchAlgorithmException, KeyStoreException { 40 | TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 41 | trustManagerFactory.init((KeyStore) null); 42 | mDefaultTrustManager = chooseTrustManager(trustManagerFactory.getTrustManagers()); 43 | mLocalTrustManager = chooseTrustManager(trustManagers); 44 | } 45 | 46 | @Override 47 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 48 | 49 | } 50 | 51 | @Override 52 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 53 | try { 54 | mDefaultTrustManager.checkServerTrusted(chain, authType); 55 | } catch (CertificateException e) { 56 | mLocalTrustManager.checkServerTrusted(chain, authType); 57 | } 58 | } 59 | 60 | 61 | @Override 62 | public X509Certificate[] getAcceptedIssuers() 63 | { 64 | return new X509Certificate[0]; 65 | } 66 | 67 | private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) { 68 | for (TrustManager trustManager : trustManagers) { 69 | if (trustManager instanceof X509TrustManager) { 70 | return (X509TrustManager) trustManager; 71 | } 72 | } 73 | return null; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/https/SSLParams.java: -------------------------------------------------------------------------------- 1 | /** 2 | *
 3 |  * Title: SSLParams.java
 4 |  * Description: 设置ssl链接参数类
 5 |  * Copyright: Copyright (c) 2014-2016 gjfax.com
 6 |  * Company: 广金所
 7 |  * Author: 罗旭东 (hi@luoxudong.com)
 8 |  * Date: 2017/1/24 12:04
 9 |  * Version: 1.0
10 |  * 
11 | */ 12 | package com.luoxudong.app.asynchttp.https; 13 | 14 | import javax.net.ssl.SSLSocketFactory; 15 | import javax.net.ssl.X509TrustManager; 16 | 17 | /** 18 | *
19 |  * Class: SSLParams
20 |  * Description: 设置ssl链接参数类
21 |  * Author: 罗旭东 (hi@luoxudong.com)
22 |  * Date: 2017/1/24 12:04
23 |  * Version: 1.0
24 |  * 
25 | */ 26 | public class SSLParams { 27 | private SSLSocketFactory mSSLSocketFactory = null; 28 | 29 | private X509TrustManager mTrustManager = null; 30 | 31 | public SSLSocketFactory getSSLSocketFactory() { 32 | return mSSLSocketFactory; 33 | } 34 | 35 | public void setSSLSocketFactory(SSLSocketFactory sSLSocketFactory) { 36 | mSSLSocketFactory = sSLSocketFactory; 37 | } 38 | 39 | public X509TrustManager getTrustManager() { 40 | return mTrustManager; 41 | } 42 | 43 | public void setTrustManager(X509TrustManager trustManager) { 44 | mTrustManager = trustManager; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/https/UnSafeHostnameVerifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | *
 3 |  * Title: UnSafeHostnameVerifier.java
 4 |  * Description:
 5 |  * Copyright: Copyright (c) 2014-2016 gjfax.com
 6 |  * Company: 广金所
 7 |  * Author: 罗旭东 (hi@luoxudong.com)
 8 |  * Date: 2017/1/24 12:04
 9 |  * Version: 1.0
10 |  * 
11 | */ 12 | package com.luoxudong.app.asynchttp.https; 13 | 14 | import javax.net.ssl.HostnameVerifier; 15 | import javax.net.ssl.SSLSession; 16 | 17 | /** 18 | *
19 |  * Class: UnSafeHostnameVerifier
20 |  * Description:
21 |  * Author: 罗旭东 (hi@luoxudong.com)
22 |  * Date: 2017/1/24 12:05
23 |  * Version: 1.0
24 |  * 
25 | */ 26 | public class UnSafeHostnameVerifier implements HostnameVerifier { 27 | @Override 28 | public boolean verify(String hostname, SSLSession session) { 29 | return true; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/https/UnSafeTrustManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | *
 3 |  * Title: UnSafeTrustManager.java
 4 |  * Description:
 5 |  * Copyright: Copyright (c) 2014-2016 gjfax.com
 6 |  * Company: 广金所
 7 |  * Author: 罗旭东 (hi@luoxudong.com)
 8 |  * Date: 2017/1/24 12:05
 9 |  * Version: 1.0
10 |  * 
11 | */ 12 | package com.luoxudong.app.asynchttp.https; 13 | 14 | import java.security.cert.CertificateException; 15 | import java.security.cert.X509Certificate; 16 | 17 | import javax.net.ssl.X509TrustManager; 18 | 19 | /** 20 | *
21 |  * Class: UnSafeTrustManager
22 |  * Description:
23 |  * Author: 罗旭东 (hi@luoxudong.com)
24 |  * Date: 2017/1/24 12:05
25 |  * Version: 1.0
26 |  * 
27 | */ 28 | public class UnSafeTrustManager implements X509TrustManager { 29 | @Override 30 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 31 | } 32 | 33 | @Override 34 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 35 | } 36 | 37 | @Override 38 | public X509Certificate[] getAcceptedIssuers() { 39 | return new java.security.cert.X509Certificate[]{}; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/interceptor/JsonRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: JsonRequestInterceptor.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年1月7日 下午3:00:00 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.interceptor; 11 | 12 | 13 | /** 14 | * ClassName: JsonRequestInterceptor 15 | * Description:发送Json请求时拦截器,在发送请求之前处理数据,需要把json对象转换成字符串 16 | * Create by: 罗旭东 17 | * Date: 2016年1月7日 下午3:00:00 18 | */ 19 | public abstract class JsonRequestInterceptor { 20 | /** 21 | * 把指定对象转换成json字符串 22 | * @param requestObj 23 | * @return 24 | */ 25 | public abstract String convertJsonToObj(Object requestObj); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/interceptor/JsonResponseInterceptor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: JsonResponseInterceptor.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年1月7日 下午3:01:00 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.interceptor; 11 | 12 | import com.luoxudong.app.asynchttp.exception.AsyncHttpExceptionCode; 13 | 14 | /** 15 | * ClassName: JsonResponseInterceptor 16 | * Description:发送Json返回拦截器,需要将json字符串转换成对象 17 | * Create by: 罗旭东 18 | * Date: 2016年1月7日 下午3:01:00 19 | */ 20 | public abstract class JsonResponseInterceptor { 21 | /** 错误码 */ 22 | private int mErrorCode = AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(); 23 | /** 错误信息 */ 24 | private String mErrorMsg = ""; 25 | 26 | /** 27 | * 把json字符串转换成对象 28 | * @param responseStr 29 | * @return 30 | */ 31 | public abstract M convertJsonToObj(String responseStr, Class responseClass); 32 | 33 | /** 34 | * 检测该结果是否成功 35 | * @param response 36 | * @return 37 | */ 38 | public abstract boolean checkResponse(M response); 39 | 40 | public void setErrorCode(int errorCode) { 41 | mErrorCode = errorCode; 42 | } 43 | 44 | public void setErrorMsg(String errorMsg) { 45 | mErrorMsg = errorMsg; 46 | } 47 | 48 | /** 49 | * 错误码 50 | * @return 51 | */ 52 | public int getErrorCode(){ 53 | return mErrorCode; 54 | } 55 | 56 | /** 57 | * 错误信息 58 | * @return 59 | */ 60 | public String getErrorMsg(){ 61 | return mErrorMsg; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/interceptor/UserAgentInterceptor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: UserAgentInterceptor.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年11月23日 上午11:55:05 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.interceptor; 11 | 12 | import android.os.Build; 13 | import android.webkit.WebSettings; 14 | 15 | import java.io.IOException; 16 | 17 | import com.luoxudong.app.asynchttp.AsyncHttpConst; 18 | 19 | import okhttp3.Interceptor; 20 | import okhttp3.Request; 21 | import okhttp3.Response; 22 | import okhttp3.Interceptor.Chain; 23 | 24 | /** 25 | *
26 |  * ClassName: UserAgentInterceptor
27 |  * Description:userAgent拦截器
28 |  * Create by: 罗旭东
29 |  * Date: 2016年11月23日 上午11:55:05
30 |  * 
31 | */ 32 | public class UserAgentInterceptor implements Interceptor { 33 | private String mUserAgent = null; 34 | 35 | public UserAgentInterceptor() { 36 | mUserAgent = AsyncHttpConst.sUserAgent; 37 | } 38 | 39 | public UserAgentInterceptor(String userAgent) { 40 | mUserAgent = userAgent; 41 | } 42 | 43 | @Override 44 | public Response intercept(Chain chain) throws IOException 45 | { 46 | Request request = chain.request(); 47 | Request newRequest = request.newBuilder() 48 | .removeHeader(AsyncHttpConst.HEADER_USER_AGENT) 49 | .addHeader(AsyncHttpConst.HEADER_USER_AGENT, checkUserAgent(mUserAgent)) 50 | .build(); 51 | return chain.proceed(newRequest); 52 | } 53 | 54 | /** 55 | * 对不合法字符处理,见Headers->checkNameAndValue 56 | * @param userAgent 57 | * @return 58 | */ 59 | private String checkUserAgent(String userAgent) { 60 | StringBuffer sb = new StringBuffer(); 61 | for (int i = 0, length = userAgent.length(); i < length; i++) { 62 | char c = userAgent.charAt(i); 63 | if (c <= '\u001f' && c!='\u0009' || c >= '\u007f') { 64 | sb.append(String.format("\\u%04x", (int) c)); 65 | } else { 66 | sb.append(c); 67 | } 68 | } 69 | return sb.toString(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/model/FileWrapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: FileWrapper.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 7 | * Date: 2015年7月17日 下午5:11:54 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.model; 11 | 12 | import java.io.File; 13 | 14 | /** 15 | * ClassName: FileWrapper 16 | * Description:上传文件参数封装类 17 | * Create by: 18 | * Date: 2015年7月17日 下午5:11:54 19 | */ 20 | public class FileWrapper { 21 | /** 上传的文件 */ 22 | private File mFile = null; 23 | /** 上传的起始地址 */ 24 | private long mStartPos = 0; 25 | /** 上传的块大小,默认上传全部文件 */ 26 | private long mBlockSize = 0; 27 | 28 | public File getFile() { 29 | return mFile; 30 | } 31 | 32 | public void setFile(File file) { 33 | mFile = file; 34 | } 35 | 36 | public long getStartPos() { 37 | return mStartPos; 38 | } 39 | 40 | public void setStartPos(long startPos) { 41 | mStartPos = startPos; 42 | } 43 | 44 | public long getBlockSize() { 45 | return mBlockSize; 46 | } 47 | 48 | public void setBlockSize(long blockSize) { 49 | mBlockSize = blockSize; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/request/AsyncHttpRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: AsyncHttpRequest.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年10月13日 下午3:43:41 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.request; 11 | 12 | import android.net.Uri; 13 | import android.text.TextUtils; 14 | 15 | import com.luoxudong.app.asynchttp.AsyncHttpClient; 16 | import com.luoxudong.app.asynchttp.AsyncHttpConst; 17 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 18 | import com.luoxudong.app.asynchttp.AsyncHttpUtil; 19 | import com.luoxudong.app.asynchttp.builder.RequestBuilder; 20 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 21 | import com.luoxudong.app.asynchttp.exception.AsyncHttpException; 22 | import com.luoxudong.app.asynchttp.exception.AsyncHttpExceptionCode; 23 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 24 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 25 | 26 | import java.util.Iterator; 27 | import java.util.Map; 28 | import java.util.Set; 29 | 30 | import okhttp3.Headers; 31 | import okhttp3.Request; 32 | 33 | /** 34 | *
 35 |  * ClassName: AsyncHttpRequest
 36 |  * Description:各种请求基类
 37 |  * Create by: 罗旭东
 38 |  * Date: 2016年10月13日 下午3:43:41
 39 |  * 
40 | */ 41 | public abstract class AsyncHttpRequest { 42 | private long mId = 0; 43 | /** http请求实例 */ 44 | private AsyncHttpClient mAsyncHttpClient = null; 45 | /** URL */ 46 | protected String mUrl = null; 47 | /** 是否在主线程中执行 */ 48 | protected boolean mMainThread = false; 49 | /** 请求tag */ 50 | protected String mTag = null; 51 | /** url参数 */ 52 | protected Map mUrlParams = null; 53 | /** http头参数 */ 54 | protected Map mHeaderParams = null; 55 | /** Cookie内容 */ 56 | protected Map mCookies = null; 57 | /** userAgent */ 58 | protected String mUserAgent = null; 59 | /** 自定义连接超时时间 */ 60 | protected int mConnectTimeout = 0; 61 | /** 读取数据超时时间 */ 62 | protected int mReadTimeout = 0; 63 | /** 写数据超时时间 */ 64 | protected int mWriteTimeout = 0; 65 | /** 发送请求之前异常 */ 66 | private AsyncHttpException mAsyncHttpException = null; 67 | protected Request.Builder mBuilder = new Request.Builder(); 68 | 69 | public AsyncHttpRequest(RequestBuilder builder) { 70 | mId = System.nanoTime() - AsyncHttpUtil.sStartTime; 71 | } 72 | 73 | public abstract AsyncHttpTask build(); 74 | 75 | /** 构建请求 */ 76 | public abstract Request buildRequest(RequestCallable callable); 77 | 78 | public abstract ResponseHandler buildResponseHandler(RequestCallable callable); 79 | 80 | /** 81 | * 初始化请求 82 | */ 83 | protected void initRequest() { 84 | if (TextUtils.isEmpty(mUrl)) { 85 | AsyncHttpLog.e(AsyncHttpConst.TAG_LOG, "url不能为空"); 86 | mAsyncHttpException = new AsyncHttpException(AsyncHttpExceptionCode.urlIsNull.getErrorCode(), "url不能为空"); 87 | return; 88 | } 89 | 90 | if (TextUtils.isEmpty(mTag)) { 91 | mTag = String.valueOf(mId); 92 | } 93 | 94 | String url = buildUrl(mUrl); 95 | mBuilder.url(url).tag(mTag); 96 | buildHeaders(); 97 | } 98 | 99 | /** 100 | * 构建url 101 | * @param url 102 | */ 103 | private String buildUrl(String url) { 104 | if (url == null || mUrlParams == null || mUrlParams.isEmpty()) { 105 | return url; 106 | } 107 | 108 | Uri.Builder builder = Uri.parse(url).buildUpon(); 109 | Set keys = mUrlParams.keySet(); 110 | Iterator iterator = keys.iterator(); 111 | while (iterator.hasNext()) { 112 | String key = iterator.next(); 113 | builder.appendQueryParameter(key, mUrlParams.get(key)); 114 | } 115 | return builder.build().toString(); 116 | } 117 | 118 | /** 119 | * 构建http头 120 | */ 121 | private void buildHeaders() { 122 | Headers.Builder headerBuilder = new Headers.Builder(); 123 | 124 | if (mHeaderParams != null) { 125 | for (String key : mHeaderParams.keySet()) { 126 | if (key.equals(AsyncHttpConst.HEADER_USER_AGENT)) { 127 | headerBuilder.removeAll(key); 128 | } 129 | 130 | try { 131 | headerBuilder.add(key, mHeaderParams.get(key)); 132 | } catch (Exception e) { 133 | 134 | } 135 | 136 | } 137 | } 138 | 139 | mBuilder.headers(headerBuilder.build()); 140 | } 141 | 142 | public AsyncHttpClient getAsyncHttpClient() { 143 | return mAsyncHttpClient; 144 | } 145 | 146 | public long getId() { 147 | return mId; 148 | } 149 | 150 | public AsyncHttpException getAsyncHttpException() { 151 | return mAsyncHttpException; 152 | } 153 | 154 | public boolean isMainThread() { return mMainThread; } 155 | 156 | public String getUserAgent() { 157 | return mUserAgent; 158 | } 159 | 160 | public Map getCookies() { 161 | return mCookies; 162 | } 163 | 164 | public int getConnectTimeout() { 165 | return mConnectTimeout; 166 | } 167 | 168 | public int getReadTimeout() { 169 | return mReadTimeout; 170 | } 171 | 172 | public int getWriteTimeout() { 173 | return mWriteTimeout; 174 | } 175 | 176 | 177 | public void setAsyncHttpClient(AsyncHttpClient asyncHttpClient) { 178 | mAsyncHttpClient = asyncHttpClient; 179 | } 180 | 181 | public void setUrl(String url) { 182 | mUrl = url; 183 | } 184 | 185 | public void setTag(String tag) { 186 | mTag = tag; 187 | } 188 | 189 | public void setMainThread(boolean mainThread) { mMainThread = mainThread; } 190 | 191 | public void setUrlParams(Map urlParams) { 192 | mUrlParams = urlParams; 193 | } 194 | 195 | public void setHeaderParams(Map headerParams) { 196 | mHeaderParams = headerParams; 197 | } 198 | 199 | public void setCookies(Map cookies) { 200 | mCookies = cookies; 201 | } 202 | 203 | public void setUserAgent(String userAgent) { 204 | mUserAgent = userAgent; 205 | } 206 | 207 | public void setConnectTimeout(int connectTimeout) { 208 | mConnectTimeout = connectTimeout; 209 | } 210 | 211 | public void setReadTimeout(int readTimeout) { 212 | mReadTimeout = readTimeout; 213 | } 214 | 215 | public void setWriteTimeout(int writeTimeout) { 216 | mWriteTimeout = writeTimeout; 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/request/DownloadFileRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | *
 3 |  * Title: DownloadFileRequest.java
 4 |  * Description: 下载文件请求类
 5 |  * Copyright: Copyright (c) 2014-2016 gjfax.com
 6 |  * Company: 广金所
 7 |  * Author: 罗旭东 (hi@luoxudong.com)
 8 |  * Date: 2017/1/24 12:12
 9 |  * Version: 1.0
10 |  * 
11 | */ 12 | package com.luoxudong.app.asynchttp.request; 13 | 14 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 15 | import com.luoxudong.app.asynchttp.builder.DownloadFileBuilder; 16 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 17 | import com.luoxudong.app.asynchttp.handler.DownloadFileResponseHandler; 18 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 19 | 20 | import okhttp3.Request; 21 | 22 | /** 23 | *
24 |  * Class: DownloadFileRequest
25 |  * Description: 下载文件请求类
26 |  * Author: 罗旭东 (hi@luoxudong.com)
27 |  * Date: 2017/1/24 12:12
28 |  * Version: 1.0
29 |  * 
30 | */ 31 | public class DownloadFileRequest extends AsyncHttpRequest { 32 | /** 断点下载起始位置 */ 33 | private long mOffset = 0; 34 | /** 下载文件大小 */ 35 | private long mLength = 0; 36 | /** 下载文件保存路径 */ 37 | private String mFileDir = null; 38 | /** 下载文件名 */ 39 | private String mFileName = null; 40 | 41 | public DownloadFileRequest(DownloadFileBuilder builder) { 42 | super(builder); 43 | } 44 | 45 | @Override 46 | public AsyncHttpTask build() { 47 | //断点下载 48 | if (mOffset > 0 || mLength > 0) { 49 | String rangeValue = "bytes=" + mOffset + "-"; 50 | 51 | if (mLength > 0) { 52 | rangeValue += (mOffset + mLength); 53 | } 54 | 55 | mHeaderParams.put("range", rangeValue); 56 | } 57 | 58 | initRequest(); 59 | return new AsyncHttpTask(this); 60 | } 61 | 62 | @Override 63 | public Request buildRequest(RequestCallable callable) { 64 | return mBuilder.get().build(); 65 | } 66 | 67 | @Override 68 | public ResponseHandler buildResponseHandler(RequestCallable callable) { 69 | return new DownloadFileResponseHandler(mFileDir, mFileName, mOffset, callable); 70 | } 71 | 72 | public void setOffset(long offset) { 73 | mOffset = offset; 74 | } 75 | 76 | public void setLength(long length) { 77 | mLength = length; 78 | } 79 | 80 | public void setFileDir(String fileDir) { 81 | mFileDir = fileDir; 82 | } 83 | 84 | public void setFileName(String fileName) { 85 | mFileName = fileName; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/request/GetRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: GetRequest.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年10月13日 下午3:44:01 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.request; 11 | 12 | import okhttp3.Request; 13 | 14 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 15 | import com.luoxudong.app.asynchttp.builder.GetBuilder; 16 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 17 | import com.luoxudong.app.asynchttp.handler.JsonResponseHandler; 18 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 19 | import com.luoxudong.app.asynchttp.handler.StringResponseHandler; 20 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 21 | 22 | /** 23 | *
24 |  * ClassName: GetRequest
25 |  * Description:Get请求
26 |  * Create by: 罗旭东
27 |  * Date: 2016年10月13日 下午3:44:01
28 |  * 
29 | */ 30 | public class GetRequest extends AsyncHttpRequest { 31 | /** 返回数据拦截器 */ 32 | private JsonResponseInterceptor mResponseInterceptor = null; 33 | /** 返回的json对象类型 */ 34 | private Class mResponseClazz = null; 35 | 36 | public GetRequest(GetBuilder builder) { 37 | super(builder); 38 | } 39 | 40 | @Override 41 | public Request buildRequest(RequestCallable callable) { 42 | return mBuilder.get().build(); 43 | } 44 | 45 | @Override 46 | public AsyncHttpTask build() { 47 | initRequest(); 48 | return new AsyncHttpTask(this); 49 | } 50 | 51 | @Override 52 | public ResponseHandler buildResponseHandler(RequestCallable callable) { 53 | return new JsonResponseHandler(getResponseClazz(), getResponseInterceptor(), callable); 54 | } 55 | 56 | public JsonResponseInterceptor getResponseInterceptor() { 57 | return mResponseInterceptor; 58 | } 59 | 60 | public void setResponseInterceptor(JsonResponseInterceptor responseInterceptor) { 61 | mResponseInterceptor = responseInterceptor; 62 | } 63 | 64 | public Class getResponseClazz() { 65 | return mResponseClazz; 66 | } 67 | 68 | public void setResponseClazz(Class responseClazz) { 69 | mResponseClazz = responseClazz; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/request/PostBytesRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: PostBytesRequest.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年12月29日 下午2:31:03 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.request; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.ContentType; 14 | import com.luoxudong.app.asynchttp.builder.PostBytesBuilder; 15 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 16 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 17 | 18 | import okhttp3.MediaType; 19 | import okhttp3.Request; 20 | import okhttp3.RequestBody; 21 | 22 | /** 23 | *
24 |  * ClassName: PostBytesRequest
25 |  * Description:提交byte数组请求类
26 |  * Create by: 罗旭东
27 |  * Date: 2016年12月29日 下午2:31:03
28 |  * 
29 | */ 30 | public class PostBytesRequest extends AsyncHttpRequest { 31 | private byte[] mBuffer = null; 32 | 33 | public PostBytesRequest(PostBytesBuilder builder) { 34 | super(builder); 35 | } 36 | 37 | @Override 38 | public AsyncHttpTask build() { 39 | initRequest(); 40 | return new AsyncHttpTask(this); 41 | } 42 | 43 | @Override 44 | public Request buildRequest(RequestCallable callable) { 45 | if (getBuffer() == null) { 46 | mBuffer = new byte[0]; 47 | } 48 | return mBuilder.post(RequestBody.create(MediaType.parse(ContentType.octetStream.getValue()), getBuffer())).build(); 49 | } 50 | 51 | @Override 52 | public ResponseHandler buildResponseHandler(RequestCallable callable) { 53 | return new ResponseHandler(callable); 54 | } 55 | 56 | public byte[] getBuffer() { 57 | return mBuffer; 58 | } 59 | 60 | public void setBuffer(byte[] buffer) { 61 | mBuffer = buffer; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/request/PostFormRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: PostFormRequest.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年11月23日 上午11:15:45 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.request; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.builder.PostFormBuilder; 14 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 15 | import com.luoxudong.app.asynchttp.handler.JsonResponseHandler; 16 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 17 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 18 | 19 | import java.util.Map; 20 | 21 | import okhttp3.FormBody; 22 | import okhttp3.Request; 23 | 24 | /** 25 | *
26 |  * ClassName: PostFormRequest
27 |  * Description:form提交数据请求
28 |  * Create by: 罗旭东
29 |  * Date: 2016年11月23日 上午11:15:45
30 |  * 
31 | */ 32 | public class PostFormRequest extends AsyncHttpRequest { 33 | protected Map mFormMap = null; 34 | /** 返回数据拦截器 */ 35 | private JsonResponseInterceptor mResponseInterceptor = null; 36 | /** 返回的json对象类型 */ 37 | private Class mResponseClazz = null; 38 | 39 | public PostFormRequest(PostFormBuilder builder) { 40 | super(builder); 41 | } 42 | 43 | @Override 44 | public Request buildRequest(RequestCallable callable) { 45 | FormBody.Builder builder = new FormBody.Builder(); 46 | addParams(builder); 47 | FormBody formBody = builder.build(); 48 | return mBuilder.post(formBody).build(); 49 | } 50 | 51 | @Override 52 | public AsyncHttpTask build() { 53 | initRequest(); 54 | return new AsyncHttpTask(this); 55 | } 56 | 57 | /** 58 | * 添加form表单参数 59 | * @param builder 60 | */ 61 | private void addParams(FormBody.Builder builder) { 62 | if (mFormMap != null) { 63 | for (String key : mFormMap.keySet()) { 64 | builder.add(key, mFormMap.get(key)); 65 | } 66 | } 67 | } 68 | 69 | @Override 70 | public ResponseHandler buildResponseHandler(RequestCallable callable) { 71 | return new JsonResponseHandler(getResponseClazz(), getResponseInterceptor(), callable); 72 | } 73 | 74 | public JsonResponseInterceptor getResponseInterceptor() { 75 | return mResponseInterceptor; 76 | } 77 | 78 | public Class getResponseClazz() { 79 | return mResponseClazz; 80 | } 81 | 82 | public void setFormMap(Map formMap) { 83 | mFormMap = formMap; 84 | } 85 | 86 | public void setResponseInterceptor(JsonResponseInterceptor responseInterceptor) { 87 | mResponseInterceptor = responseInterceptor; 88 | } 89 | 90 | public void setResponseClazz(Class responseClazz) { 91 | mResponseClazz = responseClazz; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/request/PostJsonRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: PostJsonRequest.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年12月29日 下午4:23:05 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.request; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.ContentType; 14 | import com.luoxudong.app.asynchttp.builder.PostJsonBuilder; 15 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 16 | import com.luoxudong.app.asynchttp.handler.JsonResponseHandler; 17 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 18 | import com.luoxudong.app.asynchttp.interceptor.JsonRequestInterceptor; 19 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 20 | 21 | import okhttp3.MediaType; 22 | import okhttp3.Request; 23 | import okhttp3.RequestBody; 24 | 25 | /** 26 | *
 27 |  * ClassName: PostJsonRequest
 28 |  * Description:提交json数据请求类
 29 |  * Create by: 罗旭东
 30 |  * Date: 2016年12月29日 下午4:23:05
 31 |  * 
32 | */ 33 | public class PostJsonRequest extends AsyncHttpRequest { 34 | /** 请求对象 */ 35 | private Object mReqObj = null; 36 | /** 请求数据拦截器 */ 37 | private JsonRequestInterceptor mRequestInterceptor = null; 38 | /** 返回数据拦截器 */ 39 | private JsonResponseInterceptor mResponseInterceptor = null; 40 | /** 返回的json对象类型 */ 41 | private Class mResponseClazz = null; 42 | 43 | public PostJsonRequest(PostJsonBuilder builder) { 44 | super(builder); 45 | } 46 | 47 | @Override 48 | public AsyncHttpTask build() { 49 | initRequest(); 50 | return new AsyncHttpTask(this); 51 | } 52 | 53 | @Override 54 | public Request buildRequest(RequestCallable callable) { 55 | String body = ""; 56 | 57 | if (getRequestInterceptor() != null && getReqObj() != null) {//需要拦截处理 58 | body = getRequestInterceptor().convertJsonToObj(getReqObj()); 59 | } else if (getReqObj() != null){ 60 | body = getReqObj().toString(); 61 | } 62 | 63 | return mBuilder.post(RequestBody.create(MediaType.parse(ContentType.text.getValue()), body)).build(); 64 | } 65 | 66 | @Override 67 | public ResponseHandler buildResponseHandler(RequestCallable callable) { 68 | return new JsonResponseHandler(getResponseClazz(), getResponseInterceptor(), callable); 69 | } 70 | 71 | public Object getReqObj() { 72 | return mReqObj; 73 | } 74 | 75 | public JsonRequestInterceptor getRequestInterceptor() { 76 | return mRequestInterceptor; 77 | } 78 | 79 | public JsonResponseInterceptor getResponseInterceptor() { 80 | return mResponseInterceptor; 81 | } 82 | 83 | public Class getResponseClazz() { 84 | return mResponseClazz; 85 | } 86 | 87 | public void setReqObj(Object reqObj) { 88 | mReqObj = reqObj; 89 | } 90 | 91 | public void setRequestInterceptor(JsonRequestInterceptor requestInterceptor) { 92 | mRequestInterceptor = requestInterceptor; 93 | } 94 | 95 | public void setResponseInterceptor(JsonResponseInterceptor responseInterceptor) { 96 | mResponseInterceptor = responseInterceptor; 97 | } 98 | 99 | public void setResponseClazz(Class responseClazz) { 100 | mResponseClazz = responseClazz; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/request/PostRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: PostRequest.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年10月13日 下午7:18:22 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.request; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 13 | import com.luoxudong.app.asynchttp.ContentType; 14 | import com.luoxudong.app.asynchttp.builder.PostBuilder; 15 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 16 | import com.luoxudong.app.asynchttp.handler.JsonResponseHandler; 17 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 18 | import com.luoxudong.app.asynchttp.interceptor.JsonResponseInterceptor; 19 | 20 | import okhttp3.MediaType; 21 | import okhttp3.Request; 22 | import okhttp3.RequestBody; 23 | 24 | /** 25 | *
 26 |  * ClassName: PostRequest
 27 |  * Description:POST请求
 28 |  * Create by: 罗旭东
 29 |  * Date: 2016年10月13日 下午7:18:22
 30 |  * 
31 | */ 32 | public class PostRequest extends AsyncHttpRequest { 33 | private String mBody = null; 34 | private String mContentType = null; 35 | /** 返回数据拦截器 */ 36 | private JsonResponseInterceptor mResponseInterceptor = null; 37 | /** 返回的json对象类型 */ 38 | private Class mResponseClazz = null; 39 | 40 | public PostRequest(PostBuilder builder) { 41 | super(builder); 42 | } 43 | 44 | @Override 45 | public Request buildRequest(RequestCallable callable) { 46 | if (getContentType() == null) { 47 | setContentType(ContentType.text.getValue()); 48 | } 49 | 50 | if (getBody() == null) { 51 | setBody(""); 52 | } 53 | return mBuilder.post(RequestBody.create(MediaType.parse(getContentType()), getBody())).build(); 54 | } 55 | 56 | @Override 57 | public AsyncHttpTask build() { 58 | initRequest(); 59 | return new AsyncHttpTask(this); 60 | } 61 | 62 | @Override 63 | public ResponseHandler buildResponseHandler(RequestCallable callable) { 64 | return new JsonResponseHandler(getResponseClazz(), getResponseInterceptor(), callable); 65 | } 66 | 67 | 68 | public String getBody() { 69 | return mBody; 70 | } 71 | 72 | public void setBody(String body) { 73 | mBody = body; 74 | } 75 | 76 | public String getContentType() { 77 | return mContentType; 78 | } 79 | 80 | public void setContentType(String contentType) { 81 | mContentType = contentType; 82 | } 83 | 84 | public JsonResponseInterceptor getResponseInterceptor() { 85 | return mResponseInterceptor; 86 | } 87 | 88 | public Class getResponseClazz() { 89 | return mResponseClazz; 90 | } 91 | 92 | public void setResponseInterceptor(JsonResponseInterceptor responseInterceptor) { 93 | mResponseInterceptor = responseInterceptor; 94 | } 95 | 96 | public void setResponseClazz(Class responseClazz) { 97 | mResponseClazz = responseClazz; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/request/UploadFileRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: UploadFileRequest.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2016年11月23日 下午5:07:54 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.request; 11 | 12 | import com.luoxudong.app.asynchttp.AsyncHttpConst; 13 | import com.luoxudong.app.asynchttp.AsyncHttpTask; 14 | import com.luoxudong.app.asynchttp.ContentType; 15 | import com.luoxudong.app.asynchttp.builder.UploadFileBuilder; 16 | import com.luoxudong.app.asynchttp.callable.RequestCallable; 17 | import com.luoxudong.app.asynchttp.exception.AsyncHttpException; 18 | import com.luoxudong.app.asynchttp.exception.AsyncHttpExceptionCode; 19 | import com.luoxudong.app.asynchttp.handler.ResponseHandler; 20 | import com.luoxudong.app.asynchttp.handler.UploadFileResponseHandler; 21 | import com.luoxudong.app.asynchttp.model.FileWrapper; 22 | import com.luoxudong.app.asynchttp.utils.AsyncHttpLog; 23 | 24 | import java.io.IOException; 25 | import java.io.RandomAccessFile; 26 | import java.util.Map; 27 | 28 | import okhttp3.Headers; 29 | import okhttp3.MediaType; 30 | import okhttp3.MultipartBody; 31 | import okhttp3.Request; 32 | import okhttp3.RequestBody; 33 | import okio.BufferedSink; 34 | 35 | /** 36 | *
 37 |  * ClassName: UploadFileRequest
 38 |  * Description:上传文件
 39 |  * Create by: 罗旭东
 40 |  * Date: 2016年11月23日 下午5:07:54
 41 |  * 
42 | */ 43 | public class UploadFileRequest extends AsyncHttpRequest { 44 | private final String TAG = UploadFileRequest.class.getSimpleName(); 45 | 46 | private Map mFileMap = null; 47 | protected Map mFormMap = null; 48 | private UploadFileResponseHandler mHandler = null; 49 | 50 | public UploadFileRequest(UploadFileBuilder builder) { 51 | super(builder); 52 | } 53 | 54 | @Override 55 | public Request buildRequest(RequestCallable callable) { 56 | MultipartBody.Builder builder = new MultipartBody.Builder() 57 | .setType(MultipartBody.FORM); 58 | addParams(builder); 59 | addFiles(builder); 60 | 61 | 62 | return mBuilder.post(builder.build()).build(); 63 | } 64 | 65 | @Override 66 | public AsyncHttpTask build() { 67 | initRequest(); 68 | return new AsyncHttpTask(this); 69 | } 70 | 71 | @Override 72 | public ResponseHandler buildResponseHandler(RequestCallable callable) { 73 | mHandler = new UploadFileResponseHandler(callable); 74 | return mHandler; 75 | } 76 | 77 | private void addParams(MultipartBody.Builder builder) { 78 | if (mFormMap != null && !mFormMap.isEmpty()) { 79 | for (String key : mFormMap.keySet()) { 80 | builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + key + "\""), RequestBody.create(null, mFormMap.get(key))); 81 | } 82 | } 83 | } 84 | 85 | private void addFiles(MultipartBody.Builder builder) { 86 | if (mFileMap != null) { 87 | for (String key : mFileMap.keySet()) { 88 | RequestBody fileBody = null; 89 | final FileWrapper fileWrapper = mFileMap.get(key); 90 | 91 | fileBody = new UploadFileRequestBody(fileWrapper); 92 | builder.addFormDataPart(key, fileWrapper.getFile().getName(), fileBody); 93 | } 94 | } 95 | } 96 | 97 | public void setFileMap(Map fileMap) { 98 | mFileMap = fileMap; 99 | } 100 | 101 | public void setFormMap(Map formMap) { 102 | mFormMap = formMap; 103 | } 104 | 105 | class UploadFileRequestBody extends RequestBody { 106 | private FileWrapper mFileWrapper = null; 107 | private long mOffset = 0; 108 | private long mByteCount = 0; 109 | 110 | public UploadFileRequestBody(FileWrapper fileWrapper) { 111 | mFileWrapper = fileWrapper; 112 | mOffset = mFileWrapper.getStartPos(); 113 | mByteCount = mFileWrapper.getBlockSize(); 114 | 115 | if (mOffset == 0 && mByteCount == 0) {//完整上传 116 | mByteCount = mFileWrapper.getFile().length(); 117 | } 118 | } 119 | 120 | @Override 121 | public MediaType contentType() { 122 | return MediaType.parse(ContentType.octetStream.getValue()); 123 | } 124 | 125 | @Override 126 | public long contentLength() throws IOException { 127 | return mByteCount; 128 | } 129 | 130 | @Override 131 | public void writeTo(BufferedSink sink) throws IOException { 132 | mHandler.sendStartTransferMessage(); 133 | if (mOffset < 0 || (mOffset > mFileWrapper.getFile().length() - 1)) { 134 | mHandler.sendFailureMessage(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), new AsyncHttpException("startPos错误!")); 135 | return; 136 | } 137 | 138 | if (mOffset + mByteCount > mFileWrapper.getFile().length()) { 139 | mHandler.sendFailureMessage(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), new AsyncHttpException("blockSize错误!")); 140 | return; 141 | } 142 | 143 | RandomAccessFile rf = new RandomAccessFile(mFileWrapper.getFile(), "r"); 144 | rf.seek(mOffset); 145 | 146 | byte[] buffer = new byte[20 * 1024]; 147 | long length = 0; 148 | try { 149 | long timeStamp = System.currentTimeMillis(); 150 | for (long count = 0; count < mByteCount;) { 151 | length = rf.read(buffer); 152 | if (length < 0){ 153 | break; 154 | } 155 | if (count + length > mByteCount) { 156 | length = mByteCount - count; 157 | } 158 | 159 | sink.write(buffer, 0, (int)length); 160 | count += length; 161 | 162 | if ((System.currentTimeMillis() - timeStamp) >= AsyncHttpConst.TRANSFER_REFRESH_TIME_INTERVAL) { 163 | AsyncHttpLog.d(TAG, "上传进度:" + count + "/" + mByteCount); 164 | mHandler.sendTransferingMessage(mFileWrapper.getFile().getName(), mByteCount, count); 165 | timeStamp = System.currentTimeMillis();// 每一秒调用一次 166 | } 167 | } 168 | 169 | mHandler.sendTransferSucMessage(mFileWrapper.getFile().getName()); 170 | } catch (Exception e) { 171 | mHandler.sendFailureMessage(AsyncHttpExceptionCode.defaultExceptionCode.getErrorCode(), e); 172 | } 173 | 174 | sink.flush(); 175 | rf.close(); 176 | } 177 | 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/main/src/main/java/com/luoxudong/app/asynchttp/utils/AsyncHttpLog.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Title: AsyncHttpLog.java 3 | * Description: 4 | * Copyright: Copyright (c) 2013-2015 luoxudong.com 5 | * Company: 个人 6 | * Author: 罗旭东 (hi@luoxudong.com) 7 | * Date: 2015年7月13日 下午2:32:51 8 | * Version: 1.0 9 | */ 10 | package com.luoxudong.app.asynchttp.utils; 11 | 12 | import android.util.Log; 13 | 14 | /** 15 | * ClassName: AsyncHttpLog 16 | * Description:日志打印工具类 17 | * Create by: 罗旭东 18 | * Date: 2015年7月13日 下午2:32:51 19 | */ 20 | public class AsyncHttpLog { 21 | private static boolean sIsLogEnable = false; 22 | 23 | /** 24 | * 使日志有效 25 | */ 26 | public static void enableLog() { 27 | sIsLogEnable = true; 28 | } 29 | 30 | /** 31 | * 使日志无效 32 | */ 33 | public static void disableLog() { 34 | sIsLogEnable = false; 35 | } 36 | 37 | public static void v(String tag, String msg) { 38 | if (sIsLogEnable) { 39 | Log.v(tag, getStackTraceMsg() + ": " + msg); 40 | } 41 | } 42 | 43 | public static void d(String tag, String msg) { 44 | if (sIsLogEnable) { 45 | Log.d(tag, getStackTraceMsg() + ": " + msg); 46 | } 47 | } 48 | 49 | public static void i(String tag, String msg) { 50 | if (sIsLogEnable) { 51 | Log.i(tag, getStackTraceMsg() + ": " + msg); 52 | } 53 | } 54 | 55 | public static void w(String tag, String msg) { 56 | if (sIsLogEnable) { 57 | Log.w(tag, getStackTraceMsg() + ": " + msg); 58 | } 59 | } 60 | 61 | public static void e(String tag, String msg) { 62 | if (sIsLogEnable) { 63 | Log.e(tag, getStackTraceMsg() + ": " + msg); 64 | } 65 | } 66 | 67 | /** 68 | * 定位代码位置,只能在该类内部使用 69 | */ 70 | private static String getStackTraceMsg() { 71 | String fileInfo = ""; 72 | StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); 73 | if (stackTraceElements != null && stackTraceElements.length > 4){ 74 | StackTraceElement stackTrace = stackTraceElements[4]; 75 | fileInfo = stackTrace.getFileName() + "(" + stackTrace.getLineNumber() + ") " + stackTrace.getMethodName(); 76 | } 77 | return fileInfo; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AsyncHttpHelp 3 | 4 | -------------------------------------------------------------------------------- /src/main/src/test/java/com/luoxudong/app/asynchttp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.luoxudong.app.asynchttp; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } --------------------------------------------------------------------------------