├── assert
├── README.md
├── GIF.gif
├── get.png
├── main.png
├── post.png
├── download1.png
├── Android技术交流群群二维码.png
└── mainanddownload.png
├── sample
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values
│ │ │ ├── dimens.xml
│ │ │ ├── colors.xml
│ │ │ ├── styles.xml
│ │ │ └── strings.xml
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ └── layout
│ │ │ ├── layout_download.xml
│ │ │ ├── main_item.xml
│ │ │ ├── post_main.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── get_main.xml
│ │ │ └── download_item.xml
│ │ ├── java
│ │ └── com
│ │ │ └── yang
│ │ │ └── demo
│ │ │ ├── activity
│ │ │ ├── UploadActivity.java
│ │ │ ├── GetActivity.java
│ │ │ ├── PostActivity.java
│ │ │ ├── RxGetActivity.java
│ │ │ ├── DownloadActivity.java
│ │ │ └── RxPostActivity.java
│ │ │ ├── MainApplication.java
│ │ │ ├── entity
│ │ │ ├── PostEntity.java
│ │ │ ├── MainEntity.java
│ │ │ └── DownloadEntity.java
│ │ │ ├── MainActivity.java
│ │ │ └── adapter
│ │ │ ├── MainAdapter.java
│ │ │ └── DownloadAdapter.java
│ │ └── AndroidManifest.xml
├── proguard-rules.pro
└── build.gradle
├── easy-http-library-rx
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── yang
│ │ │ │ └── easyhttprx
│ │ │ │ ├── converter
│ │ │ │ ├── RxEasyConverter.java
│ │ │ │ ├── RxEasyStringConverter.java
│ │ │ │ ├── RxEasyJsonConverter.java
│ │ │ │ └── RxEasyCustomConverter.java
│ │ │ │ ├── RxEasyHttp.java
│ │ │ │ └── manager
│ │ │ │ └── RxEasyHttpManager.java
│ │ └── AndroidManifest.xml
│ └── test
│ │ └── java
│ │ └── com
│ │ └── yang
│ │ └── easyhttprx
│ │ └── ExampleUnitTest.java
├── proguard-rules.pro
└── build.gradle
├── easy-http-library
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── yang
│ │ │ │ └── easyhttp
│ │ │ │ ├── utils
│ │ │ │ ├── EasyConstants.java
│ │ │ │ ├── Exceptions.java
│ │ │ │ ├── EasyIOUtils.java
│ │ │ │ ├── EasyFileUtils.java
│ │ │ │ ├── EasyHttpUtils.java
│ │ │ │ └── EasyNetworkUtils.java
│ │ │ │ ├── converter
│ │ │ │ ├── EasyResponseConverter.java
│ │ │ │ └── EasyResponseJsonConverter.java
│ │ │ │ ├── cache
│ │ │ │ ├── EasyCacheTime.java
│ │ │ │ ├── EasyCacheType.java
│ │ │ │ └── EasyCacheDir.java
│ │ │ │ ├── callback
│ │ │ │ ├── EasyCallback.java
│ │ │ │ ├── EasyStringCallback.java
│ │ │ │ ├── EasyJsonCallback.java
│ │ │ │ └── EasyCustomCallback.java
│ │ │ │ ├── Interceptor
│ │ │ │ ├── EasyUserAgentInterceptor.java
│ │ │ │ ├── EasyLoggingInterceptor.java
│ │ │ │ ├── EasyHeaderInterceptor.java
│ │ │ │ └── EasyCacheInterceptor.java
│ │ │ │ ├── download
│ │ │ │ ├── EasyTaskStatus.java
│ │ │ │ ├── EasyDownloadTaskListener.java
│ │ │ │ ├── EasySimpleDownloadTaskListener.java
│ │ │ │ ├── EasyTaskEntity.java
│ │ │ │ ├── EasySimpleDownloadManager.java
│ │ │ │ ├── EasyDownloadManager.java
│ │ │ │ ├── EasySimpleDownloadTask.java
│ │ │ │ └── EasyDownloadTask.java
│ │ │ │ ├── request
│ │ │ │ └── EasyRequestParams.java
│ │ │ │ ├── db
│ │ │ │ └── EasyDaoManager.java
│ │ │ │ ├── config
│ │ │ │ └── EasyHttpConfig.java
│ │ │ │ ├── EasyHttpClient.java
│ │ │ │ └── manager
│ │ │ │ └── EasyHttpClientManager.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── yang
│ │ │ └── easyhttp
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── yang
│ │ └── easyhttp
│ │ └── ApplicationTest.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── gradlew.bat
├── gradlew
├── README.md
└── LICENSE
/assert/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/easy-http-library-rx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/easy-http-library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/assert/GIF.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/assert/GIF.gif
--------------------------------------------------------------------------------
/assert/get.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/assert/get.png
--------------------------------------------------------------------------------
/assert/main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/assert/main.png
--------------------------------------------------------------------------------
/assert/post.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/assert/post.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':sample', ':easy-http-library', ':easy-http-library-rx'
2 |
--------------------------------------------------------------------------------
/assert/download1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/assert/download1.png
--------------------------------------------------------------------------------
/assert/Android技术交流群群二维码.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/assert/Android技术交流群群二维码.png
--------------------------------------------------------------------------------
/assert/mainanddownload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/assert/mainanddownload.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/easy-http-library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | easy-http-library
3 |
4 |
--------------------------------------------------------------------------------
/easy-http-library-rx/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | easy-http-library-rx
3 |
4 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LaurenceYang/EasyHttp/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/utils/EasyConstants.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.utils;
2 |
3 | /**
4 | * Created by yangy on 2017/2/16.
5 | */
6 | public class EasyConstants {
7 | public static final int MAX_THREAD_COUNT = 16;
8 | }
9 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/converter/EasyResponseConverter.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.converter;
2 |
3 | /**
4 | * Created by yangy on 2017/2/15.
5 | */
6 | public interface EasyResponseConverter {
7 | T convert(String body);
8 | }
9 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/activity/UploadActivity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.activity;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 |
5 | /**
6 | * Created by yangyang on 2017/2/17.
7 | */
8 | public class UploadActivity extends AppCompatActivity {
9 | }
10 |
--------------------------------------------------------------------------------
/easy-http-library-rx/src/main/java/com/yang/easyhttprx/converter/RxEasyConverter.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttprx.converter;
2 |
3 | /**
4 | * Created by yangyang on 2017/3/15.
5 | */
6 | public interface RxEasyConverter {
7 | T convert(String body) throws Exception;
8 |
9 | void doNothing();
10 | }
11 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/utils/Exceptions.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.utils;
2 |
3 | public class Exceptions
4 | {
5 | public static void illegalArgument(String msg, Object... params)
6 | {
7 | throw new IllegalArgumentException(String.format(msg, params));
8 | }
9 |
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/cache/EasyCacheTime.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.cache;
2 |
3 | /**
4 | * Created by yangy on 2017/2/15.
5 | */
6 | public class EasyCacheTime {
7 | public static final int CACHE_TIME_SHORT = 30;//s
8 | public static final int CACHE_TIME_MID = 3600;//s
9 | public static final int CACHE_TIME_LONG = 21600;//s
10 | }
11 |
--------------------------------------------------------------------------------
/easy-http-library-rx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/sample/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/easy-http-library/src/test/java/com/yang/easyhttp/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/easy-http-library-rx/src/main/java/com/yang/easyhttprx/converter/RxEasyStringConverter.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttprx.converter;
2 |
3 | /**
4 | * Created by yangyang on 2017/3/15.
5 | */
6 | public class RxEasyStringConverter implements RxEasyConverter {
7 | @Override
8 | public String convert(String body) throws Exception {
9 | return body;
10 | }
11 |
12 | @Override
13 | public void doNothing() {
14 |
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/cache/EasyCacheType.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.cache;
2 |
3 | /**
4 | * Created by yangy on 2017/2/15.
5 | */
6 | public class EasyCacheType {
7 | public static final int CACHE_TYPE_NO_SETTING = -1;
8 | public static final int CACHE_TYPE_DEFAULT = 0;
9 | public static final int CACHE_TYPE_SHORT = 1;
10 | public static final int CACHE_TYPE_MID = 2;
11 | public static final int CACHE_TYPE_LONG = 3;
12 | }
13 |
--------------------------------------------------------------------------------
/easy-http-library/src/androidTest/java/com/yang/easyhttp/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/callback/EasyCallback.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.callback;
2 |
3 | /**
4 | * Created by yangy on 2016/10/14.
5 | */
6 |
7 | public interface EasyCallback {
8 | // UI线程.
9 | void onStart();
10 |
11 | // UI线程.
12 | void onFinish();
13 |
14 | // UI线程.
15 | void onSuccess(T content);
16 |
17 | // UI线程.
18 | void onFailure(Throwable error, String content);
19 |
20 | // 子线程.
21 | T convert(String body) throws Exception;
22 | }
23 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/callback/EasyStringCallback.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.callback;
2 |
3 | /**
4 | * Created by yangyang on 2017/2/20.
5 | */
6 | public abstract class EasyStringCallback implements EasyCallback {
7 | @Override
8 | public void onStart() {
9 |
10 | }
11 |
12 | @Override
13 | public void onFinish() {
14 |
15 | }
16 |
17 | @Override
18 | public String convert(String body) {
19 | return body;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/easy-http-library-rx/src/test/java/com/yang/easyhttprx/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttprx;
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 | }
--------------------------------------------------------------------------------
/easy-http-library-rx/src/main/java/com/yang/easyhttprx/converter/RxEasyJsonConverter.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttprx.converter;
2 |
3 | import org.json.JSONObject;
4 |
5 | /**
6 | * Created by yangyang on 2017/3/15.
7 | */
8 | public class RxEasyJsonConverter implements RxEasyConverter {
9 | @Override
10 | public JSONObject convert(String body) throws Exception {
11 | return new JSONObject(body);
12 | }
13 |
14 | @Override
15 | public void doNothing() {
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/cache/EasyCacheDir.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.cache;
2 |
3 | import android.os.Environment;
4 |
5 | /**
6 | * Created by yangy on 2017/2/16.
7 | */
8 | public class EasyCacheDir {
9 | public static final String SD_PATH = Environment.getExternalStorageDirectory().getPath() + "/";
10 | public static final String CACHE_SHORT_DIR = "/cache/http.cache.1";
11 | public static final String CACHE_MID_DIR = "/cache/http.cache.2";
12 | public static final String CACHE_LONG_DIR = "/cache/http.cache.3";
13 | }
14 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo;
2 |
3 | import android.app.Application;
4 |
5 | import com.yang.easyhttp.EasyHttpClient;
6 |
7 | /**
8 | * Created by yangyang on 2017/2/17.
9 | */
10 | public class MainApplication extends Application {
11 |
12 | @Override
13 | public void onCreate() {
14 | super.onCreate();
15 |
16 | // 初始化HttpClient.
17 | EasyHttpClient.init(this);
18 |
19 | // 初始化下载环境.
20 | EasyHttpClient.initDownloadEnvironment(2);
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/entity/PostEntity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.entity;
2 |
3 | /**
4 | * Created by yangyang on 2017/3/15.
5 | */
6 | public class PostEntity {
7 | int status;
8 | String message;
9 |
10 | public int getStatus() {
11 | return status;
12 | }
13 |
14 | public void setStatus(int status) {
15 | this.status = status;
16 | }
17 |
18 | public String getMessage() {
19 | return message;
20 | }
21 |
22 | public void setMessage(String message) {
23 | this.message = message;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/callback/EasyJsonCallback.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.callback;
2 |
3 | import org.json.JSONException;
4 | import org.json.JSONObject;
5 |
6 | /**
7 | * Created by yangy on 2017/2/22.
8 | */
9 | public abstract class EasyJsonCallback implements EasyCallback {
10 | @Override
11 | public void onStart() {
12 |
13 | }
14 |
15 | @Override
16 | public void onFinish() {
17 |
18 | }
19 |
20 | @Override
21 | public JSONObject convert(String body) throws JSONException {
22 | return new JSONObject(body);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | EasyHttp
3 | 开始
4 | 暂停
5 | 等待
6 | 取消
7 | 继续
8 | 删除
9 | 失败
10 | 重试
11 | 连接中
12 | 等待中
13 | 请求异常
14 | 存储异常
15 |
16 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/layout_download.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/converter/EasyResponseJsonConverter.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.converter;
2 |
3 | import com.google.gson.Gson;
4 |
5 | import java.lang.reflect.ParameterizedType;
6 | import java.lang.reflect.Type;
7 |
8 | /**
9 | * Created by yangy on 2017/2/15.
10 | */
11 | public class EasyResponseJsonConverter implements EasyResponseConverter {
12 |
13 | @Override
14 | public T convert(String body) {
15 | Gson gson = new Gson(); //TODO:
16 | Type t = getClass().getGenericSuperclass();
17 | Type targ = ((ParameterizedType) t).getActualTypeArguments()[0];
18 | return gson.fromJson(body, targ);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # Intellij
36 | *.iml
37 | .idea
38 |
39 | # Keystore files
40 | *.jks
41 |
42 | # OSX files
43 | .DS_Store
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/utils/EasyIOUtils.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.utils;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 |
6 | /**
7 | * Created by yuan on 07/12/2016.
8 | */
9 |
10 | public class EasyIOUtils {
11 |
12 | /**
13 | * 关闭流
14 | * @param closeables io
15 | */
16 | public static void close(Closeable... closeables) {
17 | for (Closeable io : closeables) {
18 | if (io != null) {
19 | try {
20 | io.close();
21 | } catch (IOException e) {
22 | e.printStackTrace();
23 | }
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/sample/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 /Users/yangyang/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 |
--------------------------------------------------------------------------------
/easy-http-library/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 /Users/yangyang/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 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/entity/MainEntity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.entity;
2 |
3 | /**
4 | * Created by yangyang on 2017/2/17.
5 | */
6 | public class MainEntity {
7 | private String title;
8 | private String desc;
9 | private int type;
10 |
11 | public String getTitle() {
12 | return title;
13 | }
14 |
15 | public void setTitle(String title) {
16 | this.title = title;
17 | }
18 |
19 | public String getDesc() {
20 | return desc;
21 | }
22 |
23 | public void setDesc(String desc) {
24 | this.desc = desc;
25 | }
26 |
27 | public int getType() {
28 | return type;
29 | }
30 |
31 | public void setType(int type) {
32 | this.type = type;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/entity/DownloadEntity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.entity;
2 |
3 | /**
4 | * Created by yangyang on 2017/2/17.
5 | */
6 | public class DownloadEntity {
7 | private String title;
8 | private String url;
9 | private String hashCode;
10 |
11 | public String getTitle() {
12 | return title;
13 | }
14 |
15 | public void setTitle(String title) {
16 | this.title = title;
17 | }
18 |
19 | public String getUrl() {
20 | return url;
21 | }
22 |
23 | public void setUrl(String url) {
24 | this.url = url;
25 | }
26 |
27 | public String getHashCode() {
28 | return hashCode;
29 | }
30 |
31 | public void setHashCode(String hashCode) {
32 | this.hashCode = hashCode;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/main_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
15 |
21 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/post_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
22 |
23 |
--------------------------------------------------------------------------------
/easy-http-library-rx/src/main/java/com/yang/easyhttprx/converter/RxEasyCustomConverter.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttprx.converter;
2 |
3 | import com.google.gson.Gson;
4 | import com.yang.easyhttp.manager.EasyHttpClientManager;
5 |
6 | import java.lang.reflect.ParameterizedType;
7 | import java.lang.reflect.Type;
8 |
9 | /**
10 | * Created by yangyang on 2017/3/15.
11 | */
12 | public abstract class RxEasyCustomConverter implements RxEasyConverter {
13 |
14 | @Override
15 | public T convert(String body) throws Exception {
16 | Class clazz = this.getClass();
17 | Type superClassType = clazz.getGenericSuperclass();
18 | Type tArg = ((ParameterizedType) superClassType).getActualTypeArguments()[0];
19 | Gson gson = EasyHttpClientManager.getInstance().getGson();
20 | return gson.fromJson(body, tArg);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/callback/EasyCustomCallback.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.callback;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.JsonSyntaxException;
5 | import com.yang.easyhttp.manager.EasyHttpClientManager;
6 |
7 | import java.lang.reflect.ParameterizedType;
8 | import java.lang.reflect.Type;
9 |
10 | /**
11 | * Created by yangy on 2017/2/15.
12 | */
13 | public abstract class EasyCustomCallback implements EasyCallback {
14 | @Override
15 | public void onStart() {
16 |
17 | }
18 |
19 | @Override
20 | public void onFinish() {
21 |
22 | }
23 |
24 | @Override
25 | public T convert(String body) throws JsonSyntaxException {
26 | Type superClassType = getClass().getGenericSuperclass();
27 | Type tArg = ((ParameterizedType) superClassType).getActualTypeArguments()[0];
28 | Gson gson = EasyHttpClientManager.getInstance().getGson();
29 | return gson.fromJson(body, tArg);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/Interceptor/EasyUserAgentInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.Interceptor;
2 |
3 | import java.io.IOException;
4 |
5 | import okhttp3.Interceptor;
6 | import okhttp3.Request;
7 | import okhttp3.Response;
8 |
9 | /**
10 | * Created by yangy on 2017/2/22.
11 | */
12 | public class EasyUserAgentInterceptor implements Interceptor {
13 | private static final String USER_AGENT_HEADER_NAME = "User-Agent";
14 | private String mUserAgent;
15 |
16 | public EasyUserAgentInterceptor(String userAgent) {
17 | mUserAgent = userAgent;
18 | }
19 |
20 | @Override
21 | public Response intercept(Chain chain) throws IOException {
22 | final Request originalRequest = chain.request();
23 | final Request requestWithUserAgent = originalRequest.newBuilder()
24 | .removeHeader(USER_AGENT_HEADER_NAME)
25 | .addHeader(USER_AGENT_HEADER_NAME, mUserAgent)
26 | .build();
27 |
28 | return chain.proceed(requestWithUserAgent);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/get_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
21 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/Interceptor/EasyLoggingInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.Interceptor;
2 |
3 | import android.util.Log;
4 |
5 | import java.io.IOException;
6 |
7 | import okhttp3.Interceptor;
8 | import okhttp3.Request;
9 | import okhttp3.Response;
10 |
11 | /**
12 | * Created by yangy on 2017/2/15.
13 | */
14 | public final class EasyLoggingInterceptor implements Interceptor {
15 | private final static String TAG = "LoggingInterceptor";
16 |
17 | @Override
18 | public Response intercept(Chain chain) throws IOException {
19 | Request request = chain.request();
20 |
21 | long t1 = System.nanoTime();
22 | Log.d(TAG, String.format("Sending request %s on %s%n%s",
23 | request.url(), chain.connection(), request.headers()));
24 |
25 | Response response = chain.proceed(request);
26 |
27 | long t2 = System.nanoTime();
28 |
29 | Log.d(TAG, String.format("Received response for %s in %.1fms%n%s",
30 | response.request().url(), (t2 - t1) / 1e6d, response.headers()));
31 |
32 | return response;
33 | }
34 | }
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/download/EasyTaskStatus.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.download;
2 |
3 | /**
4 | * Created by yangy on 2017/2/16.
5 | */
6 | public class EasyTaskStatus {
7 | public static final int TASK_STATUS_INIT = 0;
8 | public static final int TASK_STATUS_QUEUE = TASK_STATUS_INIT + 1;
9 | public static final int TASK_STATUS_CONNECTING = TASK_STATUS_QUEUE + 1;
10 | public static final int TASK_STATUS_DOWNLOADING = TASK_STATUS_CONNECTING + 1;
11 | public static final int TASK_STATUS_PAUSE = TASK_STATUS_DOWNLOADING + 1;
12 | public static final int TASK_STATUS_CANCEL = TASK_STATUS_PAUSE + 1;
13 | public static final int TASK_STATUS_REQUEST_ERROR = TASK_STATUS_CANCEL + 1;
14 | public static final int TASK_STATUS_LINK_FAILURE_ERROR = TASK_STATUS_REQUEST_ERROR + 1;
15 | public static final int TASK_STATUS_STORAGE_ERROR = TASK_STATUS_LINK_FAILURE_ERROR + 1;
16 | public static final int TASK_STATUS_FINISH = TASK_STATUS_STORAGE_ERROR + 1;
17 | public static final int TASK_STATUS_RESET_STATUS = TASK_STATUS_FINISH + 1;
18 | }
19 |
--------------------------------------------------------------------------------
/easy-http-library-rx/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 D:\00_work\00_Android_Dev\adt-bundle-windows-x86_64-20140702\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 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/download/EasyDownloadTaskListener.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.download;
2 |
3 | /**
4 | * Created by yangy on 2017/2/16.
5 | */
6 | public interface EasyDownloadTaskListener {
7 | /**
8 | * queue
9 | * @param downloadTask
10 | */
11 | void onQueue(EasyDownloadTask downloadTask);
12 |
13 | /**
14 | * connecting
15 | * @param downloadTask
16 | */
17 | void onConnecting(EasyDownloadTask downloadTask);
18 |
19 | /**
20 | * downloading
21 | * @param downloadTask
22 | */
23 | void onDownloading(EasyDownloadTask downloadTask);
24 |
25 | /**
26 | * pauseTask
27 | * @param downloadTask
28 | */
29 | void onPause(EasyDownloadTask downloadTask);
30 |
31 | /**
32 | * cancel
33 | * @param downloadTask
34 | */
35 | void onCancel(EasyDownloadTask downloadTask);
36 |
37 | /**
38 | * success
39 | * @param downloadTask
40 | */
41 | void onFinish(EasyDownloadTask downloadTask);
42 |
43 | /**
44 | * failure
45 | * @param downloadTask
46 | */
47 | void onError(EasyDownloadTask downloadTask, int code);
48 | }
49 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/download/EasySimpleDownloadTaskListener.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.download;
2 |
3 | /**
4 | * Created by yangy on 2017/2/16.
5 | */
6 | public interface EasySimpleDownloadTaskListener {
7 | /**
8 | * queue
9 | * @param downloadTask
10 | */
11 | void onQueue(EasySimpleDownloadTask downloadTask);
12 |
13 | /**
14 | * connecting
15 | * @param downloadTask
16 | */
17 | void onConnecting(EasySimpleDownloadTask downloadTask);
18 |
19 | /**
20 | * downloading
21 | * @param downloadTask
22 | */
23 | void onDownloading(EasySimpleDownloadTask downloadTask);
24 |
25 | /**
26 | * pauseTask
27 | * @param downloadTask
28 | */
29 | void onPause(EasySimpleDownloadTask downloadTask);
30 |
31 | /**
32 | * cancel
33 | * @param downloadTask
34 | */
35 | void onCancel(EasySimpleDownloadTask downloadTask);
36 |
37 | /**
38 | * success
39 | * @param downloadTask
40 | */
41 | void onFinish(EasySimpleDownloadTask downloadTask);
42 |
43 | /**
44 | * failure
45 | * @param downloadTask
46 | */
47 | void onError(EasySimpleDownloadTask downloadTask, int code);
48 | }
49 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/Interceptor/EasyHeaderInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.Interceptor;
2 |
3 | import java.io.IOException;
4 | import java.util.concurrent.ConcurrentHashMap;
5 |
6 | import okhttp3.Interceptor;
7 | import okhttp3.Request;
8 | import okhttp3.Response;
9 |
10 | /**
11 | * Created by yangyang on 2017/6/14.
12 | */
13 |
14 | public class EasyHeaderInterceptor implements Interceptor {
15 | ConcurrentHashMap mHeaders;
16 |
17 | public EasyHeaderInterceptor(ConcurrentHashMap headers) {
18 | this.mHeaders = headers;
19 | }
20 |
21 | @Override
22 | public Response intercept(Chain chain) throws IOException {
23 | final Request originalRequest = chain.request();
24 |
25 | Request.Builder builder = originalRequest.newBuilder();
26 |
27 | if (mHeaders != null) {
28 | for (ConcurrentHashMap.Entry entry : mHeaders.entrySet()) {
29 | builder.addHeader(entry.getKey(), entry.getValue());
30 | }
31 | }
32 |
33 | return chain.proceed(builder.build());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/utils/EasyFileUtils.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.utils;
2 |
3 | import android.content.Context;
4 | import android.os.Environment;
5 | import android.text.TextUtils;
6 | import android.util.Log;
7 |
8 | import com.yang.easyhttp.manager.EasyHttpClientManager;
9 |
10 | import java.io.File;
11 |
12 | /**
13 | * Created by yangy on 2017/2/16.
14 | */
15 | public class EasyFileUtils {
16 | public static String getFileNameFromUrl(String url) {
17 | if (!TextUtils.isEmpty(url)) {
18 | return url.substring(url.lastIndexOf("/") + 1);
19 | }
20 |
21 | return System.currentTimeMillis() + "";
22 | }
23 |
24 | public static String getDefaultFilePath(Context context) {
25 | String filePath = Environment.getExternalStorageDirectory().getAbsolutePath()
26 | + "/"
27 | + context.getPackageName()
28 | + "/download/";
29 | File file = new File(filePath);
30 | if (!file.exists()) {
31 | boolean createDir = file.mkdirs();
32 | if (createDir) {
33 | if (EasyHttpClientManager.getInstance().isDebug()) {
34 | Log.d("EasyDownloadTask", "create file dir success");;
35 | }
36 | }
37 | }
38 | return filePath;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/easy-http-library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 | apply plugin: 'org.greenrobot.greendao'
4 |
5 | android {
6 | compileSdkVersion 23
7 | buildToolsVersion "23.0.2"
8 |
9 | defaultConfig {
10 | minSdkVersion 9
11 | targetSdkVersion 23
12 | versionCode 1
13 | versionName "1.0"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 | lintOptions {
22 | abortOnError false
23 | }
24 | }
25 |
26 | repositories {
27 | jcenter()
28 | }
29 |
30 | publish {
31 | userOrg = 'laurenceyanger'
32 | groupId = 'com.yang.easyhttp'
33 | artifactId = 'easyhttp'
34 | uploadName = 'easyhttp-laurenceyanger'
35 | publishVersion = '0.8.0'
36 | desc = 'network module for android,based on okhttp'
37 | website = 'https://github.com/LaurenceYang/EasyHttp'
38 | }
39 |
40 | dependencies {
41 | compile fileTree(dir: 'libs', include: ['*.jar'])
42 | testCompile 'junit:junit:4.12'
43 |
44 | compile 'com.squareup.okhttp3:okhttp:3.6.0'
45 | compile 'com.google.code.gson:gson:2.7'
46 | compile 'org.greenrobot:greendao:3.2.0'
47 | }
48 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'android-apt'
3 |
4 | android {
5 | compileSdkVersion 23
6 | buildToolsVersion "23.0.2"
7 |
8 | defaultConfig {
9 | applicationId "com.yang.demo"
10 | minSdkVersion 9
11 | targetSdkVersion 23
12 | versionCode 1
13 | versionName "1.0"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 |
22 | lintOptions {
23 | abortOnError false
24 | }
25 | }
26 | repositories {
27 | jcenter()
28 | }
29 | repositories {
30 | maven {
31 | url "http://dl.bintray.com/laurenceyanger/maven"
32 | }
33 | }
34 |
35 | dependencies {
36 | compile fileTree(dir: 'libs', include: ['*.jar'])
37 | testCompile 'junit:junit:4.12'
38 | // compile project(':easy-http-library')
39 | // compile project(':easy-http-library-rx')
40 | compile 'com.yang.easyhttp:easyhttp:0.8.0'
41 | compile 'com.yang.rxeasyhttp:rxeasyhttp:0.8.0'
42 |
43 | compile 'com.android.support:appcompat-v7:23.0.0'
44 | compile 'com.android.support:recyclerview-v7:23.0.0'
45 |
46 | compile 'com.jakewharton:butterknife:8.1.0'
47 | apt 'com.jakewharton:butterknife-compiler:8.1.0'
48 | }
49 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/download_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
15 |
23 |
24 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/easy-http-library-rx/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | android {
5 | compileSdkVersion 23
6 | buildToolsVersion "23.0.2"
7 |
8 | defaultConfig {
9 | minSdkVersion 9
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
15 | }
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 | lintOptions {
23 | abortOnError false
24 | }
25 | }
26 |
27 | publish {
28 | userOrg = 'laurenceyanger'
29 | groupId = 'com.yang.rxeasyhttp'
30 | artifactId = 'rxeasyhttp'
31 | publishVersion = '0.8.0'
32 | desc = 'rxjava support for easyhttp'
33 | website = 'https://github.com/LaurenceYang/EasyHttp'
34 | }
35 |
36 | dependencies {
37 | compile fileTree(dir: 'libs', include: ['*.jar'])
38 | testCompile 'junit:junit:4.12'
39 | compile project(":easy-http-library")
40 |
41 | compile 'io.reactivex.rxjava2:rxjava:2.0.7'
42 | compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
43 | compile 'org.reactivestreams:reactive-streams:1.0.0'
44 |
45 | compile 'com.android.support:support-annotations:23.3.0'
46 | }
47 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/request/EasyRequestParams.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.request;
2 |
3 | import java.util.concurrent.ConcurrentHashMap;
4 |
5 | public class EasyRequestParams {
6 | private ConcurrentHashMap mRequestParams = new ConcurrentHashMap<>();
7 | private ConcurrentHashMap mRequestHeaders = new ConcurrentHashMap<>();
8 |
9 |
10 | public void put(String key, String value) {
11 | if (key != null && value != null) {
12 | mRequestParams.put(key, value);
13 | }
14 | }
15 |
16 | public ConcurrentHashMap getRequestParams() {
17 | return mRequestParams;
18 | }
19 |
20 | public void addHeader(String key, String value) {
21 | if (key != null && value != null) {
22 | mRequestHeaders.put(key, value);
23 | }
24 | }
25 |
26 | public ConcurrentHashMap getRequestHeaders() {
27 | return mRequestHeaders;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | StringBuilder result = new StringBuilder();
33 | for (ConcurrentHashMap.Entry entry : mRequestParams.entrySet()) {
34 | if (result.length() > 0)
35 | result.append("&");
36 |
37 | result.append(entry.getKey());
38 | result.append("=");
39 | result.append(entry.getValue());
40 | }
41 | return result.toString();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/db/EasyDaoManager.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.db;
2 |
3 | import com.yang.easyhttp.download.EasyDownloadManager;
4 | import com.yang.easyhttp.download.EasyTaskEntity;
5 | import com.yang.easyhttp.download.EasyTaskEntityDao;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by yangy on 2017/2/16.
11 | */
12 | public class EasyDaoManager {
13 | private static EasyDaoManager mInstance;
14 |
15 | private EasyDaoManager() {
16 | }
17 |
18 | public static EasyDaoManager instance() {
19 | synchronized (EasyDaoManager.class) {
20 | if (mInstance == null) {
21 | mInstance = new EasyDaoManager();
22 | }
23 | }
24 | return mInstance;
25 | }
26 |
27 | public void insertOrReplace(EasyTaskEntity entity) {
28 | EasyDownloadManager.getInstance().getDaoSession().insertOrReplace(entity);
29 | }
30 |
31 | public EasyTaskEntity queryWithId(String taskId) {
32 | return EasyDownloadManager
33 | .getInstance()
34 | .getDaoSession()
35 | .getEasyTaskEntityDao()
36 | .queryBuilder()
37 | .where(EasyTaskEntityDao.Properties.TaskId.eq(taskId))
38 | .unique();
39 | }
40 |
41 | public List queryAll() {
42 | return EasyDownloadManager
43 | .getInstance()
44 | .getDaoSession()
45 | .getEasyTaskEntityDao()
46 | .loadAll();
47 | }
48 |
49 | public void update(EasyTaskEntity entity) {
50 | EasyDownloadManager
51 | .getInstance()
52 | .getDaoSession()
53 | .getEasyTaskEntityDao()
54 | .update(entity);
55 | }
56 |
57 | public void delete(EasyTaskEntity entity) {
58 | EasyDownloadManager
59 | .getInstance()
60 | .getDaoSession()
61 | .getEasyTaskEntityDao()
62 | .delete(entity);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/utils/EasyHttpUtils.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.utils;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.net.URLEncoder;
5 | import java.util.Map;
6 |
7 | import okhttp3.Headers;
8 | import okhttp3.Request;
9 |
10 | /**
11 | * Created by yangy on 2017/3/14.
12 | */
13 |
14 | public class EasyHttpUtils {
15 | public static Request.Builder appendHeaders(Map headers) {
16 | Request.Builder requestBuilder = new Request.Builder();
17 |
18 | if (headers == null || headers.size() == 0) {
19 | return requestBuilder;
20 | }
21 |
22 | Headers.Builder headerBuilder = new Headers.Builder();
23 | for (Map.Entry entry : headers.entrySet()) {
24 | // String headerValue = URLEncoder.encode(entry.getValue(), "UTF-8");
25 | headerBuilder.add(entry.getKey(), entry.getValue());
26 | }
27 | requestBuilder.headers(headerBuilder.build());
28 | return requestBuilder;
29 | }
30 |
31 | public static String createUrlFromParams(String url, Map params) {
32 | if (params == null || params.size() == 0) {
33 | return url;
34 | }
35 |
36 | try {
37 | StringBuilder sb = new StringBuilder();
38 | sb.append(url);
39 | if (url.indexOf('&') > 0 || url.indexOf('?') > 0) {
40 | sb.append("&");
41 | } else {
42 | sb.append("?");
43 | }
44 | for (Map.Entry urlParam : params.entrySet()) {
45 | //对参数进行 utf-8 编码,防止头信息传中文
46 | String urlValue = URLEncoder.encode(urlParam.getValue(), "UTF-8");
47 | sb.append(urlParam.getKey())
48 | .append("=")
49 | .append(urlValue)
50 | .append("&");
51 | }
52 | sb.deleteCharAt(sb.length() - 1);
53 | return sb.toString();
54 | } catch (UnsupportedEncodingException e) {
55 | e.printStackTrace();
56 | }
57 | return url;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/easy-http-library-rx/src/main/java/com/yang/easyhttprx/RxEasyHttp.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttprx;
2 |
3 | import com.yang.easyhttp.cache.EasyCacheType;
4 | import com.yang.easyhttp.request.EasyRequestParams;
5 | import com.yang.easyhttprx.converter.RxEasyConverter;
6 | import com.yang.easyhttprx.manager.RxEasyHttpManager;
7 |
8 | import io.reactivex.Flowable;
9 |
10 | /**
11 | * Created by yangy on 2017/3/14.
12 | */
13 |
14 | public class RxEasyHttp {
15 | /**
16 | * Get请求RxJava形式
17 | * @param url
18 | * @return
19 | */
20 | public static Flowable get(String url, RxEasyConverter converter) {
21 | return get(url, null, converter);
22 | }
23 |
24 | public static Flowable get(String url, EasyRequestParams easyRequestParams, RxEasyConverter converter) {
25 | return RxEasyHttpManager.getInstance().get(url, easyRequestParams, EasyCacheType.CACHE_TYPE_NO_SETTING, converter);
26 | }
27 |
28 | public static Flowable get(String url, int cacheType, RxEasyConverter converter) {
29 | return get(url, null, cacheType, converter);
30 | }
31 |
32 | public static Flowable get(String url, EasyRequestParams easyRequestParams, int cacheType, RxEasyConverter converter) {
33 | return RxEasyHttpManager.getInstance().get(url, easyRequestParams, cacheType, converter);
34 | }
35 |
36 | /**
37 | * Post请求RxJava形式
38 | * @param url
39 | * @return
40 | */
41 | public static Flowable post(String url, EasyRequestParams easyRequestParams, RxEasyConverter converter) {
42 | return RxEasyHttpManager.getInstance().post(url, easyRequestParams, converter);
43 | }
44 |
45 | /**
46 | * post file RxJava形式
47 | * @param url
48 | * @param filePath
49 | * @return
50 | */
51 | public static Flowable uploadFile(String url, String filePath, RxEasyConverter converter) {
52 | return RxEasyHttpManager.getInstance().uploadFile(url, filePath, converter);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/Interceptor/EasyCacheInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.Interceptor;
2 |
3 |
4 | import com.yang.easyhttp.cache.EasyCacheTime;
5 | import com.yang.easyhttp.cache.EasyCacheType;
6 | import com.yang.easyhttp.utils.EasyNetworkUtils;
7 |
8 | import java.io.IOException;
9 |
10 | import okhttp3.Interceptor;
11 | import okhttp3.Request;
12 | import okhttp3.Response;
13 |
14 | /**
15 | * Created by yangy on 2017/2/15.
16 | */
17 | public class EasyCacheInterceptor implements Interceptor {
18 | private final int mType;
19 |
20 | public EasyCacheInterceptor(int mType) {
21 | this.mType = mType;
22 | }
23 |
24 | @Override
25 | public Response intercept(Chain chain) throws IOException {
26 | final Request originalRequest = chain.request();
27 | String cacheHeaderValue = null;
28 | if (mType == EasyCacheType.CACHE_TYPE_SHORT) {
29 | cacheHeaderValue = EasyNetworkUtils.isNetWorkOnLine()
30 | ? "public, max-age=" + EasyCacheTime.CACHE_TIME_SHORT
31 | : "public, only-if-cached, max-stale=86400";
32 | } else if (mType == EasyCacheType.CACHE_TYPE_MID) {
33 | cacheHeaderValue = EasyNetworkUtils.isNetWorkOnLine()
34 | ? "public, max-age=" + EasyCacheTime.CACHE_TIME_MID
35 | : "public, only-if-cached, max-stale=86400";
36 | } else if (mType == EasyCacheType.CACHE_TYPE_LONG) {
37 | cacheHeaderValue = EasyNetworkUtils.isNetWorkOnLine()
38 | ? "public, max-age=" + EasyCacheTime.CACHE_TIME_LONG
39 | : "public, only-if-cached, max-stale=86400";
40 | }
41 |
42 | final Request finalRequest = originalRequest.newBuilder()
43 | .tag(originalRequest.url().toString())
44 | .build();
45 |
46 | Response response = chain.proceed(originalRequest);
47 |
48 | if (mType != EasyCacheType.CACHE_TYPE_DEFAULT && response.code() < 400) {
49 | return response.newBuilder()
50 | .removeHeader("Pragma")
51 | .removeHeader("Cache-Control")
52 | .addHeader("Cache-Control", cacheHeaderValue)
53 | .build();
54 | }
55 | return response;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/activity/GetActivity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.activity;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.text.Editable;
8 | import android.text.TextUtils;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 | import android.widget.TextView;
12 | import android.widget.Toast;
13 |
14 | import com.yang.demo.R;
15 | import com.yang.easyhttp.EasyHttpClient;
16 | import com.yang.easyhttp.cache.EasyCacheType;
17 | import com.yang.easyhttp.callback.EasyStringCallback;
18 |
19 | import butterknife.BindView;
20 | import butterknife.ButterKnife;
21 | import butterknife.OnClick;
22 |
23 | /**
24 | * Created by yangyang on 2017/2/17.
25 | */
26 | public class GetActivity extends AppCompatActivity {
27 | @BindView(R.id.url)
28 | EditText urlView;
29 | @BindView(R.id.go)
30 | Button go;
31 | @BindView(R.id.body)
32 | TextView body;
33 |
34 | ProgressDialog dialog;
35 | @Override
36 | protected void onCreate(@Nullable Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 | setContentView(R.layout.get_main);
39 |
40 | ButterKnife.bind(this);
41 |
42 | dialog = new ProgressDialog(this);
43 | }
44 |
45 | @OnClick(R.id.go)
46 | public void go() {
47 | Editable url = urlView.getText();
48 |
49 | if (TextUtils.isEmpty(url)) {
50 | Toast.makeText(this, "url is empty", Toast.LENGTH_SHORT);
51 | return;
52 | }
53 |
54 | // EasyHttpClient.get(url.toString(), new EasyStringCallback() {
55 | EasyHttpClient.get(url.toString(), EasyCacheType.CACHE_TYPE_SHORT, new EasyStringCallback() {
56 | @Override
57 | public void onStart() {
58 | dialog.show();
59 | }
60 |
61 | @Override
62 | public void onFinish() {
63 | dialog.cancel();
64 | }
65 |
66 | @Override
67 | public void onSuccess(String content) {
68 | body.setText(content);
69 | }
70 |
71 | @Override
72 | public void onFailure(Throwable error, String content) {
73 | body.setText(content + "\n" +error.toString());
74 | }
75 | });
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.Log;
7 |
8 | import com.yang.demo.entity.MainEntity;
9 | import com.yang.demo.adapter.MainAdapter;
10 |
11 | import java.util.ArrayList;
12 |
13 | import butterknife.BindView;
14 | import butterknife.ButterKnife;
15 |
16 | public class MainActivity extends AppCompatActivity {
17 | private MainAdapter mMainAdapter;
18 |
19 | @BindView(R.id.list)
20 | RecyclerView mRecyclerView;
21 |
22 | @Override
23 | protected void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_main);
26 | ButterKnife.bind(this);
27 | mMainAdapter = new MainAdapter(this);
28 | mRecyclerView.setAdapter(mMainAdapter);
29 | mMainAdapter.setData(getEntities());
30 | }
31 |
32 | private ArrayList getEntities() {
33 | ArrayList list = new ArrayList<>();
34 | String [][] data = {
35 | {
36 | "1",
37 | "Get",
38 | "Get请求;支持JSON字符串自动转换为对象;支持自定义转换扩展;支持String返回;支持全局缓存;支持不同接口不同缓存策略;支持debug模式",
39 | },
40 | {
41 | "2",
42 | "Post",
43 | "Post表单范例",
44 | },
45 | {
46 | "3",
47 | "Download",
48 | "下载文件请求;支持断点续传;可自定义下载线程数量;自动保存下载现场",
49 | },
50 | {
51 | "4",
52 | "Upload",
53 | "上传文件请求",
54 | },
55 | {
56 | "5",
57 | "Get(RxJava方式)",
58 | "RxJava Get请求",
59 | },
60 | {
61 | "6",
62 | "Post(RxJava方式)",
63 | "RxJava Post请求 ",
64 | },
65 | };
66 |
67 | for (int i = 0; i < data.length; i++) {
68 | MainEntity entity = new MainEntity();
69 | entity.setType(Integer.parseInt(data[i][0]));
70 | entity.setTitle(data[i][1]);
71 | entity.setDesc(data[i][2]);
72 | list.add(entity);
73 | }
74 |
75 | Log.d("test" , "list.length = " + list.size());
76 |
77 | return list;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/activity/PostActivity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.activity;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.text.Editable;
8 | import android.text.TextUtils;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 | import android.widget.TextView;
12 | import android.widget.Toast;
13 |
14 | import com.yang.demo.R;
15 | import com.yang.demo.entity.PostEntity;
16 | import com.yang.easyhttp.EasyHttpClient;
17 | import com.yang.easyhttp.callback.EasyCustomCallback;
18 | import com.yang.easyhttp.request.EasyRequestParams;
19 |
20 | import butterknife.BindView;
21 | import butterknife.ButterKnife;
22 | import butterknife.OnClick;
23 |
24 | /**
25 | * Created by yangyang on 2017/2/17.
26 | */
27 | public class PostActivity extends AppCompatActivity {
28 | @BindView(R.id.comment)
29 | EditText comment;
30 | @BindView(R.id.submit)
31 | Button submit;
32 | @BindView(R.id.result)
33 | TextView result;
34 | ProgressDialog dialog;
35 |
36 | @Override
37 | protected void onCreate(@Nullable Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 | setContentView(R.layout.post_main);
40 | ButterKnife.bind(this);
41 | dialog = new ProgressDialog(this);
42 | }
43 |
44 | @OnClick(R.id.submit)
45 | public void submit() {
46 | Editable content = comment.getText();
47 |
48 | if (TextUtils.isEmpty(content)) {
49 | Toast.makeText(this, "comment is empty", Toast.LENGTH_SHORT);
50 | return;
51 | }
52 |
53 | EasyRequestParams params = new EasyRequestParams();
54 | params.put("content", content.toString());
55 |
56 | EasyHttpClient.post("http://book.2345.com/app/index.php?c=version&a=feedback",
57 | params,
58 | new EasyCustomCallback() {
59 | @Override
60 | public void onStart() {
61 | dialog.show();
62 | }
63 |
64 | @Override
65 | public void onFinish() {
66 | dialog.cancel();
67 | }
68 |
69 | @Override
70 | public void onSuccess(PostEntity content) {
71 | Toast.makeText(PostActivity.this, "提交成功", Toast.LENGTH_LONG).show();
72 | result.setText("status : " + content.getStatus() + "\n" +
73 | "message : " + content.getMessage());
74 | }
75 |
76 | @Override
77 | public void onFailure(Throwable error, String content) {
78 | Toast.makeText(PostActivity.this, "提交失败", Toast.LENGTH_LONG).show();
79 | result.setText(content + "\n" + error.getMessage());
80 | }
81 | }
82 | );
83 | }
84 |
85 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/activity/RxGetActivity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.activity;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.text.Editable;
8 | import android.text.TextUtils;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 | import android.widget.TextView;
12 | import android.widget.Toast;
13 |
14 | import com.yang.demo.R;
15 | import com.yang.easyhttprx.RxEasyHttp;
16 | import com.yang.easyhttprx.converter.RxEasyStringConverter;
17 |
18 | import org.reactivestreams.Subscription;
19 |
20 | import butterknife.BindView;
21 | import butterknife.ButterKnife;
22 | import butterknife.OnClick;
23 | import io.reactivex.FlowableSubscriber;
24 | import io.reactivex.android.schedulers.AndroidSchedulers;
25 | import io.reactivex.annotations.NonNull;
26 | import io.reactivex.functions.Consumer;
27 |
28 | /**
29 | * Created by yangyang on 2017/2/17.
30 | */
31 | public class RxGetActivity extends AppCompatActivity {
32 | @BindView(R.id.url)
33 | EditText urlView;
34 | @BindView(R.id.go)
35 | Button go;
36 | @BindView(R.id.body)
37 | TextView body;
38 |
39 | ProgressDialog dialog;
40 | @Override
41 | protected void onCreate(@Nullable Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 | setContentView(R.layout.get_main);
44 |
45 | ButterKnife.bind(this);
46 |
47 | dialog = new ProgressDialog(this);
48 | }
49 |
50 | @OnClick(R.id.go)
51 | public void go() {
52 | Editable url = urlView.getText();
53 |
54 | if (TextUtils.isEmpty(url)) {
55 | Toast.makeText(this, "url is empty", Toast.LENGTH_SHORT);
56 | return;
57 | }
58 |
59 | RxEasyHttp.get(url.toString(), new RxEasyStringConverter())
60 | .doOnSubscribe(new Consumer() {
61 | @Override
62 | public void accept(@NonNull Subscription subscription) throws Exception {
63 | dialog.show();
64 | body.setText("");
65 | }
66 | })
67 | .observeOn(AndroidSchedulers.mainThread())
68 | .subscribe(new FlowableSubscriber() {
69 | @Override
70 | public void onSubscribe(Subscription s) {
71 | s.request(Long.MAX_VALUE);
72 | dialog.show();
73 | body.setText("");
74 | }
75 |
76 | @Override
77 | public void onNext(String response) {
78 | body.setText(response);
79 | }
80 |
81 | @Override
82 | public void onError(Throwable t) {
83 | body.setText(t.toString());
84 | }
85 |
86 | @Override
87 | public void onComplete() {
88 | dialog.cancel();
89 | }
90 | });
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/activity/DownloadActivity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.activity;
2 |
3 | import android.annotation.TargetApi;
4 | import android.os.Build;
5 | import android.os.Bundle;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.support.v7.widget.RecyclerView;
8 |
9 | import com.yang.demo.entity.DownloadEntity;
10 | import com.yang.demo.R;
11 | import com.yang.demo.adapter.DownloadAdapter;
12 |
13 | import java.util.ArrayList;
14 |
15 | import butterknife.BindView;
16 | import butterknife.ButterKnife;
17 |
18 | /**
19 | * Created by yangyang on 2017/2/17.
20 | */
21 | public class DownloadActivity extends AppCompatActivity {
22 | private DownloadAdapter mDownloadAdapter;
23 |
24 | @BindView(R.id.list)
25 | RecyclerView mRecyclerView;
26 |
27 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.layout_download);
32 | ButterKnife.bind(this);
33 |
34 | mDownloadAdapter = new DownloadAdapter(this);
35 | mRecyclerView.setAdapter(mDownloadAdapter);
36 | mDownloadAdapter.setData(getEntities());
37 | }
38 |
39 | private ArrayList getEntities() {
40 | ArrayList list = new ArrayList<>();
41 | String [][] data = {
42 | {
43 | "天气王",
44 | "http://tianqi.2345.com/redirect.php?downloadQr"
45 | },
46 | {
47 | "阅读王",
48 | "http://book.km.com/app/index.php?c=app&a=download",
49 | },
50 | {
51 | "高清壁纸",
52 | "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1487332054826&di=ad31ae9a0d64c6df1b67ddf995adea96&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2Fd01373f082025aaf2e112fa4f9edab64034f1ab9.jpg",
53 | },
54 | {
55 | "高清壁纸",
56 | "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1487332099511&di=a59747692ee933615f8d971f78cd5c32&imgtype=0&src=http%3A%2F%2Fi1284.photobucket.com%2Falbums%2Fa577%2Fxia14905029362%2Fdongfang%2Fdesk_cg_581_zps8a07ea53.jpg",
57 | },
58 | {
59 | "高清壁纸",
60 | "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2920785976,3012753148&fm=23&gp=0.jpg"
61 | },
62 | {
63 | "高清壁纸",
64 | "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1487332167386&di=97d63ccaea664b0d9ba0b6b7d88d9c4f&imgtype=jpg&src=http%3A%2F%2Fimg1.imgtn.bdimg.com%2Fit%2Fu%3D1118135712%2C1857871654%26fm%3D214%26gp%3D0.jpg"
65 | },
66 | };
67 |
68 | for (int i = 0; i < data.length; i++) {
69 | DownloadEntity entity = new DownloadEntity();
70 | entity.setTitle(data[i][0]);
71 | String url = data[i][1];
72 | String hashcode = String.valueOf(url.hashCode());
73 | entity.setUrl(data[i][1]);
74 | entity.setHashCode(hashcode);
75 | list.add(entity);
76 | }
77 |
78 |
79 | return list;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/activity/RxPostActivity.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.activity;
2 |
3 | import android.app.ProgressDialog;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.text.Editable;
8 | import android.text.TextUtils;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 | import android.widget.TextView;
12 | import android.widget.Toast;
13 |
14 | import com.yang.demo.R;
15 | import com.yang.demo.entity.PostEntity;
16 | import com.yang.easyhttp.request.EasyRequestParams;
17 | import com.yang.easyhttprx.RxEasyHttp;
18 | import com.yang.easyhttprx.converter.RxEasyCustomConverter;
19 |
20 | import org.reactivestreams.Subscription;
21 |
22 | import butterknife.BindView;
23 | import butterknife.ButterKnife;
24 | import butterknife.OnClick;
25 | import io.reactivex.FlowableSubscriber;
26 | import io.reactivex.android.schedulers.AndroidSchedulers;
27 |
28 | /**
29 | * Created by yangyang on 2017/2/17.
30 | */
31 | public class RxPostActivity extends AppCompatActivity {
32 | @BindView(R.id.comment)
33 | EditText comment;
34 | @BindView(R.id.submit)
35 | Button submit;
36 | @BindView(R.id.result)
37 | TextView result;
38 | ProgressDialog dialog;
39 |
40 | @Override
41 | protected void onCreate(@Nullable Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 | setContentView(R.layout.post_main);
44 | ButterKnife.bind(this);
45 | dialog = new ProgressDialog(this);
46 | }
47 |
48 | @OnClick(R.id.submit)
49 | public void submit() {
50 | Editable content = comment.getText();
51 |
52 | if (TextUtils.isEmpty(content)) {
53 | Toast.makeText(this, "comment is empty", Toast.LENGTH_SHORT);
54 | return;
55 | }
56 |
57 | EasyRequestParams params = new EasyRequestParams();
58 | params.put("content", content.toString());
59 |
60 | String url = "http://book.km.com/app/index.php?c=version&a=feedback";
61 |
62 | RxEasyHttp.post(url, params, new RxEasyCustomConverter() {
63 | @Override
64 | public void doNothing() {
65 | // 防止范型类型擦除引起范型类型不能正确获取问题.
66 | }
67 | })
68 | .observeOn(AndroidSchedulers.mainThread())
69 | .subscribe(new FlowableSubscriber() {
70 |
71 | @Override
72 | public void onSubscribe(Subscription s) {
73 | s.request(Long.MAX_VALUE);
74 | dialog.show();
75 | }
76 |
77 | @Override
78 | public void onNext(PostEntity entity) {
79 | Toast.makeText(RxPostActivity.this, "提交成功", Toast.LENGTH_LONG).show();
80 | result.setText("status : " + entity.getStatus() + "\n" +
81 | "message : " + entity.getMessage());
82 |
83 | }
84 |
85 | @Override
86 | public void onError(Throwable t) {
87 | Toast.makeText(RxPostActivity.this, "提交失败", Toast.LENGTH_LONG).show();
88 | result.setText(t.getMessage());
89 | dialog.cancel();
90 | }
91 |
92 | @Override
93 | public void onComplete() {
94 | dialog.cancel();
95 | }
96 | });
97 | }
98 |
99 |
100 | }
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/adapter/MainAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.adapter;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import com.yang.demo.activity.GetActivity;
13 | import com.yang.demo.activity.PostActivity;
14 | import com.yang.demo.activity.RxGetActivity;
15 | import com.yang.demo.activity.RxPostActivity;
16 | import com.yang.demo.entity.MainEntity;
17 | import com.yang.demo.R;
18 | import com.yang.demo.activity.DownloadActivity;
19 | import com.yang.demo.activity.UploadActivity;
20 |
21 | import java.util.ArrayList;
22 |
23 | import butterknife.BindView;
24 | import butterknife.ButterKnife;
25 |
26 | /**
27 | * Created by yangyang on 2017/2/17.
28 | */
29 | public class MainAdapter extends RecyclerView.Adapter {
30 | private ArrayList mList;
31 | private Context mContext;
32 |
33 | public MainAdapter(Context context) {
34 | this.mContext = context;
35 | }
36 |
37 | public void setData(ArrayList list) {
38 | mList = list;
39 | notifyDataSetChanged();
40 | }
41 |
42 | @Override
43 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
44 | View view = LayoutInflater.from(mContext).inflate(R.layout.main_item, parent, false);
45 | return new ViewHolder(view);
46 | }
47 |
48 | @Override
49 | public void onBindViewHolder(ViewHolder holder, int position) {
50 | Log.d("test", "onBindViewHolder called position : " + position);
51 | final MainEntity entity = mList.get(position);
52 |
53 | holder.title.setText(entity.getTitle());
54 | holder.desc.setText(entity.getDesc());
55 |
56 | holder.itemView.setOnClickListener(new View.OnClickListener() {
57 | @Override
58 | public void onClick(View v) {
59 | switch (entity.getType()) {
60 | case 1:
61 | Intent intent = new Intent(mContext, GetActivity.class);
62 | mContext.startActivity(intent);
63 | break;
64 | case 2:
65 | intent = new Intent(mContext, PostActivity.class);
66 | mContext.startActivity(intent);
67 | break;
68 | case 3:
69 | intent = new Intent(mContext, DownloadActivity.class);
70 | mContext.startActivity(intent);
71 | break;
72 | case 4:
73 | intent = new Intent(mContext, UploadActivity.class);
74 | mContext.startActivity(intent);
75 | break;
76 | case 5:
77 | intent = new Intent(mContext, RxGetActivity.class);
78 | mContext.startActivity(intent);
79 | break;
80 | case 6:
81 | intent = new Intent(mContext, RxPostActivity.class);
82 | mContext.startActivity(intent);
83 | break;
84 | default:
85 | break;
86 | }
87 | }
88 | });
89 | }
90 |
91 | @Override
92 | public int getItemCount() {
93 | return mList != null ? mList.size() : 0;
94 | }
95 |
96 | class ViewHolder extends RecyclerView.ViewHolder {
97 | @BindView(R.id.title)
98 | TextView title;
99 | @BindView(R.id.desc)
100 | TextView desc;
101 |
102 | public ViewHolder(View itemView) {
103 | super(itemView);
104 | ButterKnife.bind(this, itemView);
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/config/EasyHttpConfig.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.config;
2 |
3 | /**
4 | * Created by yangy on 2017/2/22.
5 | */
6 | public class EasyHttpConfig {
7 | String cacheDir;
8 |
9 | int cacheShortTime;
10 | int cacheMidTime;
11 | int cacheLongTime;
12 |
13 | long cacheShortMaxSize;
14 | long cacheMidMaxSize;
15 | long cacheLongMaxSize;
16 |
17 | int globalCacheType;
18 |
19 | String userAgent;
20 |
21 | EasyHttpConfig(Builder builder) {
22 | this.cacheDir = builder.cacheDir;
23 | this.cacheShortTime = builder.cacheShortTime;
24 | this.cacheMidTime = builder.cacheMidTime;
25 | this.cacheLongTime = builder.cacheLongTime;
26 | this.cacheShortMaxSize = builder.cacheShortMaxSize;
27 | this.cacheMidMaxSize = builder.cacheMidMaxSize;
28 | this.cacheLongMaxSize = builder.cacheLongMaxSize;
29 | this.globalCacheType = builder.globalCacheType;
30 | this.userAgent = builder.userAgent;
31 | }
32 |
33 | public void setCacheDir(String cacheDir) {
34 | this.cacheDir = cacheDir;
35 | }
36 |
37 | public void setCacheShortTime(int cacheShortTime) {
38 | this.cacheShortTime = cacheShortTime;
39 | }
40 |
41 | public void setCacheMidTime(int cacheMidTime) {
42 | this.cacheMidTime = cacheMidTime;
43 | }
44 |
45 | public void setCacheLongTime(int cacheLongTime) {
46 | this.cacheLongTime = cacheLongTime;
47 | }
48 |
49 | public void setGlobalCacheType(int globalCacheType) {
50 | this.globalCacheType = globalCacheType;
51 | }
52 |
53 | public String getCacheDir() {
54 | return cacheDir;
55 | }
56 |
57 | public int getCacheShortTime() {
58 | return cacheShortTime;
59 | }
60 |
61 | public int getCacheMidTime() {
62 | return cacheMidTime;
63 | }
64 |
65 | public int getCacheLongTime() {
66 | return cacheLongTime;
67 | }
68 |
69 | public int getGlobalCacheType() {
70 | return globalCacheType;
71 | }
72 |
73 | public long getCacheShortMaxSize() {
74 | return cacheShortMaxSize;
75 | }
76 |
77 | public void setCacheShortMaxSize(long cacheShortMaxSize) {
78 | this.cacheShortMaxSize = cacheShortMaxSize;
79 | }
80 |
81 | public long getCacheMidMaxSize() {
82 | return cacheMidMaxSize;
83 | }
84 |
85 | public void setCacheMidMaxSize(long cacheMidMaxSize) {
86 | this.cacheMidMaxSize = cacheMidMaxSize;
87 | }
88 |
89 | public long getCacheLongMaxSize() {
90 | return cacheLongMaxSize;
91 | }
92 |
93 | public void setCacheLongMaxSize(long cacheLongMaxSize) {
94 | this.cacheLongMaxSize = cacheLongMaxSize;
95 | }
96 |
97 | public String getUserAgent() {
98 | return userAgent;
99 | }
100 |
101 | public void setUserAgent(String userAgent) {
102 | this.userAgent = userAgent;
103 | }
104 |
105 | public static class Builder {
106 | String cacheDir;
107 |
108 | int cacheShortTime = 0;
109 | int cacheMidTime = 0;
110 | int cacheLongTime = 0;
111 |
112 | long cacheShortMaxSize = 0;
113 | long cacheMidMaxSize = 0;
114 | long cacheLongMaxSize = 0;
115 |
116 | int globalCacheType = -1;
117 |
118 | String userAgent;
119 |
120 | public Builder setCacheDir(String cacheDir) {
121 | this.cacheDir = cacheDir;
122 | return this;
123 | }
124 |
125 | public Builder setCacheTime(int shortTime, int midTime, int longTime) {
126 | this.cacheShortTime = shortTime;
127 | this.cacheMidTime = midTime;
128 | this.cacheLongTime = longTime;
129 |
130 | return this;
131 | }
132 |
133 | public Builder setGlobalCacheType(int type) {
134 | this.globalCacheType = type;
135 | return this;
136 | }
137 |
138 | public Builder setCacheMaxSize(long cacheShortMaxSize, long cacheMidMaxSize, long cacheLongMaxSize) {
139 | this.cacheShortMaxSize = cacheShortMaxSize;
140 | this.cacheMidMaxSize = cacheMidMaxSize;
141 | this.cacheLongMaxSize = cacheLongMaxSize;
142 | return this;
143 | }
144 |
145 | public Builder setUserAgent(String userAgent) {
146 | this.userAgent = userAgent;
147 | return this;
148 | }
149 |
150 | public EasyHttpConfig build() {
151 | return new EasyHttpConfig(this);
152 | }
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/EasyHttpClient.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp;
2 |
3 | import android.content.Context;
4 |
5 | import com.yang.easyhttp.cache.EasyCacheType;
6 | import com.yang.easyhttp.callback.EasyCallback;
7 | import com.yang.easyhttp.config.EasyHttpConfig;
8 | import com.yang.easyhttp.download.EasyDownloadManager;
9 | import com.yang.easyhttp.manager.EasyHttpClientManager;
10 | import com.yang.easyhttp.request.EasyRequestParams;
11 |
12 | /**
13 | * Created by yangy on 2017/2/15.
14 | */
15 | public class EasyHttpClient {
16 | /**
17 | * EasyHttpClient init.
18 | * @param context
19 | */
20 | public static void init(Context context) {
21 | EasyHttpClientManager.getInstance().init(context);
22 | }
23 |
24 | public static void init(Context context, EasyHttpConfig config) {
25 | EasyHttpClientManager.getInstance().init(context, config);
26 | }
27 |
28 | /**
29 | * Download environment init.
30 | * Make sure the init function is only called once.
31 | */
32 | public static void initDownloadEnvironment() {
33 | EasyDownloadManager.getInstance().init(EasyHttpClientManager.getInstance().getContext());
34 | }
35 |
36 | public static void initDownloadEnvironment(int threadCount) {
37 | EasyDownloadManager.getInstance().init(EasyHttpClientManager.getInstance().getContext(), threadCount);
38 | }
39 |
40 | /**
41 | * set the debug mode.
42 | * @param debug
43 | */
44 | public static void setDebug(boolean debug) {
45 | EasyHttpClientManager.getInstance().setDebug(debug);
46 | }
47 |
48 | /**
49 | * get request.
50 | * @param url
51 | * @param callback
52 | * @param
53 | */
54 | public static void get(String url, EasyCallback callback) {
55 | get(url, null, callback);
56 | }
57 |
58 | public static void get(String url, EasyRequestParams easyRequestParams, EasyCallback callBack) {
59 | EasyHttpClientManager.getInstance().get(url, easyRequestParams, EasyCacheType.CACHE_TYPE_NO_SETTING, callBack);
60 | }
61 |
62 | public static void get(String url, int cacheType, EasyCallback callback) {
63 | get(url, null, cacheType, callback);
64 | }
65 |
66 | public static void get(String url, EasyRequestParams easyRequestParams, int cacheType, EasyCallback callback) {
67 | EasyHttpClientManager.getInstance().get(url, easyRequestParams, cacheType, callback);
68 | }
69 |
70 | /**
71 | * post request.
72 | * @param url
73 | * @param easyRequestParams
74 | * @param callback
75 | * @param
76 | */
77 | public static void post(String url, EasyRequestParams easyRequestParams, EasyCallback callback) {
78 | EasyHttpClientManager.getInstance().postOrDeleteOrPut(url, easyRequestParams, callback, EasyHttpClientManager.REQUEST_POST);
79 | }
80 |
81 | /**
82 | * delete request.
83 | * @param url
84 | * @param easyRequestParams
85 | * @param callback
86 | * @param
87 | */
88 | public static void delete(String url, EasyRequestParams easyRequestParams, EasyCallback callback) {
89 | EasyHttpClientManager.getInstance().postOrDeleteOrPut(url, easyRequestParams, callback, EasyHttpClientManager.REQUEST_DELETE);
90 | }
91 |
92 | /**
93 | * put request
94 | * @param url
95 | * @param easyRequestParams
96 | * @param callback
97 | * @param
98 | */
99 | public static void put(String url, EasyRequestParams easyRequestParams, EasyCallback callback) {
100 | EasyHttpClientManager.getInstance().postOrDeleteOrPut(url, easyRequestParams, callback, EasyHttpClientManager.REQUEST_PUT);
101 | }
102 |
103 | /**
104 | * upload file.
105 | * @param url
106 | * @param filePath
107 | * @param callback
108 | * @param
109 | */
110 | public static void uploadFile(String url, String filePath, EasyCallback callback) {
111 | EasyHttpClientManager.getInstance().uploadFile(url, filePath, callback);
112 | }
113 |
114 | /**
115 | * cancel request.
116 | * @param cacheType
117 | */
118 | public static void cancel(int cacheType) {
119 | EasyHttpClientManager.getInstance().cancelRequest(cacheType);
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/easy-http-library-rx/src/main/java/com/yang/easyhttprx/manager/RxEasyHttpManager.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttprx.manager;
2 |
3 | import com.yang.easyhttp.cache.EasyCacheType;
4 | import com.yang.easyhttp.manager.EasyHttpClientManager;
5 | import com.yang.easyhttp.request.EasyRequestParams;
6 | import com.yang.easyhttprx.converter.RxEasyConverter;
7 |
8 | import java.io.File;
9 | import java.util.concurrent.ConcurrentHashMap;
10 |
11 | import io.reactivex.BackpressureStrategy;
12 | import io.reactivex.Flowable;
13 | import io.reactivex.FlowableEmitter;
14 | import io.reactivex.FlowableOnSubscribe;
15 | import io.reactivex.schedulers.Schedulers;
16 | import okhttp3.Call;
17 | import okhttp3.FormBody;
18 | import okhttp3.MediaType;
19 | import okhttp3.Request;
20 | import okhttp3.RequestBody;
21 | import okhttp3.Response;
22 |
23 | /**
24 | * Created by yangy on 2017/3/14.
25 | */
26 |
27 | public class RxEasyHttpManager {
28 | private static RxEasyHttpManager mInstance = null;
29 |
30 | public static synchronized RxEasyHttpManager getInstance() {
31 | if (null == mInstance) {
32 | mInstance = new RxEasyHttpManager();
33 | }
34 |
35 | return mInstance;
36 | }
37 |
38 | /**
39 | * Get请求的Rxjava方式.
40 | * @param url
41 | * @param requestParams
42 | * @param cacheType
43 | * @return
44 | */
45 | public Flowable get(String url, EasyRequestParams requestParams, int cacheType, RxEasyConverter rxEasyConverter) {
46 | final Request request = new Request.Builder().url(EasyHttpClientManager.getInstance().buildUrl(url, requestParams)).build();
47 | // 接口没有单独设定缓存类型,使用全局缓存类型.
48 | if (cacheType == EasyCacheType.CACHE_TYPE_NO_SETTING) {
49 | cacheType = EasyHttpClientManager.getInstance().getConfig().getGlobalCacheType();
50 | }
51 |
52 | Call call = EasyHttpClientManager.getInstance().getOkHttpClient(cacheType).newCall(request);
53 |
54 | return Flowable.create(new CallFlowableOnSubscribe(call, rxEasyConverter), BackpressureStrategy.BUFFER)
55 | .subscribeOn(Schedulers.io());
56 | }
57 |
58 | /**
59 | * Post请求的Rxjava方式.
60 | * @param url
61 | * @param requestParams
62 | * @return
63 | */
64 | public Flowable post(String url, EasyRequestParams requestParams, RxEasyConverter rxEasyConverter) {
65 | FormBody.Builder builder = new FormBody.Builder();
66 | ConcurrentHashMap paramsMap = requestParams.getRequestParams();
67 | for (ConcurrentHashMap.Entry entry : paramsMap.entrySet()) {
68 | builder.add(entry.getKey(), entry.getValue());
69 | }
70 |
71 | RequestBody requestBody = builder.build();
72 | final Request request = new Request.Builder()
73 | .url(url)
74 | .post(requestBody)
75 | .build();
76 |
77 | Call call = EasyHttpClientManager.getInstance().getOkHttpClient(EasyCacheType.CACHE_TYPE_DEFAULT).newCall(request);
78 |
79 | return Flowable.create(new CallFlowableOnSubscribe(call,rxEasyConverter), BackpressureStrategy.BUFFER)
80 | .subscribeOn(Schedulers.io());
81 | }
82 |
83 | /**
84 | * upload file.
85 | * @param url
86 | * @param filePath
87 | * @return
88 | */
89 | public Flowable uploadFile(String url, String filePath, RxEasyConverter rxEasyConverter) {
90 | File file = new File(filePath);
91 | RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
92 |
93 | final Request request = new Request.Builder()
94 | .url(url)
95 | .post(requestBody)
96 | .build();
97 |
98 | Call call = EasyHttpClientManager.getInstance().getOkHttpClient(EasyCacheType.CACHE_TYPE_DEFAULT).newCall(request);
99 |
100 | return Flowable.create(new CallFlowableOnSubscribe(call, rxEasyConverter), BackpressureStrategy.BUFFER)
101 | .subscribeOn(Schedulers.io());
102 | }
103 |
104 | class CallFlowableOnSubscribe implements FlowableOnSubscribe {
105 | private Call call;
106 | private RxEasyConverter rxEasyConverter;
107 |
108 | public CallFlowableOnSubscribe(Call call, RxEasyConverter rxEasyConverter) {
109 | this.call = call;
110 | this.rxEasyConverter = rxEasyConverter;
111 | }
112 |
113 | @Override
114 | public void subscribe(FlowableEmitter e) throws Exception {
115 | try {
116 | Response response = call.execute();
117 |
118 | if (!e.isCancelled()) {
119 | if (response.isSuccessful()) {
120 | e.onNext(rxEasyConverter.convert(response.body().string()));
121 | } else {
122 | e.onError(new Throwable("response is unsuccessful"));
123 | }
124 | }
125 | } catch (Throwable t) {
126 | if (!e.isCancelled()) {
127 | e.onError(t);
128 | }
129 | } finally {
130 | e.onComplete();
131 | }
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/download/EasyTaskEntity.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.download;
2 |
3 | import org.greenrobot.greendao.annotation.Entity;
4 | import org.greenrobot.greendao.annotation.Generated;
5 | import org.greenrobot.greendao.annotation.Id;
6 | import org.greenrobot.greendao.annotation.NotNull;
7 | import org.greenrobot.greendao.annotation.Property;
8 |
9 | /**
10 | * Created by yangy on 2017/2/16.
11 | */
12 | @Entity(nameInDb = "download_status")
13 | public class EasyTaskEntity {
14 | @Id(autoincrement = true)
15 | private Long id;
16 | @Property
17 | @NotNull
18 | private String taskId;
19 | @Property
20 | private long totalSize;
21 | @Property
22 | private long completedSize;
23 | @Property
24 | @NotNull
25 | private String downloadUrl;
26 | @Property
27 | private String saveDirPath;
28 | @Property
29 | private String saveFileName;
30 | @Property
31 | private int taskStatus;
32 |
33 | public EasyTaskEntity(Builder builder) {
34 | this.taskId = builder.taskId;
35 | this.totalSize = builder.totalSize;
36 | this.completedSize = builder.completedSize;
37 | this.downloadUrl = builder.downloadUrl;
38 | this.saveDirPath = builder.saveDirPath;
39 | this.saveFileName = builder.saveFileName;
40 | this.taskStatus = builder.taskStatus;
41 | }
42 |
43 | @Generated(hash = 1668992877)
44 | public EasyTaskEntity(Long id, @NotNull String taskId, long totalSize, long completedSize,
45 | @NotNull String downloadUrl, String saveDirPath, String saveFileName,
46 | int taskStatus) {
47 | this.id = id;
48 | this.taskId = taskId;
49 | this.totalSize = totalSize;
50 | this.completedSize = completedSize;
51 | this.downloadUrl = downloadUrl;
52 | this.saveDirPath = saveDirPath;
53 | this.saveFileName = saveFileName;
54 | this.taskStatus = taskStatus;
55 | }
56 |
57 | @Generated(hash = 1657904667)
58 | public EasyTaskEntity() {
59 | }
60 |
61 | public String getTaskId() {
62 | return taskId;
63 | }
64 |
65 | public void setTaskId(String taskId) {
66 | this.taskId = taskId;
67 | }
68 |
69 | public long getTotalSize() {
70 | return totalSize;
71 | }
72 |
73 | public void setTotalSize(long totalSize) {
74 | this.totalSize = totalSize;
75 | }
76 |
77 | public long getCompletedSize() {
78 | return completedSize;
79 | }
80 |
81 | public void setCompletedSize(long completedSize) {
82 | this.completedSize = completedSize;
83 | }
84 |
85 | public String getDownloadUrl() {
86 | return downloadUrl;
87 | }
88 |
89 | public void setDownloadUrl(String downloadUrl) {
90 | this.downloadUrl = downloadUrl;
91 | }
92 |
93 | public String getSaveDirPath() {
94 | return saveDirPath;
95 | }
96 |
97 | public void setSaveDirPath(String saveDirPath) {
98 | this.saveDirPath = saveDirPath;
99 | }
100 |
101 | public String getSaveFileName() {
102 | return saveFileName;
103 | }
104 |
105 | public void setSaveFileName(String saveFileName) {
106 | this.saveFileName = saveFileName;
107 | }
108 |
109 | public int getTaskStatus() {
110 | return taskStatus;
111 | }
112 |
113 | public void setTaskStatus(int taskStatus) {
114 | this.taskStatus = taskStatus;
115 | }
116 |
117 | public Long getId() {
118 | return this.id;
119 | }
120 |
121 | public void setId(Long id) {
122 | this.id = id;
123 | }
124 | public static class Builder {
125 | // file id
126 | @NotNull
127 | private String taskId;
128 | // file length
129 | private long totalSize;
130 | // file complete length
131 | private long completedSize;
132 | // file url
133 | @NotNull
134 | private String downloadUrl;
135 | // file save path
136 | private String saveDirPath;
137 | // file name
138 | private String saveFileName;
139 | // file download status
140 | private int taskStatus;
141 |
142 | public Builder taskId(String taskId) {
143 | this.taskId = taskId;
144 | return this;
145 | }
146 |
147 | public Builder totalSize(long totalSize) {
148 | this.totalSize = totalSize;
149 | return this;
150 | }
151 |
152 | public Builder completedSize(long completedSize) {
153 | this.completedSize = completedSize;
154 | return this;
155 | }
156 |
157 | public Builder downloadUrl(String downloadUrl) {
158 | this.downloadUrl = downloadUrl;
159 | return this;
160 | }
161 |
162 | public Builder saveDirPath(String saveDirPath) {
163 | this.saveDirPath = saveDirPath;
164 | return this;
165 | }
166 |
167 | public Builder saveFileName(String saveFileName) {
168 | this.saveFileName = saveFileName;
169 | return this;
170 | }
171 |
172 | public Builder taskStatus(int taskStatus) {
173 | this.taskStatus = taskStatus;
174 | return this;
175 | }
176 |
177 | public EasyTaskEntity build() {
178 | return new EasyTaskEntity(this);
179 | }
180 | }
181 |
182 | @Override
183 | public String toString() {
184 | return "EasyTaskEntity{" +
185 | "taskId='" + taskId + '\'' +
186 | ", totalSize=" + totalSize +
187 | ", completedSize=" + completedSize +
188 | ", downloadUrl='" + downloadUrl + '\'' +
189 | ", saveDirPath='" + saveDirPath + '\'' +
190 | ", saveFileName='" + saveFileName + '\'' +
191 | ", taskStatus=" + taskStatus +
192 | '}';
193 | }
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/utils/EasyNetworkUtils.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.utils;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 | import android.telephony.TelephonyManager;
7 |
8 | import com.yang.easyhttp.manager.EasyHttpClientManager;
9 |
10 | /**
11 | * Created by yangy on 2017/2/16.
12 | */
13 | public class EasyNetworkUtils {
14 | public static final int NETWORKTYPE_INVALID = 0;
15 | public static final int NETWORKTYPE_MOBILE = 1;
16 | public static final int NETWORKTYPE_2G = 2;
17 | public static final int NETWORKTYPE_3G = 3;
18 | public static final int NETWORKTYPE_4G = 4;
19 | public static final int NETWORKTYPE_WIFI = 5;
20 |
21 | /**
22 | * 网络是否在线.
23 | *
24 | * @return
25 | */
26 | public static boolean isNetWorkOnLine() {
27 | Context context = EasyHttpClientManager.getInstance().getContext();
28 | // 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
29 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
30 |
31 | if (connectivityManager == null) {
32 | return false;
33 | } else {
34 | // 获取NetworkInfo对象
35 | NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();
36 | if (networkInfo != null && networkInfo.length > 0) {
37 | for (int i = 0; i < networkInfo.length; i++) {
38 | // 判断当前网络状态是否为连接状态
39 | if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
40 | return true;
41 | }
42 | }
43 | }
44 | }
45 | return false;
46 | }
47 |
48 | /**
49 | * 获取网络状态
50 | * @param context 上下文
51 | * @return int 网络状态
52 | */
53 | public static int getNetWorkType(Context context) {
54 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
55 |
56 | if (connectivityManager == null) {
57 | return NETWORKTYPE_INVALID;
58 | }
59 |
60 | NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
61 |
62 | if (activeNetworkInfo == null || !activeNetworkInfo.isAvailable()) {
63 | return NETWORKTYPE_INVALID;
64 | }
65 |
66 | //判断是不是连接的是不是wifi
67 | NetworkInfo wifiInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
68 | if (null != wifiInfo) {
69 | NetworkInfo.State state = wifiInfo.getState();
70 | if (null != state)
71 | if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) {
72 | return NETWORKTYPE_WIFI;
73 | }
74 | }
75 |
76 | // 如果不是wifi,则判断当前连接的是运营商的哪种网络2g、3g、4g等
77 | NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
78 |
79 | if (null != networkInfo) {
80 | NetworkInfo.State state = networkInfo.getState();
81 | String strSubTypeName = networkInfo.getSubtypeName();
82 | if (null != state)
83 | if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) {
84 | switch (activeNetworkInfo.getSubtype()) {
85 | //如果是2g类型
86 | case TelephonyManager.NETWORK_TYPE_GPRS: // 联通2g
87 | case TelephonyManager.NETWORK_TYPE_CDMA: // 电信2g
88 | case TelephonyManager.NETWORK_TYPE_EDGE: // 移动2g
89 | case TelephonyManager.NETWORK_TYPE_1xRTT:
90 | case TelephonyManager.NETWORK_TYPE_IDEN:
91 | return NETWORKTYPE_2G;
92 | //如果是3g类型
93 | case TelephonyManager.NETWORK_TYPE_EVDO_A: // 电信3g
94 | case TelephonyManager.NETWORK_TYPE_UMTS:
95 | case TelephonyManager.NETWORK_TYPE_EVDO_0:
96 | case TelephonyManager.NETWORK_TYPE_HSDPA:
97 | case TelephonyManager.NETWORK_TYPE_HSUPA:
98 | case TelephonyManager.NETWORK_TYPE_HSPA:
99 | case TelephonyManager.NETWORK_TYPE_EVDO_B:
100 | case TelephonyManager.NETWORK_TYPE_EHRPD:
101 | case TelephonyManager.NETWORK_TYPE_HSPAP:
102 | return NETWORKTYPE_3G;
103 | //如果是4g类型
104 | case TelephonyManager.NETWORK_TYPE_LTE:
105 | return NETWORKTYPE_4G;
106 | default:
107 | //中国移动 联通 电信 三种3G制式
108 | if (strSubTypeName.equalsIgnoreCase("TD-SCDMA") || strSubTypeName.equalsIgnoreCase("WCDMA") || strSubTypeName.equalsIgnoreCase("CDMA2000")) {
109 | return NETWORKTYPE_3G;
110 | } else {
111 | return NETWORKTYPE_MOBILE;
112 | }
113 | }
114 | }
115 | }
116 | return NETWORKTYPE_INVALID;
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/download/EasySimpleDownloadManager.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.download;
2 |
3 | import android.content.Context;
4 | import android.text.TextUtils;
5 | import android.util.Log;
6 |
7 | import com.yang.easyhttp.BuildConfig;
8 | import com.yang.easyhttp.cache.EasyCacheType;
9 | import com.yang.easyhttp.manager.EasyHttpClientManager;
10 | import com.yang.easyhttp.utils.EasyConstants;
11 |
12 | import java.io.File;
13 | import java.util.HashMap;
14 | import java.util.Iterator;
15 | import java.util.Map;
16 | import java.util.concurrent.LinkedBlockingQueue;
17 | import java.util.concurrent.ThreadPoolExecutor;
18 | import java.util.concurrent.TimeUnit;
19 |
20 | import okhttp3.OkHttpClient;
21 |
22 | /**
23 | * Created by yangy on 2017/2/16.
24 | */
25 | public class EasySimpleDownloadManager {
26 | private static EasySimpleDownloadManager mInstance;
27 |
28 | // ok http client
29 | private OkHttpClient mClient;
30 | // the thread count
31 | private int mThreadCount = 1;
32 | // ThreadPoolExecutor
33 | private ThreadPoolExecutor mExecutor;
34 | // task list
35 | private Map mCurrentTaskList;
36 | // queue
37 | private LinkedBlockingQueue mQueue;
38 |
39 | private EasySimpleDownloadManager() {
40 |
41 | }
42 |
43 | public static synchronized EasySimpleDownloadManager getInstance() {
44 | if (mInstance == null) {
45 | mInstance = new EasySimpleDownloadManager();
46 | }
47 |
48 | return mInstance;
49 | }
50 |
51 | public void init(Context context) {
52 | init(context, getAppropriateThreadCount());
53 | }
54 |
55 | public void init(Context context, int threadCount) {
56 | init(context, threadCount, getOkHttpClient());
57 | }
58 |
59 | public void init(Context context, int threadCount, OkHttpClient client) {
60 | mClient = client;
61 | mThreadCount = threadCount < 1 ? 1 : threadCount <= EasyConstants.MAX_THREAD_COUNT ? threadCount : EasyConstants.MAX_THREAD_COUNT;
62 | mExecutor = new ThreadPoolExecutor(
63 | mThreadCount,
64 | mThreadCount,
65 | 20,
66 | TimeUnit.MILLISECONDS,
67 | new LinkedBlockingQueue()
68 | );
69 | mCurrentTaskList = new HashMap<>();
70 | mQueue = (LinkedBlockingQueue) mExecutor.getQueue();
71 | }
72 |
73 | /**
74 | * generate default client
75 | */
76 | private OkHttpClient getOkHttpClient() {
77 | return EasyHttpClientManager.getInstance().getOkHttpClient(EasyCacheType.CACHE_TYPE_DEFAULT);
78 | }
79 |
80 | /**
81 | * @return generate the appropriate thread count.
82 | */
83 | private int getAppropriateThreadCount() {
84 | return Runtime.getRuntime().availableProcessors() * 2 + 1;
85 | }
86 |
87 | public void addTask(EasySimpleDownloadTask task) {
88 |
89 | synchronized (this) {
90 | EasyTaskEntity taskEntity = task.getTaskEntity();
91 |
92 | if (taskEntity != null
93 | && taskEntity.getTaskStatus() != EasyTaskStatus.TASK_STATUS_DOWNLOADING) {
94 | task.init();
95 | task.setClient(mClient);
96 | mCurrentTaskList.put(taskEntity.getTaskId(), task);
97 |
98 | if (!mQueue.contains(task)) {
99 | mExecutor.execute(task);
100 | }
101 |
102 | if (mExecutor.getTaskCount() > mThreadCount) {
103 | task.queue();
104 | }
105 | }
106 | }
107 | }
108 |
109 | public void pauseTask(EasySimpleDownloadTask task) {
110 | if (mQueue.contains(task)) {
111 | mQueue.remove(task);
112 | }
113 |
114 | task.pause();
115 | }
116 |
117 | public void resumeTask(EasySimpleDownloadTask task) {
118 | addTask(task);
119 | }
120 |
121 | public void cancelTask(EasySimpleDownloadTask task) {
122 | if (task == null) {
123 | return;
124 | }
125 |
126 | EasyTaskEntity taskEntity = task.getTaskEntity();
127 | if (taskEntity != null) {
128 | if (taskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_DOWNLOADING) {
129 | pauseTask(task);
130 | mExecutor.remove(task);
131 | }
132 |
133 | if (mQueue.contains(task)) {
134 | mQueue.remove(task);
135 | }
136 |
137 | mCurrentTaskList.remove(taskEntity.getTaskId());
138 |
139 | task.cancel();
140 |
141 | if (!TextUtils.isEmpty(taskEntity.getSaveDirPath())
142 | && !TextUtils.isEmpty(taskEntity.getSaveFileName())) {
143 | File temp = new File(taskEntity.getSaveDirPath(), taskEntity.getSaveFileName());
144 | if (temp.exists()) {
145 | if (temp.delete()) {
146 | if (BuildConfig.DEBUG)
147 | Log.d("DownloadManager", "delete temp file!");
148 | }
149 | }
150 | }
151 | }
152 | }
153 |
154 | public void deleteTaskInMemory(EasySimpleDownloadTask task) {
155 | synchronized (this) {
156 | if (task == null) {
157 | return;
158 | }
159 |
160 | final EasyTaskEntity taskEntity = task.getTaskEntity();
161 | if (taskEntity != null) {
162 | if (taskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_DOWNLOADING) {
163 | pauseTask(task);
164 | mExecutor.remove(task);
165 | }
166 |
167 | if (mQueue.contains(task)) {
168 | mQueue.remove(task);
169 | }
170 |
171 | mCurrentTaskList.remove(taskEntity.getTaskId());
172 | task.cancel();
173 | }
174 | }
175 | }
176 |
177 | public EasySimpleDownloadTask getTask(String taskId) {
178 | synchronized (this) {
179 | EasySimpleDownloadTask currTask = mCurrentTaskList.get(taskId);
180 | return currTask;
181 | }
182 | }
183 |
184 | public void cancelAllTask() {
185 | Iterator iterator = mCurrentTaskList.keySet().iterator();
186 |
187 | while (iterator.hasNext()) {
188 | String key = (String) iterator.next();
189 | EasySimpleDownloadTask task = mCurrentTaskList.get(key);
190 | EasyTaskEntity taskEntity = task.getTaskEntity();
191 | if (taskEntity != null) {
192 | if (taskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_DOWNLOADING) {
193 | pauseTask(task);
194 | mExecutor.remove(task);
195 | }
196 |
197 | if (mQueue.contains(task)) {
198 | mQueue.remove(task);
199 | }
200 |
201 | task.cancel();
202 | }
203 | iterator.remove();
204 | mCurrentTaskList.remove(taskEntity.getTaskId());
205 | }
206 | }
207 | }
208 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EasyHttp
2 | [](https://www.apache.org/licenses/LICENSE-2.0)
3 | [ ](https://bintray.com/laurenceyanger/maven/easyhttp-laurenceyanger/_latestVersion)
4 | Support RxJava[ ](https://bintray.com/laurenceyanger/maven/rxeasyhttp/_latestVersion)
5 | ## 特性
6 | * 支持Get/Post/Delete/Put请求
7 | * 完美支持String/Json/自定义对象返回
8 | * Get支持全局缓存设置及不同请求不同缓存设置
9 | * 支持Callback和RxJava2两种形式回调
10 | * 支持文件下载及下载管理
11 | * 支持文件下载的断点续传
12 | * 支持文件上传
13 | * 使用简单;轻量级代码;结构清晰
14 | * 基于okhttp3
15 | * 下载管理数据库使用greendao
16 |
17 | ## 最新版本
18 | * v0.8.0 - 2017.06.15 - 添加Delete/Put请求支持;下载添加404/403异常处理;容错性稳定性优化;其它细节优化
19 | * v0.7.0 - 2017.03.15 - Get/Post请求支持RxJava2
20 | * v0.6.0 - 2017.02.27 - Get/Post请求完美支持String,Json,自定义对象返回;下载模块添加异常检测及容错处理
21 | * v0.5.0 - 2017.02.21 - 初版发布,支持Get、Post、下载、上传、断点续传、不同缓存策略等
22 |
23 |
24 | ## ScreenShot
25 | 
26 |
27 | ## 使用指南
28 |
29 | ### With Gradle
30 |
31 | 在全局`build.gradle`文件的`repositories`添加如下所示配置:
32 |
33 | ```java
34 | jcenter()
35 | ```
36 | 在module的`build.gradle`文件的`dependencies`区域内添加如下所示配置:
37 |
38 | ```java
39 | compile 'com.yang.easyhttp:easyhttp:0.8.0'
40 | ```
41 |
42 | ## 初始化
43 |
44 | 在Applicaiton里进行初始化。
45 |
46 | ```java
47 | public class MainApplication extends Application {
48 |
49 | @Override
50 | public void onCreate() {
51 | super.onCreate();
52 |
53 | // 初始化HttpClient.
54 | EasyHttpClient.init(this);
55 |
56 | // 初始化下载环境.optional.
57 | EasyHttpClient.initDownloadEnvironment(2);
58 |
59 | }
60 | }
61 | ```
62 |
63 | ### Get 请求
64 |
65 | EasyHttp提供`EasyHttpClient.get`接口用来异步请求网络数据。返回自定义对象eg:
66 |
67 | ```java
68 | EasyHttpClient.get(url, new EasyCustomCallback() {
69 | @Override
70 | public void onStart() {//ui thread.
71 | dialog.show();
72 | }
73 |
74 | @Override
75 | public void onFinish() {//ui thread.
76 | dialog.cancel();
77 | }
78 |
79 | @Override
80 | public void onSuccess(Entity content) {//ui thread.
81 | // ui operation using content object.
82 | }
83 |
84 | @Override
85 | public void onFailure(Throwable error, String content) {//ui thread.
86 | body.setText(content + "\n" +error.toString());
87 | }
88 | });
89 | ```
90 |
91 | Get请求接口列表如下:
92 |
93 | ```java
94 | public static void get(String url, EasyCallback callback);
95 | public static void get(String url, EasyRequestParams easyRequestParams, EasyCallback callBack);
96 | public static void get(String url, int cacheType, EasyCallback callback);
97 | public static void get(String url, EasyRequestParams easyRequestParams, int cacheType, EasyCallback callback);
98 | ```
99 |
100 | 返回的是Json对象时,可以使用`EasyJsonCallback`作为回调。
101 |
102 | 返回的是普通的字符串,可以使用`EasyStringCallback`作为回调。
103 |
104 | `EasyRequestParams`用来设定请求的参数。
105 |
106 | `EasyCacheType`用来设定每个请求的缓存类型。
107 |
108 | ### Post请求
109 |
110 | EasyHttp提供`EasyHttpClient.post`接口用来异步post数据。
111 |
112 | ```java
113 | EasyRequestParams params = new EasyRequestParams();
114 | params.put("key1", "value1");
115 | params.put("key2", "value2");
116 |
117 | EasyHttpClient.post(postUrl,
118 | params,
119 | new EasyStringCallback() {
120 | @Override
121 | public void onStart() {
122 | dialog.show();
123 | }
124 |
125 | @Override
126 | public void onFinish() {
127 | dialog.cancel();
128 | }
129 |
130 | @Override
131 | public void onSuccess(String content) {
132 | Toast.makeText(PostActivity.this, "提交成功", Toast.LENGTH_LONG);
133 | result.setText(content);
134 | }
135 |
136 | @Override
137 | public void onFailure(Throwable error, String content) {
138 | Toast.makeText(PostActivity.this, "提交失败", Toast.LENGTH_LONG);
139 | result.setText(content + "\n" + error.getMessage());
140 | }
141 | }
142 | );
143 | ```
144 |
145 | Post请求接口列表如下:
146 |
147 | ```java
148 | public static void post(String url, EasyRequestParams easyRequestParams, EasyCallback callback)
149 | ```
150 |
151 | 同Get请求类似,返回的是Json数据,可以使用`EasyJsonCallback`类来作为回调。
152 |
153 | 返回的是普通的字符串,可以使用`EasyStringCallback`作为回调。
154 |
155 | `EasyRequestParams`用来设定post的键值对。
156 |
157 | ### Download File
158 |
159 | 初始化时可通过`initDownloadEnvironment(int threadCount)`来设定同时下载的数量。
160 |
161 | 跟下载相关的类包括:
162 |
163 | * EasyDownloadManager 负责管理下载任务
164 | * EasyDownloadTask 下载任务
165 | * EasyDownloadTaskListener 下载回调
166 | * EasyTaskEntity 任务的实体
167 | * EasyTaskStatus 下载的状态
168 |
169 | 关于下载的管理,可以参考sampe中的`DownloadAdapter`文件,实现了文件的下载,断点续传,进度展示等通用功能。
170 |
171 | ### Upload File
172 |
173 | EasyHttp提供`EasyHttpClient.uploadFile`接口用来上传文件。接口如下:
174 |
175 | ```
176 | public static void uploadFile(String url, String filePath, EasyCallback callback)
177 | ```
178 |
179 | ### 支持RxJava
180 | EasyHttp提供RxJava2的扩展,如需使用RxJava2回调方式,
181 | 在module的`build.gradle`文件的`dependencies`区域内如下所示进行配置:
182 |
183 | ```java
184 | compile 'com.yang.easyhttp:easyhttp:0.8.0'
185 | compile 'com.yang.rxeasyhttp:rxeasyhttp:0.8.0'
186 |
187 | ```
188 | ### Get请求的RxJava形式
189 | ```
190 | RxEasyHttp.get(url.toString(), new RxEasyStringConverter())
191 | .observeOn(AndroidSchedulers.mainThread())
192 | .subscribe(new FlowableSubscriber() {
193 | @Override
194 | public void onSubscribe(Subscription s) {
195 | s.request(Long.MAX_VALUE);
196 | dialog.show();
197 | body.setText("");
198 | }
199 |
200 | @Override
201 | public void onNext(String response) {
202 | body.setText(response);
203 | }
204 |
205 | @Override
206 | public void onError(Throwable t) {
207 | body.setText(t.toString());
208 | }
209 |
210 | @Override
211 | public void onComplete() {
212 | dialog.cancel();
213 | }
214 | });
215 | ```
216 | ### Post请求的RxJava形式
217 | ```
218 | RxEasyHttp.post(url, params, new RxEasyCustomConverter() {
219 | @Override
220 | public void doNothing() {}
221 | })
222 | .observeOn(AndroidSchedulers.mainThread())
223 | .subscribe(new FlowableSubscriber() {
224 |
225 | @Override
226 | public void onSubscribe(Subscription s) {
227 | s.request(Long.MAX_VALUE);
228 | dialog.show();
229 | }
230 |
231 | @Override
232 | public void onNext(PostEntity entity) {
233 | Toast.makeText(RxPostActivity.this, "提交成功", Toast.LENGTH_LONG).show();
234 | result.setText("status : " + entity.getStatus() + "\n" +
235 | "message : " + entity.getMessage());
236 |
237 | }
238 |
239 | @Override
240 | public void onError(Throwable t) {
241 | Toast.makeText(RxPostActivity.this, "提交失败", Toast.LENGTH_LONG).show();
242 | result.setText(t.getMessage());
243 | dialog.cancel();
244 | }
245 |
246 | @Override
247 | public void onComplete() {
248 | dialog.cancel();
249 | }
250 | });
251 | ```
252 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/download/EasyDownloadManager.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.download;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.text.TextUtils;
6 | import android.util.Log;
7 |
8 | import com.yang.easyhttp.BuildConfig;
9 | import com.yang.easyhttp.cache.EasyCacheType;
10 | import com.yang.easyhttp.db.EasyDaoManager;
11 | import com.yang.easyhttp.manager.EasyHttpClientManager;
12 | import com.yang.easyhttp.utils.EasyConstants;
13 |
14 | import java.io.File;
15 | import java.util.HashMap;
16 | import java.util.List;
17 | import java.util.Map;
18 | import java.util.concurrent.LinkedBlockingQueue;
19 | import java.util.concurrent.ThreadPoolExecutor;
20 | import java.util.concurrent.TimeUnit;
21 |
22 | import okhttp3.OkHttpClient;
23 |
24 | /**
25 | * Created by yangy on 2017/2/16.
26 | */
27 | public class EasyDownloadManager {
28 | private static EasyDownloadManager mInstance;
29 |
30 | // ok http client
31 | private OkHttpClient mClient;
32 | // the thread count
33 | private int mThreadCount = 1;
34 | // greenDao seesion
35 | private DaoSession mDaoSession;
36 | // ThreadPoolExecutor
37 | private ThreadPoolExecutor mExecutor;
38 | // task list
39 | private Map mCurrentTaskList;
40 | // queue
41 | private LinkedBlockingQueue mQueue;
42 |
43 | private EasyDownloadManager() {
44 |
45 | }
46 |
47 | public static synchronized EasyDownloadManager getInstance() {
48 | if (mInstance == null) {
49 | mInstance = new EasyDownloadManager();
50 | }
51 |
52 | return mInstance;
53 | }
54 |
55 | public void init(Context context) {
56 | init(context, getAppropriateThreadCount());
57 | }
58 |
59 | public void init(Context context, int threadCount) {
60 | init(context, threadCount, getOkHttpClient());
61 | }
62 |
63 | public void init(Context context, int threadCount, OkHttpClient client) {
64 | setupDatabase(context);
65 | recoveryTaskState();
66 |
67 | mClient = client;
68 | mThreadCount = threadCount < 1 ? 1 : threadCount <= EasyConstants.MAX_THREAD_COUNT ? threadCount : EasyConstants.MAX_THREAD_COUNT;
69 | mExecutor = new ThreadPoolExecutor(
70 | mThreadCount,
71 | mThreadCount,
72 | 20,
73 | TimeUnit.MILLISECONDS,
74 | new LinkedBlockingQueue()
75 | );
76 | mCurrentTaskList = new HashMap<>();
77 | mQueue = (LinkedBlockingQueue) mExecutor.getQueue();
78 | }
79 |
80 | private void setupDatabase(Context context) {
81 | DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "download.db", null);
82 | SQLiteDatabase db = helper.getWritableDatabase();
83 | DaoMaster master = new DaoMaster(db);
84 | mDaoSession = master.newSession();
85 | }
86 |
87 | public DaoSession getDaoSession() {
88 | return mDaoSession;
89 | }
90 |
91 | /**
92 | * generate default client
93 | */
94 | private OkHttpClient getOkHttpClient() {
95 | return EasyHttpClientManager.getInstance().getOkHttpClient(EasyCacheType.CACHE_TYPE_DEFAULT);
96 | }
97 |
98 | /**
99 | * @return generate the appropriate thread count.
100 | */
101 | private int getAppropriateThreadCount() {
102 | return Runtime.getRuntime().availableProcessors() * 2 + 1;
103 | }
104 |
105 | public void addTask(EasyDownloadTask task) {
106 | EasyTaskEntity taskEntity = task.getTaskEntity();
107 |
108 | if (taskEntity != null
109 | && taskEntity.getTaskStatus() != EasyTaskStatus.TASK_STATUS_DOWNLOADING) {
110 | task.init();
111 | task.setClient(mClient);
112 | mCurrentTaskList.put(taskEntity.getTaskId(), task);
113 |
114 | if (!mQueue.contains(task)) {
115 | mExecutor.execute(task);
116 | }
117 |
118 | if (mExecutor.getTaskCount() > mThreadCount) {
119 | task.queue();
120 | }
121 | }
122 | }
123 |
124 | public void pauseTask(EasyDownloadTask task) {
125 | if (mQueue.contains(task)) {
126 | mQueue.remove(task);
127 | }
128 |
129 | task.pause();
130 | }
131 |
132 | public void resumeTask(EasyDownloadTask task) {
133 | addTask(task);
134 | }
135 |
136 | public void cancelTask(EasyDownloadTask task) {
137 | if(task == null) {
138 | return;
139 | }
140 |
141 | EasyTaskEntity taskEntity = task.getTaskEntity();
142 | if (taskEntity != null) {
143 | if (taskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_DOWNLOADING) {
144 | pauseTask(task);
145 | mExecutor.remove(task);
146 | }
147 |
148 | if (mQueue.contains(task)) {
149 | mQueue.remove(task);
150 | }
151 |
152 | mCurrentTaskList.remove(taskEntity.getTaskId());
153 |
154 | task.cancel();
155 |
156 | if (!TextUtils.isEmpty(taskEntity.getSaveDirPath())
157 | && !TextUtils.isEmpty(taskEntity.getSaveFileName())) {
158 | File temp = new File(taskEntity.getSaveDirPath(), taskEntity.getSaveFileName());
159 | if (temp.exists()) {
160 | if (temp.delete()) {
161 | if (BuildConfig.DEBUG)
162 | Log.d("DownloadManager", "delete temp file!");
163 | }
164 | }
165 | }
166 | }
167 | }
168 |
169 | public EasyDownloadTask getTask(String taskId) {
170 | EasyDownloadTask currTask = mCurrentTaskList.get(taskId);
171 | if (currTask == null) {
172 | EasyTaskEntity entity = EasyDaoManager.instance().queryWithId(taskId);
173 | if (entity != null) {
174 | int status = entity.getTaskStatus();
175 | currTask = new EasyDownloadTask(entity);
176 | if (status != EasyTaskStatus.TASK_STATUS_FINISH) {
177 | mCurrentTaskList.put(taskId, currTask);
178 | }
179 | }
180 | }
181 |
182 | // // 如果下载完成,判断本地是否被删除.
183 | // if (currTask != null) {
184 | // EasyTaskEntity entity = currTask.getTaskEntity();
185 | // int status = entity.getTaskStatus();
186 | // if (status == EasyTaskStatus.TASK_STATUS_FINISH) {
187 | // String saveDirPath = entity.getSaveDirPath();
188 | // String saveFileName = entity.getSaveFileName();
189 | // if (TextUtils.isEmpty(saveDirPath) || TextUtils.isEmpty(saveFileName)) {
190 | // return currTask;
191 | // }
192 | //
193 | // File file = new File(saveDirPath, saveFileName);
194 | // if (!file.exists()) {
195 | // mCurrentTaskList.remove(taskId);
196 | // EasyDaoManager.instance().delete(entity);
197 | // }
198 | // }
199 | // }
200 |
201 | return currTask;
202 | }
203 |
204 | public boolean isPauseTask(String taskId) {
205 | EasyTaskEntity entity = EasyDaoManager.instance().queryWithId(taskId);
206 | if (entity != null) {
207 | File file = new File(entity.getSaveDirPath(), entity.getSaveFileName());
208 | if (file.exists()) {
209 | long totalSize = entity.getTotalSize();
210 | return totalSize > 0 && file.length() < totalSize;
211 | }
212 | }
213 | return false;
214 | }
215 |
216 | public boolean isFinishTask(String taskId) {
217 | EasyTaskEntity entity = EasyDaoManager.instance().queryWithId(taskId);
218 | if (entity != null) {
219 | File file = new File(entity.getSaveDirPath(), entity.getSaveFileName());
220 | if (file.exists()) {
221 | return file.length() == entity.getTotalSize();
222 | }
223 | }
224 |
225 | return false;
226 | }
227 |
228 | private void recoveryTaskState() {
229 | List entities = EasyDaoManager.instance().queryAll();
230 |
231 | for (EasyTaskEntity entity : entities) {
232 | long completedSize = entity.getCompletedSize();
233 | long totalSize = entity.getTotalSize();
234 | if (completedSize > 0 &&
235 | completedSize < totalSize &&
236 | entity.getTaskStatus() != EasyTaskStatus.TASK_STATUS_PAUSE) {
237 | entity.setTaskStatus(EasyTaskStatus.TASK_STATUS_PAUSE);
238 | EasyDaoManager.instance().update(entity);
239 | }
240 | }
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/download/EasySimpleDownloadTask.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.download;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 | import android.os.Message;
6 | import android.text.TextUtils;
7 | import android.util.Log;
8 |
9 | import com.yang.easyhttp.cache.EasyCacheType;
10 | import com.yang.easyhttp.manager.EasyHttpClientManager;
11 | import com.yang.easyhttp.utils.EasyFileUtils;
12 | import com.yang.easyhttp.utils.EasyIOUtils;
13 |
14 | import java.io.BufferedInputStream;
15 | import java.io.File;
16 | import java.io.FileNotFoundException;
17 | import java.io.IOException;
18 | import java.io.InputStream;
19 | import java.io.RandomAccessFile;
20 | import java.net.SocketTimeoutException;
21 |
22 | import okhttp3.OkHttpClient;
23 | import okhttp3.Request;
24 | import okhttp3.Response;
25 | import okhttp3.ResponseBody;
26 |
27 | /**
28 | * Created by yangy on 2017/2/16.
29 | */
30 | public class EasySimpleDownloadTask implements Runnable {
31 | private OkHttpClient mClient;
32 | private EasySimpleDownloadTaskListener mSimpleDownloadTaskListener;
33 | private EasyTaskEntity mTaskEntity;
34 | private Handler mHandler = new Handler(Looper.getMainLooper()) {
35 | @Override
36 | public void handleMessage(Message msg) {
37 | if (mSimpleDownloadTaskListener == null) {
38 | return;
39 | }
40 | int code = msg.what;
41 | switch (code) {
42 | case EasyTaskStatus.TASK_STATUS_INIT:
43 | break;
44 | case EasyTaskStatus.TASK_STATUS_QUEUE:
45 | mSimpleDownloadTaskListener.onQueue(EasySimpleDownloadTask.this);
46 | break;
47 | case EasyTaskStatus.TASK_STATUS_CONNECTING:
48 | mSimpleDownloadTaskListener.onConnecting(EasySimpleDownloadTask.this);
49 | break;
50 | case EasyTaskStatus.TASK_STATUS_DOWNLOADING:
51 | mSimpleDownloadTaskListener.onDownloading(EasySimpleDownloadTask.this);
52 | break;
53 | case EasyTaskStatus.TASK_STATUS_PAUSE:
54 | mSimpleDownloadTaskListener.onPause(EasySimpleDownloadTask.this);
55 | break;
56 | case EasyTaskStatus.TASK_STATUS_CANCEL:
57 | mSimpleDownloadTaskListener.onCancel(EasySimpleDownloadTask.this);
58 | break;
59 | case EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR:
60 | mSimpleDownloadTaskListener.onError(EasySimpleDownloadTask.this, EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
61 | break;
62 | case EasyTaskStatus.TASK_STATUS_REQUEST_ERROR:
63 | mSimpleDownloadTaskListener.onError(EasySimpleDownloadTask.this, EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
64 | break;
65 | case EasyTaskStatus.TASK_STATUS_STORAGE_ERROR:
66 | mSimpleDownloadTaskListener.onError(EasySimpleDownloadTask.this, EasyTaskStatus.TASK_STATUS_STORAGE_ERROR);
67 | break;
68 | case EasyTaskStatus.TASK_STATUS_FINISH:
69 | mSimpleDownloadTaskListener.onFinish(EasySimpleDownloadTask.this);
70 | break;
71 | default:
72 | break;
73 | }
74 | }
75 | };
76 |
77 | public EasySimpleDownloadTask(EasyTaskEntity taskEntity) {
78 | mClient = EasyHttpClientManager.getInstance().getOkHttpClient(EasyCacheType.CACHE_TYPE_DEFAULT);
79 | mTaskEntity = taskEntity;
80 | }
81 |
82 | public void setClient(OkHttpClient client) {
83 | this.mClient = client;
84 | }
85 |
86 | public void setSimpleDownloadTaskListener(EasySimpleDownloadTaskListener simpleDownloadTaskListener) {
87 | this.mSimpleDownloadTaskListener = simpleDownloadTaskListener;
88 | }
89 |
90 | public EasyTaskEntity getTaskEntity() {
91 | return mTaskEntity;
92 | }
93 |
94 | @Override
95 | public void run() {
96 | InputStream inputStream = null;
97 | BufferedInputStream bufferedInputStream = null;
98 | RandomAccessFile randomAccessFile = null;
99 |
100 | try {
101 | String saveDirPath = mTaskEntity.getSaveDirPath();
102 | if (TextUtils.isEmpty(saveDirPath)) {
103 | saveDirPath = EasyFileUtils.getDefaultFilePath(EasyHttpClientManager.getInstance().getContext());
104 | mTaskEntity.setSaveDirPath(saveDirPath);
105 | }
106 |
107 | File file = new File(saveDirPath);
108 | if (!file.exists()) {
109 | boolean created = file.mkdirs();
110 | if (!created) {
111 | throw new FileNotFoundException("save dir path not created");
112 | }
113 | }
114 |
115 | String saveFileName = mTaskEntity.getSaveFileName();
116 | if (TextUtils.isEmpty(saveFileName)) {
117 | saveFileName = EasyFileUtils.getFileNameFromUrl(mTaskEntity.getDownloadUrl());
118 | mTaskEntity.setSaveFileName(saveFileName);
119 | }
120 |
121 | File saveFile = new File(saveDirPath, saveFileName);
122 | File saveTempFile = new File(saveDirPath, saveFileName + ".tmp");
123 | randomAccessFile = new RandomAccessFile(saveTempFile, "rwd");
124 |
125 | if (mTaskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_CANCEL ||
126 | mTaskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_PAUSE) {
127 | // 任何步骤都可能插入暂停操作.
128 | EasyIOUtils.close(bufferedInputStream, inputStream, randomAccessFile);
129 | return;
130 | } else {
131 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_CONNECTING);
132 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_CONNECTING);
133 | }
134 |
135 | // 异常检测及下载错误校正.
136 | long completedSize = mTaskEntity.getCompletedSize();
137 | long fileLength = randomAccessFile.length();
138 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],fileLength[" + fileLength + "],completedSize[" + completedSize + "]");
139 |
140 | if (completedSize > 0 && fileLength != completedSize) {
141 | // 比较激进的容错方案.
142 | completedSize = fileLength;
143 | mTaskEntity.setCompletedSize(fileLength);
144 | }
145 |
146 | Request request = new Request.Builder()
147 | .url(mTaskEntity.getDownloadUrl())
148 | .header("RANGE", "bytes=" + completedSize + "-")
149 | .build();
150 |
151 | randomAccessFile.seek(completedSize);
152 |
153 | Response response = mClient.newCall(request).execute();
154 |
155 | if (response.isSuccessful()) {
156 | ResponseBody responseBody = response.body();
157 | if (responseBody != null) {
158 | if (mTaskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_CANCEL ||
159 | mTaskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_PAUSE) {
160 | // 任何步骤都可能插入暂停操作.
161 | EasyIOUtils.close(bufferedInputStream, inputStream, randomAccessFile);
162 | return;
163 | } else {
164 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_DOWNLOADING);
165 | }
166 | long contentLength = responseBody.contentLength();
167 | if (contentLength == -1) {
168 | // 下载链接存在问题.
169 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
170 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
171 | return;
172 | }
173 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],contentLength[" + contentLength + "]");
174 | mTaskEntity.setTotalSize(contentLength + completedSize);
175 |
176 | long fileTotalSize = mTaskEntity.getTotalSize();
177 |
178 | double updateSize = fileTotalSize / 100;
179 | inputStream = responseBody.byteStream();
180 | bufferedInputStream = new BufferedInputStream(inputStream);
181 | byte[] buffer = new byte[1024];
182 | int length;
183 | int buffOffset = 0;
184 |
185 | while ((length = bufferedInputStream.read(buffer)) > 0
186 | && mTaskEntity.getTaskStatus() != EasyTaskStatus.TASK_STATUS_CANCEL
187 | && mTaskEntity.getTaskStatus() != EasyTaskStatus.TASK_STATUS_PAUSE) {
188 | randomAccessFile.write(buffer, 0, length);
189 | completedSize += length;
190 | buffOffset += length;
191 |
192 | mTaskEntity.setCompletedSize(completedSize);
193 | //避免一直调用数据库.
194 | if (buffOffset >= updateSize) {
195 | buffOffset = 0;
196 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_DOWNLOADING);
197 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],totalSize[" + fileTotalSize + "],completedSize[" + completedSize + "]");
198 | }
199 | if (completedSize == fileTotalSize) {
200 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],totalSize[" + fileTotalSize + "],completedSize[" + completedSize + "]");
201 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_DOWNLOADING);
202 | saveTempFile.renameTo(saveFile);
203 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_FINISH);
204 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_FINISH);
205 | }
206 | }
207 |
208 |
209 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],exception:totalSize[" + fileTotalSize + "],completedSize[" + completedSize + "]");
210 | }
211 | } else if (response.code() == 403 || response.code() == 404) {
212 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],response.code()[" + response.code() + "]");
213 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
214 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
215 | } else {
216 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],response.code()[" + response.code() + "]");
217 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
218 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
219 | }
220 |
221 | } catch (FileNotFoundException e) {
222 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "]FileNotFoundException");
223 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_STORAGE_ERROR);
224 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_STORAGE_ERROR);
225 | e.printStackTrace();
226 | } catch (SocketTimeoutException e) {
227 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "]SocketTimeoutException");
228 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
229 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
230 | e.printStackTrace();
231 | } catch (IOException e) {
232 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "]IOException");
233 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
234 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
235 | e.printStackTrace();
236 | } finally {
237 | EasyIOUtils.close(bufferedInputStream, inputStream, randomAccessFile);
238 | }
239 | }
240 |
241 | public void pause() {
242 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_PAUSE);
243 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_PAUSE);
244 | }
245 |
246 | public void init() {
247 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_INIT);
248 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_INIT);
249 | }
250 |
251 | public void queue() {
252 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_QUEUE);
253 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_QUEUE);
254 | }
255 |
256 | public void cancel() {
257 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_CANCEL);
258 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_CANCEL);
259 | }
260 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/yang/demo/adapter/DownloadAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yang.demo.adapter;
2 |
3 | import android.app.DownloadManager;
4 | import android.content.Context;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.Button;
10 | import android.widget.ProgressBar;
11 | import android.widget.TextView;
12 | import android.widget.Toast;
13 |
14 | import com.yang.demo.entity.DownloadEntity;
15 | import com.yang.demo.R;
16 | import com.yang.easyhttp.download.EasyDownloadManager;
17 | import com.yang.easyhttp.download.EasyDownloadTask;
18 | import com.yang.easyhttp.download.EasyDownloadTaskListener;
19 | import com.yang.easyhttp.download.EasyTaskEntity;
20 | import com.yang.easyhttp.download.EasyTaskStatus;
21 |
22 | import java.text.DecimalFormat;
23 | import java.util.ArrayList;
24 |
25 | import butterknife.BindView;
26 | import butterknife.ButterKnife;
27 |
28 | /**
29 | * Created by yangyang on 2017/2/17.
30 | */
31 | public class DownloadAdapter extends RecyclerView.Adapter {
32 | private ArrayList mList;
33 | private Context mContext;
34 | private EasyDownloadManager mDownloadManger;
35 |
36 | public DownloadAdapter(Context context) {
37 | this.mContext = context;
38 | }
39 |
40 | public void setData(ArrayList list) {
41 | mList = list;
42 | notifyDataSetChanged();
43 | mDownloadManger = EasyDownloadManager.getInstance();
44 | }
45 |
46 | @Override
47 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
48 | View view = LayoutInflater.from(mContext).inflate(R.layout.download_item, parent, false);
49 | return new ViewHolder(view);
50 | }
51 |
52 | @Override
53 | public void onBindViewHolder(final ViewHolder holder, int position) {
54 | DownloadEntity entity = mList.get(position);
55 | final String url = entity.getUrl();
56 | String taskId = entity.getHashCode();
57 | final EasyDownloadTask task = mDownloadManger.getTask(taskId);
58 |
59 | holder.itemView.setTag(url);
60 |
61 | if (task == null) {
62 | holder.button.setText(R.string.start);
63 | holder.progressTxt.setText("0");
64 | holder.progress.setProgress(0);
65 | } else {
66 | EasyTaskEntity easyTaskEntity = task.getTaskEntity();
67 | final int status = easyTaskEntity.getTaskStatus();
68 | responseUIListener(task, holder);
69 |
70 | String progress = getPercent(easyTaskEntity.getCompletedSize(), easyTaskEntity.getTotalSize());
71 |
72 | switch (status) {
73 | case EasyTaskStatus.TASK_STATUS_INIT:
74 | boolean isPause = mDownloadManger.isPauseTask(easyTaskEntity.getTaskId());
75 | boolean isFinish = mDownloadManger.isFinishTask(easyTaskEntity.getTaskId());
76 | holder.button.setText(isFinish ? R.string.delete : !isPause ? R.string.start : R.string.resume);
77 | holder.progress.setProgress(Integer.parseInt(progress));
78 | holder.progressTxt.setText(progress);
79 | break;
80 | case EasyTaskStatus.TASK_STATUS_QUEUE:
81 | holder.button.setText(R.string.queue);
82 | holder.progress.setProgress(Integer.parseInt(progress));
83 | holder.progressTxt.setText(progress);
84 | break;
85 | case EasyTaskStatus.TASK_STATUS_CONNECTING:
86 | holder.button.setText(R.string.connecting);
87 | holder.progress.setProgress(Integer.parseInt(progress));
88 | holder.progressTxt.setText(progress);
89 | break;
90 | case EasyTaskStatus.TASK_STATUS_DOWNLOADING:
91 | holder.button.setText(R.string.pause);
92 | holder.progress.setProgress(Integer.parseInt(progress));
93 | holder.progressTxt.setText(progress);
94 | break;
95 | case EasyTaskStatus.TASK_STATUS_PAUSE:
96 | holder.button.setText(R.string.resume);
97 | holder.progress.setProgress(Integer.parseInt(progress));
98 | holder.progressTxt.setText(progress);
99 | break;
100 | case EasyTaskStatus.TASK_STATUS_FINISH:
101 | holder.button.setText(R.string.delete);
102 | holder.progress.setProgress(100);
103 | holder.progressTxt.setText(progress);
104 | break;
105 | case EasyTaskStatus.TASK_STATUS_REQUEST_ERROR:
106 | case EasyTaskStatus.TASK_STATUS_STORAGE_ERROR:
107 | holder.button.setText(R.string.retry);
108 | holder.progress.setProgress(Integer.parseInt(progress));
109 | holder.progressTxt.setText(progress);
110 | break;
111 | }
112 | }
113 |
114 | holder.title.setText(entity.getTitle());
115 |
116 | holder.button.setOnClickListener(new View.OnClickListener() {
117 | @Override
118 | public void onClick(View v) {
119 | String taskId = String.valueOf(holder.itemView.getTag().hashCode());
120 | EasyDownloadTask task = mDownloadManger.getTask(taskId);
121 |
122 | if (task == null) {
123 | task = new EasyDownloadTask(new EasyTaskEntity.Builder().taskId(taskId).downloadUrl(url).build());
124 | responseUIListener(task, holder);
125 | mDownloadManger.addTask(task);
126 | } else {
127 | responseUIListener(task, holder);
128 | EasyTaskEntity easyTaskEntity = task.getTaskEntity();
129 | final int status = easyTaskEntity.getTaskStatus();
130 | responseUIListener(task, holder);
131 |
132 | switch (status) {
133 | case EasyTaskStatus.TASK_STATUS_QUEUE:
134 | mDownloadManger.pauseTask(task);
135 | break;
136 | case EasyTaskStatus.TASK_STATUS_INIT:
137 | mDownloadManger.addTask(task);
138 | break;
139 | case EasyTaskStatus.TASK_STATUS_CONNECTING:
140 | mDownloadManger.pauseTask(task);
141 | break;
142 | case EasyTaskStatus.TASK_STATUS_DOWNLOADING:
143 | mDownloadManger.pauseTask(task);
144 | break;
145 | case EasyTaskStatus.TASK_STATUS_CANCEL:
146 | mDownloadManger.addTask(task);
147 | break;
148 | case EasyTaskStatus.TASK_STATUS_PAUSE:
149 | mDownloadManger.resumeTask(task);
150 | break;
151 | case EasyTaskStatus.TASK_STATUS_FINISH:
152 | mDownloadManger.cancelTask(task);
153 | break;
154 | case EasyTaskStatus.TASK_STATUS_REQUEST_ERROR:
155 | case EasyTaskStatus.TASK_STATUS_STORAGE_ERROR:
156 | mDownloadManger.addTask(task);
157 | break;
158 | }
159 |
160 | }
161 | }
162 | });
163 | }
164 |
165 | private void responseUIListener(EasyDownloadTask task, final ViewHolder holder) {
166 | final EasyTaskEntity taskEntity = task.getTaskEntity();
167 |
168 | task.setDownloadTaskListener(new EasyDownloadTaskListener() {
169 | @Override
170 | public void onQueue(EasyDownloadTask downloadTask) {
171 | if (holder.itemView.getTag().equals(taskEntity.getDownloadUrl())) {
172 | holder.button.setText(R.string.queue);
173 | }
174 | }
175 |
176 | @Override
177 | public void onConnecting(EasyDownloadTask downloadTask) {
178 | if (holder.itemView.getTag().equals(taskEntity.getDownloadUrl())) {
179 | holder.button.setText(R.string.connecting);
180 | }
181 | }
182 |
183 | @Override
184 | public void onDownloading(EasyDownloadTask downloadTask) {
185 | if (holder.itemView.getTag().equals(taskEntity.getDownloadUrl())) {
186 | if (holder.itemView.getTag().equals(taskEntity.getDownloadUrl())) {
187 | holder.button.setText(R.string.pause);
188 | holder.progress.setProgress(Integer.parseInt(getPercent(taskEntity.getCompletedSize(), taskEntity.getTotalSize())));
189 | holder.progressTxt.setText(getPercent(taskEntity.getCompletedSize(), taskEntity.getTotalSize()));
190 | }
191 | }
192 | }
193 |
194 | @Override
195 | public void onPause(EasyDownloadTask downloadTask) {
196 | if (holder.itemView.getTag().equals(taskEntity.getDownloadUrl())) {
197 | holder.button.setText(R.string.resume);
198 | }
199 | }
200 |
201 | @Override
202 | public void onCancel(EasyDownloadTask downloadTask) {
203 | if (holder.itemView.getTag().equals(taskEntity.getDownloadUrl())) {
204 | holder.button.setText(R.string.start);
205 | holder.progressTxt.setText("0");
206 | holder.progress.setProgress(0);
207 | }
208 | }
209 |
210 | @Override
211 | public void onFinish(EasyDownloadTask downloadTask) {
212 | if (holder.itemView.getTag().equals(taskEntity.getDownloadUrl())) {
213 | holder.button.setText(R.string.delete);
214 | }
215 | }
216 |
217 | @Override
218 | public void onError(EasyDownloadTask downloadTask, int code) {
219 | if (holder.itemView.getTag().equals(taskEntity.getDownloadUrl())) {
220 | holder.button.setText(R.string.retry);
221 |
222 | switch (code) {
223 | case EasyTaskStatus.TASK_STATUS_REQUEST_ERROR:
224 | Toast.makeText(mContext, R.string.request_error, Toast.LENGTH_SHORT).show();
225 | break;
226 | case EasyTaskStatus.TASK_STATUS_STORAGE_ERROR:
227 | Toast.makeText(mContext, R.string.storage_error, Toast.LENGTH_SHORT).show();
228 | break;
229 | }
230 | }
231 | }
232 | });
233 | }
234 |
235 | @Override
236 | public int getItemCount() {
237 | return mList != null ? mList.size() : 0;
238 | }
239 |
240 | private String getPercent(long completed, long total) {
241 | if (total > 0) {
242 | double fen = ((double)completed/(double)total) * 100;
243 | DecimalFormat df = new DecimalFormat("0");
244 | return df.format(fen);
245 | }
246 |
247 | return "0";
248 | }
249 |
250 | class ViewHolder extends RecyclerView.ViewHolder {
251 | @BindView(R.id.title)
252 | TextView title;
253 | @BindView(R.id.progress)
254 | ProgressBar progress;
255 | @BindView(R.id.progress_txt)
256 | TextView progressTxt;
257 | @BindView(R.id.button)
258 | Button button;
259 |
260 | public ViewHolder(View itemView) {
261 | super(itemView);
262 | ButterKnife.bind(this, itemView);
263 | }
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/download/EasyDownloadTask.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.download;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 | import android.os.Message;
6 | import android.text.TextUtils;
7 | import android.util.Log;
8 |
9 | import com.yang.easyhttp.cache.EasyCacheType;
10 | import com.yang.easyhttp.db.EasyDaoManager;
11 | import com.yang.easyhttp.manager.EasyHttpClientManager;
12 | import com.yang.easyhttp.utils.EasyIOUtils;
13 | import com.yang.easyhttp.utils.EasyFileUtils;
14 |
15 | import java.io.BufferedInputStream;
16 | import java.io.File;
17 | import java.io.FileNotFoundException;
18 | import java.io.IOException;
19 | import java.io.InputStream;
20 | import java.io.RandomAccessFile;
21 | import java.net.SocketTimeoutException;
22 |
23 | import okhttp3.OkHttpClient;
24 | import okhttp3.Request;
25 | import okhttp3.Response;
26 | import okhttp3.ResponseBody;
27 |
28 | /**
29 | * Created by yangy on 2017/2/16.
30 | */
31 | public class EasyDownloadTask implements Runnable {
32 | private OkHttpClient mClient;
33 | private EasyDownloadTaskListener mDownloadTaskListener;
34 | private EasyTaskEntity mTaskEntity;
35 | private Handler mHandler = new Handler(Looper.getMainLooper()) {
36 | @Override
37 | public void handleMessage(Message msg) {
38 | if (mDownloadTaskListener == null) {
39 | return;
40 | }
41 | int code = msg.what;
42 | switch (code) {
43 | case EasyTaskStatus.TASK_STATUS_INIT:
44 | break;
45 | case EasyTaskStatus.TASK_STATUS_QUEUE:
46 | mDownloadTaskListener.onQueue(EasyDownloadTask.this);
47 | break;
48 | case EasyTaskStatus.TASK_STATUS_CONNECTING:
49 | mDownloadTaskListener.onConnecting(EasyDownloadTask.this);
50 | break;
51 | case EasyTaskStatus.TASK_STATUS_DOWNLOADING:
52 | mDownloadTaskListener.onDownloading(EasyDownloadTask.this);
53 | break;
54 | case EasyTaskStatus.TASK_STATUS_PAUSE:
55 | mDownloadTaskListener.onPause(EasyDownloadTask.this);
56 | break;
57 | case EasyTaskStatus.TASK_STATUS_CANCEL:
58 | mDownloadTaskListener.onCancel(EasyDownloadTask.this);
59 | break;
60 | case EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR:
61 | mDownloadTaskListener.onError(EasyDownloadTask.this, EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
62 | break;
63 | case EasyTaskStatus.TASK_STATUS_REQUEST_ERROR:
64 | mDownloadTaskListener.onError(EasyDownloadTask.this, EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
65 | break;
66 | case EasyTaskStatus.TASK_STATUS_STORAGE_ERROR:
67 | mDownloadTaskListener.onError(EasyDownloadTask.this, EasyTaskStatus.TASK_STATUS_STORAGE_ERROR);
68 | break;
69 | case EasyTaskStatus.TASK_STATUS_FINISH:
70 | mDownloadTaskListener.onFinish(EasyDownloadTask.this);
71 | break;
72 | default:
73 | break;
74 | }
75 | }
76 | };
77 |
78 | public EasyDownloadTask(EasyTaskEntity taskEntity) {
79 | mClient = EasyHttpClientManager.getInstance().getOkHttpClient(EasyCacheType.CACHE_TYPE_DEFAULT);
80 | mTaskEntity = taskEntity;
81 | }
82 |
83 | public void setClient(OkHttpClient client) {
84 | this.mClient = client;
85 | }
86 |
87 | public void setDownloadTaskListener(EasyDownloadTaskListener downloadTaskListener) {
88 | this.mDownloadTaskListener = downloadTaskListener;
89 | }
90 |
91 | public EasyTaskEntity getTaskEntity() {
92 | return mTaskEntity;
93 | }
94 |
95 | @Override
96 | public void run() {
97 | InputStream inputStream = null;
98 | BufferedInputStream bufferedInputStream = null;
99 | RandomAccessFile randomAccessFile = null;
100 |
101 | try {
102 | String saveDirPath = mTaskEntity.getSaveDirPath();
103 | if (TextUtils.isEmpty(saveDirPath)) {
104 | saveDirPath = EasyFileUtils.getDefaultFilePath(EasyHttpClientManager.getInstance().getContext());
105 | mTaskEntity.setSaveDirPath(saveDirPath);
106 | }
107 |
108 | File file = new File(saveDirPath);
109 | if (!file.exists()) {
110 | boolean created = file.mkdirs();
111 | if (!created) {
112 | throw new FileNotFoundException("save dir path not created");
113 | }
114 | }
115 |
116 | String saveFileName = mTaskEntity.getSaveFileName();
117 | if (TextUtils.isEmpty(saveFileName)) {
118 | saveFileName = EasyFileUtils.getFileNameFromUrl(mTaskEntity.getDownloadUrl());
119 | mTaskEntity.setSaveFileName(saveFileName);
120 | }
121 |
122 | File saveFile = new File(saveDirPath, saveFileName);
123 | randomAccessFile = new RandomAccessFile(saveFile, "rwd");
124 |
125 | if (mTaskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_CANCEL ||
126 | mTaskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_PAUSE) {
127 | // 任何步骤都可能插入暂停操作.
128 | EasyIOUtils.close(bufferedInputStream, inputStream, randomAccessFile);
129 | return;
130 | } else {
131 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_CONNECTING);
132 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_CONNECTING);
133 | }
134 |
135 | // 异常检测及下载错误校正.
136 | long completedSize = mTaskEntity.getCompletedSize();
137 | long fileLength = randomAccessFile.length();
138 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],fileLength[" + fileLength + "],completedSize[" + completedSize + "]");
139 | // if (completedSize > 0 && fileLength != completedSize) {
140 | // // 最保险的容错方案.
141 | // completedSize = 0;
142 | // mTaskEntity.setTotalSize(0);
143 | // mTaskEntity.setCompletedSize(0);
144 | // if (EasyDaoManager.instance().queryWithId(mTaskEntity.getTaskId()) != null) {
145 | // EasyDaoManager.instance().delete(mTaskEntity);
146 | // }
147 | // }
148 | if (completedSize > 0 && fileLength != completedSize) {
149 | // 比较激进的容错方案.
150 | completedSize = fileLength;
151 | mTaskEntity.setCompletedSize(fileLength);
152 | }
153 |
154 | if (EasyDaoManager.instance().queryWithId(mTaskEntity.getTaskId()) != null) {
155 | EasyDaoManager.instance().update(mTaskEntity);
156 | }
157 |
158 | Request request = new Request.Builder()
159 | .url(mTaskEntity.getDownloadUrl())
160 | .header("RANGE", "bytes=" + completedSize + "-")
161 | .build();
162 |
163 | randomAccessFile.seek(completedSize);
164 |
165 | Response response = mClient.newCall(request).execute();
166 |
167 | if (response.isSuccessful()) {
168 | ResponseBody responseBody = response.body();
169 | if (responseBody != null) {
170 | if (mTaskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_CANCEL ||
171 | mTaskEntity.getTaskStatus() == EasyTaskStatus.TASK_STATUS_PAUSE) {
172 | // 任何步骤都可能插入暂停操作.
173 | EasyIOUtils.close(bufferedInputStream, inputStream, randomAccessFile);
174 | return;
175 | } else {
176 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_DOWNLOADING);
177 | }
178 | long contentLength = responseBody.contentLength();
179 | if (contentLength == -1) {
180 | // 下载链接存在问题.
181 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
182 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
183 | return;
184 | }
185 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],contentLength[" + contentLength + "]");
186 | if (EasyDaoManager.instance().queryWithId(mTaskEntity.getTaskId()) == null) {
187 | // 首次下载记录总的长度,并保存入数据库.
188 | mTaskEntity.setTotalSize(contentLength + completedSize);
189 | EasyDaoManager.instance().insertOrReplace(mTaskEntity);
190 | } else {
191 | // 断点续传情况下,更新总长度.
192 | mTaskEntity.setTotalSize(contentLength + completedSize);
193 | EasyDaoManager.instance().update(mTaskEntity);
194 | }
195 |
196 | long fileTotalSize = mTaskEntity.getTotalSize();
197 |
198 | double updateSize = fileTotalSize / 100;
199 | inputStream = responseBody.byteStream();
200 | bufferedInputStream = new BufferedInputStream(inputStream);
201 | byte[] buffer = new byte[1024];
202 | int length;
203 | int buffOffset = 0;
204 |
205 | while ((length = bufferedInputStream.read(buffer)) > 0
206 | && mTaskEntity.getTaskStatus() != EasyTaskStatus.TASK_STATUS_CANCEL
207 | && mTaskEntity.getTaskStatus() != EasyTaskStatus.TASK_STATUS_PAUSE) {
208 | randomAccessFile.write(buffer, 0, length);
209 | completedSize += length;
210 | buffOffset += length;
211 |
212 | mTaskEntity.setCompletedSize(completedSize);
213 | //避免一直调用数据库.
214 | if (buffOffset >= updateSize) {
215 | buffOffset = 0;
216 | EasyDaoManager.instance().update(mTaskEntity);
217 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_DOWNLOADING);
218 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],totalSize[" + fileTotalSize + "],completedSize[" + completedSize + "]");
219 | }
220 | if (completedSize == fileTotalSize) {
221 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],totalSize[" + fileTotalSize + "],completedSize[" + completedSize + "]");
222 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_DOWNLOADING);
223 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_FINISH);
224 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_FINISH);
225 | EasyDaoManager.instance().update(mTaskEntity);
226 | }
227 | }
228 |
229 | // 更新
230 | if (EasyDaoManager.instance().queryWithId(mTaskEntity.getTaskId()) != null) {
231 | EasyDaoManager.instance().update(mTaskEntity);
232 | }
233 |
234 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],exception:totalSize[" + fileTotalSize + "],completedSize[" + completedSize + "]");
235 |
236 | // if (mTaskEntity.getTotalSize() == -1 && completedSize > 0) {
237 | // // 返回文件大小未知情况下,直接设为下载完成.
238 | // mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_DOWNLOADING);
239 | // mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_FINISH);
240 | // mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_FINISH);
241 | // EasyDaoManager.instance().update(mTaskEntity);
242 | // }
243 |
244 | }
245 | } else if (response.code() == 403 || response.code() == 404) {
246 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],response.code()[" + response.code() + "]");
247 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
248 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_LINK_FAILURE_ERROR);
249 | } else {
250 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "],response.code()[" + response.code() + "]");
251 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
252 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
253 | }
254 |
255 | } catch (FileNotFoundException e) {
256 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "]FileNotFoundException");
257 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_STORAGE_ERROR);
258 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_STORAGE_ERROR);
259 | e.printStackTrace();
260 | } catch (SocketTimeoutException e) {
261 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "]SocketTimeoutException");
262 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
263 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
264 | e.printStackTrace();
265 | } catch (IOException e) {
266 | // Log.d("EasyDownload", "taskId[" + mTaskEntity.getTaskId() + "]IOException");
267 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
268 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_REQUEST_ERROR);
269 | e.printStackTrace();
270 | } finally {
271 | EasyIOUtils.close(bufferedInputStream, inputStream, randomAccessFile);
272 | }
273 | }
274 |
275 | public void pause() {
276 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_PAUSE);
277 | if (EasyDaoManager.instance().queryWithId(mTaskEntity.getTaskId()) == null) {
278 | EasyDaoManager.instance().insertOrReplace(mTaskEntity);
279 | } else {
280 | EasyDaoManager.instance().update(mTaskEntity);
281 | }
282 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_PAUSE);
283 | }
284 |
285 | public void init() {
286 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_INIT);
287 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_INIT);
288 | }
289 |
290 | public void queue() {
291 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_QUEUE);
292 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_QUEUE);
293 | }
294 |
295 | public void cancel() {
296 | mTaskEntity.setTaskStatus(EasyTaskStatus.TASK_STATUS_CANCEL);
297 | if (EasyDaoManager.instance().queryWithId(mTaskEntity.getTaskId()) != null) {
298 | EasyDaoManager.instance().delete(mTaskEntity);
299 | }
300 | mHandler.sendEmptyMessage(EasyTaskStatus.TASK_STATUS_CANCEL);
301 | }
302 | }
--------------------------------------------------------------------------------
/easy-http-library/src/main/java/com/yang/easyhttp/manager/EasyHttpClientManager.java:
--------------------------------------------------------------------------------
1 | package com.yang.easyhttp.manager;
2 |
3 | import android.content.Context;
4 | import android.os.Handler;
5 | import android.os.Looper;
6 | import android.text.TextUtils;
7 |
8 | import com.google.gson.Gson;
9 | import com.yang.easyhttp.Interceptor.EasyCacheInterceptor;
10 | import com.yang.easyhttp.Interceptor.EasyHeaderInterceptor;
11 | import com.yang.easyhttp.Interceptor.EasyLoggingInterceptor;
12 | import com.yang.easyhttp.Interceptor.EasyUserAgentInterceptor;
13 | import com.yang.easyhttp.cache.EasyCacheDir;
14 | import com.yang.easyhttp.cache.EasyCacheTime;
15 | import com.yang.easyhttp.cache.EasyCacheType;
16 | import com.yang.easyhttp.callback.EasyCallback;
17 | import com.yang.easyhttp.config.EasyHttpConfig;
18 | import com.yang.easyhttp.request.EasyRequestParams;
19 |
20 | import java.io.File;
21 | import java.io.IOException;
22 | import java.util.concurrent.ConcurrentHashMap;
23 | import java.util.concurrent.locks.ReentrantLock;
24 |
25 | import okhttp3.Cache;
26 | import okhttp3.Call;
27 | import okhttp3.Callback;
28 | import okhttp3.FormBody;
29 | import okhttp3.MediaType;
30 | import okhttp3.OkHttpClient;
31 | import okhttp3.Request;
32 | import okhttp3.RequestBody;
33 | import okhttp3.Response;
34 |
35 | /**
36 | * Created by yangy on 2016/9/14.
37 | */
38 | public class EasyHttpClientManager {
39 | private final static String TAG = "EasyHttpClientManager";
40 | public final static int REQUEST_POST = 1;
41 | public final static int REQUEST_DELETE = 2;
42 | public final static int REQUEST_PUT = 3;
43 |
44 | private static EasyHttpClientManager mInstance = null;
45 |
46 | private OkHttpClient mNoCacheOKHttpClient;
47 | private OkHttpClient mCacheShortOKHttpClient;
48 | private OkHttpClient mCacheMidOKHttpClient;
49 | private OkHttpClient mCacheLongOKHttpClient;
50 |
51 | private Context mContext;
52 | private boolean mDebug;
53 | private Handler mHandler;
54 | private Gson mGson;
55 | private EasyHttpConfig mConfig;
56 |
57 | private static final ReentrantLock LOCK = new ReentrantLock();
58 |
59 | /**
60 | * constructor.
61 | */
62 | private EasyHttpClientManager() {
63 | mDebug = false;
64 | mGson = new Gson();
65 | }
66 |
67 | /**
68 | * EasyHttpClientManager getInstance.
69 | *
70 | * @return
71 | */
72 | public static EasyHttpClientManager getInstance() {
73 | try {
74 | LOCK.lock();
75 | if (null == mInstance) {
76 | mInstance = new EasyHttpClientManager();
77 | }
78 | } finally {
79 | LOCK.unlock();
80 | }
81 |
82 | return mInstance;
83 | }
84 |
85 | /**
86 | * 初始化上下文.
87 | * @param context
88 | */
89 | public void init(Context context) {
90 | mContext = context;
91 | mHandler = new Handler(Looper.getMainLooper());
92 | // default http config.
93 | mConfig = new EasyHttpConfig.Builder()
94 | .setCacheDir(EasyCacheDir.SD_PATH + mContext.getPackageName())
95 | .setCacheTime(EasyCacheTime.CACHE_TIME_SHORT, EasyCacheTime.CACHE_TIME_MID, EasyCacheTime.CACHE_TIME_LONG)
96 | .setCacheMaxSize(5 * 1024 * 1024, 5 * 1024 * 1024, 20 * 1024 * 1024)
97 | .setGlobalCacheType(EasyCacheType.CACHE_TYPE_NO_SETTING)
98 | .build();
99 | }
100 |
101 | /**
102 | * 初始化上下文,带配置.
103 | * @param context
104 | * @param config
105 | */
106 | public void init(Context context, EasyHttpConfig config) {
107 | init(context);
108 | if (!TextUtils.isEmpty(config.getCacheDir())) {
109 | mConfig.setCacheDir(config.getCacheDir());
110 | }
111 | if (config.getCacheShortTime() > 0) {
112 | mConfig.setCacheShortTime(config.getCacheShortTime());
113 | }
114 | if (config.getCacheMidTime() > 0) {
115 | mConfig.setCacheMidTime(config.getCacheMidTime());
116 | }
117 | if (config.getCacheLongTime() > 0) {
118 | mConfig.setCacheLongTime(config.getCacheLongTime());
119 | }
120 | if (config.getCacheShortMaxSize() > 0) {
121 | mConfig.setCacheShortMaxSize(config.getCacheShortMaxSize());
122 | }
123 | if (config.getCacheMidMaxSize() > 0) {
124 | mConfig.setCacheMidMaxSize(config.getCacheMidMaxSize());
125 | }
126 | if (config.getCacheLongMaxSize() > 0) {
127 | mConfig.setCacheLongMaxSize(config.getCacheLongMaxSize());
128 | }
129 | if (config.getGlobalCacheType() > -1) {
130 | mConfig.setGlobalCacheType(config.getGlobalCacheType());
131 | }
132 | if (!TextUtils.isEmpty(config.getUserAgent())) {
133 | mConfig.setUserAgent(config.getUserAgent());
134 | }
135 | }
136 |
137 | /**
138 | * 获取上下文.
139 | * @return
140 | */
141 | public Context getContext() {
142 | return mContext;
143 | }
144 |
145 | /**
146 | * 设定debug类型.
147 | * @param debug
148 | */
149 | public void setDebug(boolean debug) {
150 | mDebug = debug;
151 | }
152 |
153 | /**
154 | * 返回是否debug.
155 | * @return
156 | */
157 | public boolean isDebug() {
158 | return mDebug;
159 | }
160 |
161 | /**
162 | * 获取Gson对象.
163 | * @return
164 | */
165 | public Gson getGson() {
166 | return mGson;
167 | }
168 |
169 | /**
170 | * 获取配置.
171 | * @return
172 | */
173 | public EasyHttpConfig getConfig() {
174 | return mConfig;
175 | }
176 |
177 | /**
178 | * getOkHttpClient.
179 | * @param cacheType
180 | * @return
181 | */
182 | public OkHttpClient getOkHttpClient(int cacheType) {
183 | OkHttpClient okHttpClient;
184 |
185 | if (cacheType == EasyCacheType.CACHE_TYPE_DEFAULT) {
186 | okHttpClient = getNoCacheOkHttpClient();
187 | } else if (cacheType == EasyCacheType.CACHE_TYPE_SHORT) {
188 | okHttpClient = getCacheShortOkHttpClient();
189 | } else if (cacheType == EasyCacheType.CACHE_TYPE_MID) {
190 | okHttpClient = getCacheMidOkHttpClient();
191 | } else if (cacheType == EasyCacheType.CACHE_TYPE_LONG) {
192 | okHttpClient = getCacheLongOkHttpClient();
193 | } else {
194 | okHttpClient = getNoCacheOkHttpClient();
195 | }
196 |
197 | return okHttpClient;
198 | }
199 |
200 | /**
201 | * 获取无缓存OkHttpClient.
202 | *
203 | * @return
204 | */
205 | private synchronized OkHttpClient getNoCacheOkHttpClient() {
206 | if (mNoCacheOKHttpClient == null) {
207 | EasyCacheInterceptor interceptor = new EasyCacheInterceptor(EasyCacheType.CACHE_TYPE_DEFAULT);
208 |
209 | OkHttpClient.Builder builder = new OkHttpClient()
210 | .newBuilder()
211 | .addNetworkInterceptor(interceptor);
212 | if (!TextUtils.isEmpty(mConfig.getUserAgent())) {
213 | builder.addNetworkInterceptor(new EasyUserAgentInterceptor(mConfig.getUserAgent()));
214 | }
215 | if (mDebug) {
216 | builder.addNetworkInterceptor(new EasyLoggingInterceptor());
217 | }
218 |
219 | mNoCacheOKHttpClient = builder.build();
220 | }
221 |
222 | return mNoCacheOKHttpClient;
223 | }
224 |
225 | /**
226 | * 获取短期缓存OkHttpClient.
227 | *
228 | * @return
229 | */
230 | private synchronized OkHttpClient getCacheShortOkHttpClient() {
231 | if (mCacheShortOKHttpClient == null) {
232 | File httpCacheDirectory = new File(mConfig.getCacheDir() + EasyCacheDir.CACHE_SHORT_DIR);
233 | if (!httpCacheDirectory.exists()) {
234 | httpCacheDirectory.mkdirs();
235 | }
236 | Cache cache = new Cache(httpCacheDirectory, mConfig.getCacheShortMaxSize());
237 | EasyCacheInterceptor interceptor = new EasyCacheInterceptor(EasyCacheType.CACHE_TYPE_SHORT);
238 |
239 | OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
240 | .addNetworkInterceptor(interceptor)
241 | .cache(cache);
242 | if (!TextUtils.isEmpty(mConfig.getUserAgent())) {
243 | builder.addNetworkInterceptor(new EasyUserAgentInterceptor(mConfig.getUserAgent()));
244 | }
245 | if (mDebug) {
246 | builder.addNetworkInterceptor(new EasyLoggingInterceptor());
247 | }
248 |
249 | mCacheShortOKHttpClient = builder.build();
250 | }
251 |
252 | return mCacheShortOKHttpClient;
253 | }
254 |
255 | /**
256 | * 获取中期缓存OkHttpClient.
257 | *
258 | * @return
259 | */
260 | private synchronized OkHttpClient getCacheMidOkHttpClient() {
261 | if (mCacheMidOKHttpClient == null) {
262 | File httpCacheDirectory = new File(mConfig.getCacheDir() + EasyCacheDir.CACHE_MID_DIR);
263 | if (!httpCacheDirectory.exists()) {
264 | httpCacheDirectory.mkdirs();
265 | }
266 | Cache cache = new Cache(httpCacheDirectory, mConfig.getCacheMidMaxSize());
267 | EasyCacheInterceptor interceptor = new EasyCacheInterceptor(EasyCacheType.CACHE_TYPE_MID);
268 |
269 | OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
270 | .addNetworkInterceptor(interceptor)
271 | .cache(cache);
272 | if (!TextUtils.isEmpty(mConfig.getUserAgent())) {
273 | builder.addNetworkInterceptor(new EasyUserAgentInterceptor(mConfig.getUserAgent()));
274 | }
275 | if (mDebug) {
276 | builder.addNetworkInterceptor(new EasyLoggingInterceptor());
277 | }
278 |
279 | mCacheMidOKHttpClient = builder.build();
280 | }
281 |
282 | return mCacheMidOKHttpClient;
283 | }
284 |
285 | /**
286 | * 获取长期缓存OkHttpClient.
287 | *
288 | * @return
289 | */
290 | private synchronized OkHttpClient getCacheLongOkHttpClient() {
291 | if (mCacheLongOKHttpClient == null) {
292 | File httpCacheDirectory = new File(mConfig.getCacheDir() + EasyCacheDir.CACHE_LONG_DIR);
293 | if (!httpCacheDirectory.exists()) {
294 | httpCacheDirectory.mkdirs();
295 | }
296 | Cache cache = new Cache(httpCacheDirectory, mConfig.getCacheLongMaxSize());
297 |
298 | EasyCacheInterceptor interceptor = new EasyCacheInterceptor(EasyCacheType.CACHE_TYPE_LONG);
299 |
300 | OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
301 | .addNetworkInterceptor(interceptor)
302 | .cache(cache);
303 | if (!TextUtils.isEmpty(mConfig.getUserAgent())) {
304 | builder.addNetworkInterceptor(new EasyUserAgentInterceptor(mConfig.getUserAgent()));
305 | }
306 | if (mDebug) {
307 | builder.addNetworkInterceptor(new EasyLoggingInterceptor());
308 | }
309 |
310 | mCacheLongOKHttpClient = builder.build();
311 | }
312 |
313 | return mCacheLongOKHttpClient;
314 | }
315 |
316 | /**
317 | * 拼接url
318 | * @param url
319 | * @param params
320 | * @return
321 | */
322 | public String buildUrl(String url, EasyRequestParams params) {
323 | if (params != null && params.getRequestParams()!= null && params.getRequestParams().size() > 0) {
324 | return url + "&" + params.toString();
325 | } else {
326 | return url;
327 | }
328 | }
329 |
330 | /**
331 | * get异步请求
332 | * @param url
333 | * @param requestParams
334 | * @param cacheType
335 | * @param callBack
336 | * @param
337 | */
338 | public void get(String url, EasyRequestParams requestParams, int cacheType, final EasyCallback callBack) {
339 | final Request request = new Request.Builder().url(buildUrl(url, requestParams)).build();
340 | if (callBack != null) {
341 | // UI线程.
342 | callBack.onStart();
343 | }
344 |
345 | // 接口没有单独设定缓存类型,使用全局缓存类型.
346 | if (cacheType == EasyCacheType.CACHE_TYPE_NO_SETTING) {
347 | cacheType = mConfig.getGlobalCacheType();
348 | }
349 |
350 | OkHttpClient httpClient = getOkHttpClient(cacheType);
351 |
352 | if (requestParams != null) {
353 | ConcurrentHashMap headers = requestParams.getRequestHeaders();
354 | if (headers != null && headers.size() > 0) {
355 | OkHttpClient.Builder builder = httpClient.newBuilder();
356 | builder.addNetworkInterceptor(new EasyHeaderInterceptor(headers));
357 | httpClient = builder.build();
358 | }
359 | }
360 |
361 | // 异步.
362 | httpClient.newCall(request).enqueue(new Callback() {
363 | @Override
364 | public void onFailure(Call call, final IOException e) {
365 | // 子线程
366 | if (callBack == null) {
367 | return;
368 | }
369 |
370 | mHandler.post(new Runnable() {
371 | @Override
372 | public void run() {
373 | callBack.onFailure(e,
374 | "the request could not be executed due to cancellation, a connectivity problem or timeout");
375 | callBack.onFinish();
376 | }
377 | });
378 | }
379 |
380 | @Override
381 | public void onResponse(Call call, final Response response) throws IOException {
382 | // 子线程
383 | if (callBack == null) {
384 | return;
385 | }
386 |
387 | if (!response.isSuccessful()) {
388 | final IOException e = new IOException("Unexpected code " + response);
389 | mHandler.post(new Runnable() {
390 | @Override
391 | public void run() {
392 | callBack.onFailure(e, "the HTTP response was not successfully");
393 | callBack.onFinish();
394 | }
395 | });
396 | return;
397 | }
398 |
399 | try {
400 | final String content = response.body().string();
401 | response.body().close();
402 | final T data = callBack.convert(content);
403 |
404 | mHandler.post(new Runnable() {
405 | @Override
406 | public void run() {
407 | callBack.onSuccess(data);
408 | callBack.onFinish();
409 | }
410 | });
411 | } catch (final Exception e) {
412 | mHandler.post(new Runnable() {
413 | @Override
414 | public void run() {
415 | callBack.onFailure(e, "Exception");
416 | callBack.onFinish();
417 | }
418 | });
419 | e.printStackTrace();
420 | }
421 | }
422 | });
423 | }
424 |
425 | /**
426 | * post异步请求,
427 | * @param url
428 | * @param requestParams
429 | * @param callBack
430 | * @param
431 | */
432 | public void postOrDeleteOrPut(String url, EasyRequestParams requestParams, final EasyCallback callBack, int type) {
433 | FormBody.Builder builder = new FormBody.Builder();
434 | ConcurrentHashMap paramsMap = requestParams.getRequestParams();
435 | for (ConcurrentHashMap.Entry entry : paramsMap.entrySet()) {
436 | builder.add(entry.getKey(), entry.getValue());
437 | }
438 |
439 | RequestBody requestBody = builder.build();
440 | Request.Builder requestBuilder = new Request.Builder();
441 | requestBuilder.url(url);
442 | switch (type) {
443 | case REQUEST_POST:
444 | requestBuilder.post(requestBody);
445 | break;
446 | case REQUEST_DELETE:
447 | requestBuilder.delete(requestBody);
448 | break;
449 | case REQUEST_PUT:
450 | requestBuilder.put(requestBody);
451 | break;
452 | default:
453 | requestBuilder.post(requestBody);
454 | break;
455 | }
456 | final Request request = requestBuilder.build();
457 |
458 | if (callBack != null) {
459 | // UI线程.
460 | callBack.onStart();
461 | }
462 |
463 | OkHttpClient httpClient = getNoCacheOkHttpClient();
464 |
465 | if (requestParams != null) {
466 | ConcurrentHashMap headers = requestParams.getRequestHeaders();
467 | if (headers != null && headers.size() > 0) {
468 | OkHttpClient.Builder okHttpClientBuilder = httpClient.newBuilder();
469 | okHttpClientBuilder.addNetworkInterceptor(new EasyHeaderInterceptor(headers));
470 | httpClient = okHttpClientBuilder.build();
471 | }
472 | }
473 |
474 | // 异步.
475 | httpClient.newCall(request).enqueue(new Callback() {
476 | @Override
477 | public void onFailure(Call call, final IOException e) {
478 | // 子线程
479 | if (callBack == null) {
480 | return;
481 | }
482 |
483 | mHandler.post(new Runnable() {
484 | @Override
485 | public void run() {
486 | callBack.onFailure(e,
487 | "the request could not be executed due to cancellation, a connectivity problem or timeout");
488 | callBack.onFinish();
489 | }
490 | });
491 | }
492 |
493 | @Override
494 | public void onResponse(Call call, final Response response) throws IOException {
495 | // 子线程
496 | if (callBack == null) {
497 | return;
498 | }
499 |
500 | if (!response.isSuccessful()) {
501 | final IOException e = new IOException("Unexpected code " + response);
502 | mHandler.post(new Runnable() {
503 | @Override
504 | public void run() {
505 | callBack.onFailure(e, "the HTTP response was not successfully");
506 | callBack.onFinish();
507 | }
508 | });
509 | return;
510 | }
511 |
512 | try {
513 | final String content = response.body().string();
514 | response.body().close();
515 | final T data = callBack.convert(content);
516 |
517 | mHandler.post(new Runnable() {
518 | @Override
519 | public void run() {
520 | callBack.onSuccess(data);
521 | callBack.onFinish();
522 | }
523 | });
524 | } catch (final Exception e) {
525 | mHandler.post(new Runnable() {
526 | @Override
527 | public void run() {
528 | callBack.onFailure(e, "Exception");
529 | callBack.onFinish();
530 | }
531 | });
532 | e.printStackTrace();
533 | }
534 | }
535 | });
536 | }
537 |
538 | public void uploadFile(String url, String filePath, final EasyCallback callBack) {
539 | File file = new File(filePath);
540 | RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
541 |
542 | final Request request = new Request.Builder()
543 | .url(url)
544 | .post(requestBody)
545 | .build();
546 |
547 | if (callBack != null) {
548 | // UI线程.
549 | callBack.onStart();
550 | }
551 |
552 | // 异步.
553 | getNoCacheOkHttpClient().newCall(request).enqueue(new Callback() {
554 | @Override
555 | public void onFailure(Call call, final IOException e) {
556 | // 子线程
557 | if (callBack == null) {
558 | return;
559 | }
560 |
561 | mHandler.post(new Runnable() {
562 | @Override
563 | public void run() {
564 | callBack.onFailure(e,
565 | "the request could not be executed due to cancellation, a connectivity problem or timeout");
566 | callBack.onFinish();
567 | }
568 | });
569 | }
570 |
571 | @Override
572 | public void onResponse(Call call, final Response response) throws IOException {
573 | // 子线程
574 | if (callBack == null) {
575 | return;
576 | }
577 |
578 | if (!response.isSuccessful()) {
579 | final IOException e = new IOException("Unexpected code " + response);
580 | mHandler.post(new Runnable() {
581 | @Override
582 | public void run() {
583 | callBack.onFailure(e, "the HTTP response was not successfully");
584 | callBack.onFinish();
585 | }
586 | });
587 | return;
588 | }
589 |
590 | try {
591 | final String content = response.body().string();
592 | response.body().close();
593 | final T data = callBack.convert(content);
594 |
595 | mHandler.post(new Runnable() {
596 | @Override
597 | public void run() {
598 | callBack.onSuccess(data);
599 | callBack.onFinish();
600 | }
601 | });
602 | } catch (final Exception e) {
603 | mHandler.post(new Runnable() {
604 | @Override
605 | public void run() {
606 | callBack.onFailure(e, "Exception");
607 | callBack.onFinish();
608 | }
609 | });
610 | e.printStackTrace();
611 | }
612 | }
613 | });
614 | }
615 |
616 | /**
617 | * 取消请求.
618 | * @param type
619 | */
620 | public void cancelRequest(int type) {
621 | getOkHttpClient(type).dispatcher().cancelAll();
622 | }
623 | }
624 |
--------------------------------------------------------------------------------