YanYi 7 rokov pred
commit
e977f30803
59 zmenil súbory, kde vykonal 2481 pridanie a 0 odobranie
  1. 9 0
      .gitignore
  2. 19 0
      .idea/gradle.xml
  3. 49 0
      .idea/misc.xml
  4. 10 0
      .idea/modules.xml
  5. 12 0
      .idea/runConfigurations.xml
  6. 1 0
      app/.gitignore
  7. 34 0
      app/build.gradle
  8. 21 0
      app/proguard-rules.pro
  9. 26 0
      app/src/androidTest/java/com/mylove/okhttp/ExampleInstrumentedTest.java
  10. 19 0
      app/src/main/AndroidManifest.xml
  11. 21 0
      app/src/main/java/com/mylove/okhttp/AppContext.java
  12. 42 0
      app/src/main/java/com/mylove/okhttp/MainActivity.java
  13. 34 0
      app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  14. 170 0
      app/src/main/res/drawable/ic_launcher_background.xml
  15. 6 0
      app/src/main/res/layout/activity_main.xml
  16. 5 0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  17. 5 0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  18. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher.png
  19. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  20. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher.png
  21. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  22. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher.png
  23. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  24. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  25. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  26. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  27. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  28. 6 0
      app/src/main/res/values/colors.xml
  29. 3 0
      app/src/main/res/values/strings.xml
  30. 11 0
      app/src/main/res/values/styles.xml
  31. 17 0
      app/src/test/java/com/mylove/okhttp/ExampleUnitTest.java
  32. 31 0
      build.gradle
  33. 17 0
      gradle.properties
  34. BIN
      gradle/wrapper/gradle-wrapper.jar
  35. 6 0
      gradle/wrapper/gradle-wrapper.properties
  36. 160 0
      gradlew
  37. 90 0
      gradlew.bat
  38. 1 0
      okhttp2/.gitignore
  39. 41 0
      okhttp2/build.gradle
  40. 21 0
      okhttp2/proguard-rules.pro
  41. 26 0
      okhttp2/src/androidTest/java/com/mylove/okhttp/ExampleInstrumentedTest.java
  42. 2 0
      okhttp2/src/main/AndroidManifest.xml
  43. 44 0
      okhttp2/src/main/java/com/mylove/okhttp/AutoRequest.java
  44. 27 0
      okhttp2/src/main/java/com/mylove/okhttp/CacheInterceptor.java
  45. 95 0
      okhttp2/src/main/java/com/mylove/okhttp/CacheUtils.java
  46. 13 0
      okhttp2/src/main/java/com/mylove/okhttp/CallType.java
  47. 350 0
      okhttp2/src/main/java/com/mylove/okhttp/FormatUtil.java
  48. 54 0
      okhttp2/src/main/java/com/mylove/okhttp/Internet.java
  49. 116 0
      okhttp2/src/main/java/com/mylove/okhttp/InternetUtil.java
  50. 342 0
      okhttp2/src/main/java/com/mylove/okhttp/MD5keyUtil.java
  51. 223 0
      okhttp2/src/main/java/com/mylove/okhttp/ObservableRequest.java
  52. 157 0
      okhttp2/src/main/java/com/mylove/okhttp/OkCall.java
  53. 54 0
      okhttp2/src/main/java/com/mylove/okhttp/OkHttpUtil.java
  54. 15 0
      okhttp2/src/main/java/com/mylove/okhttp/RequestType.java
  55. 39 0
      okhttp2/src/main/java/com/mylove/okhttp/ShowToast.java
  56. 16 0
      okhttp2/src/main/java/com/mylove/okhttp/onOkHttpListener.java
  57. 3 0
      okhttp2/src/main/res/values/strings.xml
  58. 17 0
      okhttp2/src/test/java/com/mylove/okhttp/ExampleUnitTest.java
  59. 1 0
      settings.gradle

+ 9 - 0
.gitignore

@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild

+ 19 - 0
.idea/gradle.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/okhttp2" />
+          </set>
+        </option>
+        <option name="resolveModulePerSourceSet" value="false" />
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 49 - 0
.idea/misc.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="NullableNotNullManager">
+    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
+    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
+    <option name="myNullables">
+      <value>
+        <list size="4">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+        </list>
+      </value>
+    </option>
+    <option name="myNotNulls">
+      <value>
+        <list size="4">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
+        </list>
+      </value>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+  <component name="masterDetails">
+    <states>
+      <state key="ProjectJDKs.UI">
+        <settings>
+          <last-edited>1.8</last-edited>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+    </states>
+  </component>
+</project>

+ 10 - 0
.idea/modules.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/OkHttp.iml" filepath="$PROJECT_DIR$/OkHttp.iml" />
+      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
+      <module fileurl="file://$PROJECT_DIR$/okhttp2/okhttp2.iml" filepath="$PROJECT_DIR$/okhttp2/okhttp2.iml" />
+    </modules>
+  </component>
+</project>

+ 12 - 0
.idea/runConfigurations.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RunConfigurationProducerService">
+    <option name="ignoredProducers">
+      <set>
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
+      </set>
+    </option>
+  </component>
+</project>

+ 1 - 0
app/.gitignore

@@ -0,0 +1 @@
+/build

+ 34 - 0
app/build.gradle

@@ -0,0 +1,34 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 26
+    defaultConfig {
+        applicationId "com.mylove.okhttp"
+        minSdkVersion 14
+        targetSdkVersion 26
+        versionCode 1
+        versionName "1.0"
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+    }
+    buildTypes {
+        debug {
+            buildConfigField "boolean", "LOG_DEBUG", "true"
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+        release {
+            buildConfigField "boolean", "LOG_DEBUG", "false"
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    implementation fileTree(include: ['*.jar'], dir: 'libs')
+    implementation 'com.android.support:appcompat-v7:26.1.0'
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'com.android.support.test:runner:1.0.1'
+    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
+    compile project(':okhttp2')
+}

+ 21 - 0
app/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 26 - 0
app/src/androidTest/java/com/mylove/okhttp/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.mylove.okhttp;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() throws Exception {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.mylove.okhttp", appContext.getPackageName());
+    }
+}

+ 19 - 0
app/src/main/AndroidManifest.xml

@@ -0,0 +1,19 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.mylove.okhttp">
+
+    <application
+        android:name=".AppContext"
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity android:name=".MainActivity">
+            <intent-filter>
+                <category android:name="android.intent.category.LAUNCHER" />
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>

+ 21 - 0
app/src/main/java/com/mylove/okhttp/AppContext.java

@@ -0,0 +1,21 @@
+package com.mylove.okhttp;
+
+import android.app.Application;
+
+import com.mylove.loglib.JLog;
+
+/**
+ * @author myLove
+ * @time 2017/11/16 19:11
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+public class AppContext extends Application {
+    @Override
+    public void onCreate() {
+        super.onCreate();
+//        JLog.init(BuildConfig.LOG_DEBUG);
+        JLog.init(true);
+    }
+}

+ 42 - 0
app/src/main/java/com/mylove/okhttp/MainActivity.java

@@ -0,0 +1,42 @@
+package com.mylove.okhttp;
+
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+
+import com.mylove.loglib.JLog;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * @author myLove
+ * @time 2017/11/16 19:18
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+public class MainActivity extends AppCompatActivity {
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
+        super.onCreate(savedInstanceState, persistentState);
+        setContentView(R.layout.activity_main);
+        String url = "https://www.yjw1020.club/api/myIndex.php";
+        Map<Object, Object> oMap = new HashMap<>();
+        oMap.put("type", "1");
+        OkHttpUtil.getInstance(this).post(url).async(oMap, new onOkHttpListener<String, String>() {
+            public void onCompleted() {
+            }
+
+            public void onSuccess(String s) {
+                JLog.v(s);
+            }
+
+            public void onFailure(String s) {
+                JLog.v(s);
+            }
+        });
+    }
+}

+ 34 - 0
app/src/main/res/drawable-v24/ic_launcher_foreground.xml

@@ -0,0 +1,34 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108">
+    <path
+        android:fillType="evenOdd"
+        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="78.5885"
+                android:endY="90.9159"
+                android:startX="48.7653"
+                android:startY="61.0927"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1" />
+</vector>

+ 170 - 0
app/src/main/res/drawable/ic_launcher_background.xml

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108">
+    <path
+        android:fillColor="#26A69A"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+</vector>

+ 6 - 0
app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</LinearLayout>

+ 5 - 0
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

+ 5 - 0
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>

BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png


BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png


+ 6 - 0
app/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>

+ 3 - 0
app/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">OkHttp</string>
+</resources>

+ 11 - 0
app/src/main/res/values/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>

+ 17 - 0
app/src/test/java/com/mylove/okhttp/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.mylove.okhttp;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() throws Exception {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 31 - 0
build.gradle

@@ -0,0 +1,31 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    
+    repositories {
+        google()
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.0.0'
+        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
+        
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+        maven {
+            url 'https://jitpack.io'
+        }
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 17 - 0
gradle.properties

@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true

BIN
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Thu Nov 16 17:33:07 CST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

+ 160 - 0
gradlew

@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90 - 0
gradlew.bat

@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 1 - 0
okhttp2/.gitignore

@@ -0,0 +1 @@
+/build

+ 41 - 0
okhttp2/build.gradle

@@ -0,0 +1,41 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+group = 'com.github.love-yanyi'
+
+android {
+    compileSdkVersion 26
+
+
+
+    defaultConfig {
+        minSdkVersion 14
+        targetSdkVersion 26
+        versionCode 1
+        versionName "1.0"
+
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+    implementation 'com.android.support:appcompat-v7:26.1.0'
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'com.android.support.test:runner:1.0.1'
+    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
+    implementation 'com.squareup.okhttp3:okhttp:3.9.0'
+    implementation 'com.squareup.okio:okio:1.13.0'
+    implementation 'io.reactivex:rxjava:1.3.3'
+    implementation 'io.reactivex:rxandroid:1.2.1'
+    compile 'com.github.love-yanyi:Logger:1.0.1'
+}

+ 21 - 0
okhttp2/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 26 - 0
okhttp2/src/androidTest/java/com/mylove/okhttp/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.mylove.okhttp;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() throws Exception {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.mylove.okhttp.test", appContext.getPackageName());
+    }
+}

+ 2 - 0
okhttp2/src/main/AndroidManifest.xml

@@ -0,0 +1,2 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.mylove.okhttp" />

+ 44 - 0
okhttp2/src/main/java/com/mylove/okhttp/AutoRequest.java

@@ -0,0 +1,44 @@
+package com.mylove.okhttp;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+
+import java.util.Map;
+
+/**
+ * @author myLove
+ * @time 2017/11/15 14:17
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+public class AutoRequest {
+    @SuppressLint("StaticFieldLeak")
+    private static AutoRequest instance;
+    private static String url;
+    @SuppressLint("StaticFieldLeak")
+    private static Context mContext;
+    private static RequestType requestType;
+
+    public static AutoRequest getInstance(Context context, String str, RequestType type) {
+        if (instance == null) {
+            synchronized (AutoRequest.class) {
+                if (instance == null) {
+                    instance = new AutoRequest();
+                    mContext = context;
+                    url = str;
+                    requestType = type;
+                }
+            }
+        }
+        return instance;
+    }
+
+    public void sync(Map<Object, Object> oMap, onOkHttpListener<String, String> onOkHttpListener) {
+        ObservableRequest.getInstance(mContext, requestType, CallType.SYNC).request(url, oMap, onOkHttpListener);
+    }
+
+    public void async(Map<Object, Object> oMap, onOkHttpListener<String, String> onOkHttpListener) {
+        ObservableRequest.getInstance(mContext, requestType, CallType.ASYNC).request(url, oMap, onOkHttpListener);
+    }
+}

+ 27 - 0
okhttp2/src/main/java/com/mylove/okhttp/CacheInterceptor.java

@@ -0,0 +1,27 @@
+package com.mylove.okhttp;
+
+import java.io.IOException;
+
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * @author myLove
+ * @time 2017/11/7 16:26
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+ class CacheInterceptor implements Interceptor {
+    public Response intercept(Chain chain) throws IOException {
+        Request request = chain.request();
+        Response response = chain.proceed(request);
+        Response build = response.newBuilder()
+                .removeHeader("Pragma")
+                .removeHeader("GlideCache-Control")
+                .header("GlideCache-Control", "max-age=" + 60)
+                .build();
+        return build;
+    }
+}

+ 95 - 0
okhttp2/src/main/java/com/mylove/okhttp/CacheUtils.java

@@ -0,0 +1,95 @@
+package com.mylove.okhttp;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.os.Environment;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.OutputStreamWriter;
+
+/**
+ * @author myLove
+ * @time 2017/11/7 17:03
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+class CacheUtils {
+    private static File realFile;
+    @SuppressLint("StaticFieldLeak")
+    private static Context mContext;
+    @SuppressLint("StaticFieldLeak")
+    private static CacheUtils instance;
+
+    public static CacheUtils getInstance(Context context) {
+        if (instance == null) {
+            instance = new CacheUtils();
+            mContext = context;
+            File dir = mContext.getExternalFilesDir(null);
+            if (dir != null && !dir.exists() && Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+                dir.mkdirs();
+            }
+            realFile = dir;
+        }
+        return instance;
+    }
+
+    /**
+     * 根据url的MD5作为文件名,进行缓存
+     *
+     * @param url  文件名
+     * @param json
+     */
+    public void setCacheToLocalJson(String url, String json) {
+        String urlMD5 = MD5keyUtil.newInstance().getkeyBeanofStr(url);
+        String path = realFile.getAbsolutePath() + "/" + urlMD5;
+        try {
+            File file = new File(path);
+            if (file.exists()) {
+                file.delete();
+            }
+            FileOutputStream fis = new FileOutputStream(file);
+            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fis));
+            long currentTime = System.currentTimeMillis();
+            bw.write(currentTime + "");
+            bw.newLine();
+            bw.write(json);
+            bw.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * 根据缓存地址,从缓存中取出数据
+     *
+     * @param url
+     * @return
+     */
+    public String getCacheToLocalJson(String url) {
+        StringBuffer sb = new StringBuffer();
+        String urlMD5 = MD5keyUtil.newInstance().getkeyBeanofStr(url);
+        // 创建缓存文件夹
+        File file = new File(realFile, urlMD5);
+        if (file.exists()) {
+            try {
+                FileReader fr = new FileReader(file);
+                BufferedReader br = new BufferedReader(fr);
+                br.readLine();
+                String temp;
+                while ((temp = br.readLine()) != null) {
+                    sb.append(temp);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
+        return sb.toString();
+    }
+}

+ 13 - 0
okhttp2/src/main/java/com/mylove/okhttp/CallType.java

@@ -0,0 +1,13 @@
+package com.mylove.okhttp;
+
+/**
+ * @author myLove
+ * @time 2017/11/15 14:02
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+enum CallType {
+    SYNC,
+    ASYNC
+}

+ 350 - 0
okhttp2/src/main/java/com/mylove/okhttp/FormatUtil.java

@@ -0,0 +1,350 @@
+package com.mylove.okhttp;
+
+import android.content.Context;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 字符串工具类
+ */
+public class FormatUtil {
+
+
+    public static final String EMPTY = "";
+
+    /**
+     * 判断字符串是否为空
+     *
+     * @param str
+     * @return true 不为空, false 为空
+     */
+    public static boolean isNotEmpty(String str) {
+        return str != null && !"null".equals(str) && str.trim().length() != 0;
+    }
+
+    /**
+     * 判断字符串是否为空
+     *
+     * @param str
+     * @return true 为空,false 不为空
+     */
+    public static boolean isEmpty(String str) {
+        return str == null || "null".equals(str) || str.trim().length() == 0;
+    }
+
+    public static final SimpleDateFormat dateformat = new SimpleDateFormat("HH:mm", Locale.CHINA);
+
+    public static String getCurrentTime() {
+        return dateformat.format(new Date());
+    }
+
+    public static final SimpleDateFormat sdformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
+
+    public static String formatDateTime(long millseconds) {
+        return sdformat.format(new Date(millseconds));
+    }
+
+    public static String getCurrentDateTime() {
+        return sdformat.format(new Date());
+    }
+
+    /**
+     * 判断集合是否为空
+     */
+    public static <T> boolean isCollectionsNotEmpty(Collection<T> collection) {
+        return collection != null && collection.size() > 0;
+    }
+
+    /**
+     * 判断MAP是否为空
+     */
+    public static <K, V> boolean isMapNotEmpty(Map<K, V> map) {
+        return map != null && map.size() > 0;
+    }
+
+    /**
+     * 判断List是否为空
+     */
+    public static boolean isListEmpty(List<?> array) {
+        return array != null && array.size() == 0;
+    }
+
+    /**
+     * 判断JSON数组是否为空
+     */
+    public static boolean isJSONArrayEmpty(JSONArray array) {
+        return array == null || array.length() == 0;
+    }
+
+    public static boolean isObjectNotNull(Object object) {
+        if (object != null && object.getClass().isArray()) {
+            // 如果是数组类型
+            throw new UnsupportedOperationException("isObjectNotNull not supported operation :" + object);
+        }
+        return object != null;
+    }
+
+    /**
+     * 判断JSON数据不空为
+     */
+    public static boolean isJSONArrayNotEmpty(JSONArray array) {
+        return array != null && array.length() > 0;
+    }
+
+    /**
+     * 判断JSON数组是否为空
+     */
+    public static boolean isJSONObjectEmpty(JSONObject object) {
+        return object == null || object.length() == 0;
+    }
+
+    /**
+     * 判断JSON数据不空为
+     */
+    public static boolean isJSONObjectNotEmpty(JSONObject object) {
+        return object != null && object.length() > 0;
+    }
+
+    public static boolean isIntArrayNotEmpty(int[] array) {
+        return array != null && array.length > 0;
+    }
+
+    /**
+     * 判断List数据不空为
+     */
+    public static boolean isListNotEmpty(List<?> array) {
+        return array != null && array.size() > 0;
+    }
+
+    /**
+     * 判断long数组不为空
+     *
+     * @param array
+     * @return
+     */
+    public static boolean isLongArrayNotEmpty(long[] array) {
+        return array != null && array.length > 0;
+    }
+
+    /**
+     * 判断float数组不为空
+     *
+     * @param array
+     * @return
+     */
+    public static boolean isFloatArrayNotEmpty(float[] array) {
+        return array != null && array.length > 0;
+    }
+
+    /**
+     * 判断double数组不为空
+     *
+     * @param array
+     * @return
+     */
+    public static boolean isDoubleArrayNotEmpty(double[] array) {
+        return array != null && array.length > 0;
+    }
+
+    /**
+     * 该方法主要使用正则表达式来判断字符串中是否包含字母
+     *
+     * @param cardNum
+     * @return 返回是否包含
+     */
+    public static boolean isJudge(String cardNum) {
+        String regex = ".*[a-zA-Z]+.*";
+        Matcher m = Pattern.compile(regex).matcher(cardNum);
+        return m.matches();
+    }
+
+    public static boolean isNotBlank(String str) {
+        return (str != null) && (str.length() != 0);
+    }
+
+    public static boolean isBlank(String str) {
+        return (str == null) || (str.length() == 0);
+    }
+
+    public static boolean isNotTrimBlank(String str) {
+        return (str != null) && (str.trim().length() != 0);
+    }
+
+    public static boolean isTrimBlank(String str) {
+        return (str == null) || (str.trim().length() == 0);
+    }
+
+    /**
+     * 判断是否是身份证
+     *
+     * @param idNo
+     * @return
+     */
+    public static boolean isIdNo(String idNo) {
+//        if (isTrimBlank(idNo))
+//        {
+//            return false;
+//        }
+//        Pattern p = Pattern.compile("^([1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3})|([1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[X,x]))$");
+//        Matcher matcher = p.matcher(idNo);
+//        return matcher.find();
+        if (isTrimBlank(idNo)) {
+            return false;
+        }
+        Pattern p = Pattern.compile("^([1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3})|([1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[X,x]))$");
+        Matcher matcher = p.matcher(idNo);
+        return !matcher.find();
+    }
+
+    /**
+     * 判断是否为手机号
+     *
+     * @param mobiles
+     * @return
+     */
+    public static boolean isNotMobileNO(String mobiles) {
+//        Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
+        Pattern p = Pattern.compile("^((1[358][0-9])|(14[57])|(17[0678]))\\d{8}$");
+        Matcher m = p.matcher(mobiles);
+        return !m.matches();
+    }
+
+    /**
+     * 判断是否为邮箱号
+     *
+     * @param email
+     * @return
+     */
+    public static boolean isEmail(String email) {
+        if (isTrimBlank(email)) {
+            return false;
+        }
+        String str = "^([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$";
+        Pattern p = Pattern.compile(str);
+        Matcher m = p.matcher(email);
+        return m.matches();
+    }
+
+    /**
+     * 在HTML特殊字符的处理
+     *
+     * @param source
+     * @return
+     */
+    public static String htmlEscapeCharsToString(String source) {
+        return FormatUtil.isEmpty(source) ? source : source.replaceAll("&lt;", "<")
+                .replaceAll("&gt;", ">")
+                .replaceAll("&amp;", "&")
+                .replaceAll("&quot;", "\"")
+                .replaceAll("&copy;", "©")
+                .replaceAll("&yen;", "¥")
+                .replaceAll("&divide;", "÷")
+                .replaceAll("&times;", "×")
+                .replaceAll("&reg;", "®")
+                .replaceAll("&sect;", "§")
+                .replaceAll("&pound;", "£")
+                .replaceAll("&cent;", "¢");
+    }
+
+    /**
+     * 验证用户名是否合法
+     *
+     * @param id
+     * @return
+     */
+    public static boolean isNotUserName(String id) {
+        if (isTrimBlank(id)) {
+            return false;
+        }
+        // 字母开头,由字母,数字和下划线组成的长度为2到16的字符串
+        Pattern p = Pattern.compile("^[a-zA-Z0-9_-]{2,16}$");
+        Matcher m = p.matcher(id);
+        return !m.find();
+    }
+
+    public static boolean isNotPassWord(String password) {
+        if (isTrimBlank(password)) {
+            return false;
+        }
+        // 就是以大小写字母开头,由大小写字母,数字和下划线组成的长度为6到18的字符串
+        Pattern p = Pattern.compile("^[a-zA-Z0-9_]{6,18}$");
+        Matcher m = p.matcher(password);
+        return !m.find();
+    }
+
+    /**
+     * 判断银行卡号是否合法
+     *
+     * @param bankCard
+     * @return
+     */
+    public static boolean isNotBank(String bankCard) {
+        if (isTrimBlank(bankCard)) {
+            return false;
+        }
+        // 一共16或19位,都是数字。
+        Pattern p = Pattern.compile("^\\d{16}$|^\\d{19}$");
+        Matcher m = p.matcher(bankCard);
+        return !m.find();
+    }
+
+    /**
+     * @param context
+     * @param resId
+     * @param str
+     * @return
+     */
+    public static String isStringFormat(Context context, int resId, String str) {
+        return String.format(context.getResources().getString(resId), str);
+    }
+
+    /**
+     * 从Raw文件中读取
+     *
+     * @param context
+     * @param resId
+     * @return
+     */
+    public static String getFromRaw(Context context, int resId) {
+        try {
+            InputStreamReader inputReader = new InputStreamReader(context.getResources().openRawResource(resId));
+            BufferedReader bufReader = new BufferedReader(inputReader);
+            String line = "";
+            StringBuilder Result = new StringBuilder();
+            while ((line = bufReader.readLine()) != null)
+                Result.append(line);
+            return Result.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    // 直接从assets读取
+    public static String getFromAssets(Context context, String fileName) {
+        try {
+            InputStreamReader inputReader = new InputStreamReader(context.getResources().getAssets().open(fileName));
+            BufferedReader bufReader = new BufferedReader(inputReader);
+            String line = "";
+            StringBuilder Result = new StringBuilder();
+            while ((line = bufReader.readLine()) != null)
+                Result.append(line);
+            return Result.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 54 - 0
okhttp2/src/main/java/com/mylove/okhttp/Internet.java

@@ -0,0 +1,54 @@
+package com.mylove.okhttp;
+
+import android.content.Context;
+
+import com.mylove.loglib.JLog;
+
+
+/**
+ * @author myLove
+ * @time 2017/11/15 13:42
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+class Internet {
+    /**
+     * 判断网络
+     */
+    static boolean ifInternet(Context mContext) {
+        switch (InternetUtil.getConnectedType(mContext)) {
+            case -1:
+                JLog.d();
+                ShowToast.getInstance(mContext).show("网络异常");
+                return false;
+            case 0:
+                if (!InternetUtil.isNetWorkConnected(mContext)) {
+                    ShowToast.getInstance(mContext).show("网络异常");
+                    JLog.d();
+                    return false;
+                } else {
+                    JLog.d();
+                    return true;
+                }
+            case 1:
+                if (!InternetUtil.isNetWorkConnected(mContext)) {
+                    ShowToast.getInstance(mContext).show("WIFI网络异常");
+                    JLog.d();
+                    return false;
+                } else {
+                    JLog.d();
+                    return true;
+                }
+            default:
+                if (!InternetUtil.isNetWorkConnected(mContext)) {
+                    ShowToast.getInstance(mContext).show("网络异常");
+                    JLog.d();
+                    return false;
+                } else {
+                    JLog.d();
+                    return true;
+                }
+        }
+    }
+}

+ 116 - 0
okhttp2/src/main/java/com/mylove/okhttp/InternetUtil.java

@@ -0,0 +1,116 @@
+package com.mylove.okhttp;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+
+/**
+ * @author myLove
+ * @time 2017/11/7 16:08
+ * @e-mail mylove.520.y@gmail.com
+ * @overview 网络工具类
+ */
+
+ class InternetUtil {
+    /**
+     * 判断是否有网络连接
+     */
+     static boolean isNetWorkConnected(Context context) {
+        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo networkInfo = null;
+        if (connectivityManager != null) {
+            networkInfo = connectivityManager.getActiveNetworkInfo();
+        }
+        return networkInfo != null && networkInfo.isAvailable();
+    }
+
+    /**
+     * 判断WIFI网络是否可用
+     *
+     * @msg 测试没用
+     */
+     static boolean isWifiConnected(Context context) {
+        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo networkInfo = null;
+        if (connectivityManager != null) {
+            networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        }
+        return networkInfo != null && networkInfo.isAvailable();
+    }
+
+    /**
+     * 判断MOBILE网络是否可用
+     *
+     * @msg 测试没用
+     */
+     static boolean isMobileConnected(Context context) {
+        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo networkInfo = null;
+        if (connectivityManager != null) {
+            networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        }
+        return networkInfo != null && networkInfo.isAvailable();
+    }
+
+    /**
+     * 获取当前网络连接的类型信息
+     */
+     static int getConnectedType(Context context) {
+        int i = -1;
+        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
+        if (networkInfo != null) {
+            if (networkInfo.isAvailable()) {
+                i = networkInfo.getType();
+//                int type = networkInfo.getType();
+//                if (type == ConnectivityManager.TYPE_MOBILE) {
+//                    JLog.d(networkInfo.getExtraInfo());
+//                    if (networkInfo.getExtraInfo().toLowerCase() == "cmnet") {
+//                        JLog.d("CMNET");
+//                    } else {
+//                        JLog.d("CMWAP");
+//                    }
+//                } else if (type == ConnectivityManager.TYPE_WIFI) {
+//                    JLog.d("WIFI");
+//                }
+            }
+        }
+        return i;
+    }
+
+    /**
+     * 获取当前ip地址
+     *
+     * @param context
+     * @return
+     */
+     static String getLocalIpAddress(Context context) {
+        try {
+            WifiManager wifiManager = (WifiManager) context.getApplicationContext()
+                    .getSystemService(Context.WIFI_SERVICE);
+            @SuppressLint("MissingPermission")
+            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
+            int i = wifiInfo.getIpAddress();
+            return int2ip(i);
+        } catch (Exception ex) {
+            return " 获取IP出错!!!!请保证是WIFI,或者请重新打开网络!\n" + ex.getMessage();
+        }
+        // return null;
+    }
+
+    /**
+     * 将ip的整数形式转换成ip形式
+     *
+     * @param ipInt
+     * @return
+     */
+    private static String int2ip(int ipInt) {
+        return String.valueOf(ipInt & 0xFF) + "." +
+                ((ipInt >> 8) & 0xFF) + "." +
+                ((ipInt >> 16) & 0xFF) + "." +
+                ((ipInt >> 24) & 0xFF);
+    }
+}

+ 342 - 0
okhttp2/src/main/java/com/mylove/okhttp/MD5keyUtil.java

@@ -0,0 +1,342 @@
+package com.mylove.okhttp;
+
+/**
+ * @author myLove
+ * @time 2017/11/7 17:05
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+class MD5keyUtil {
+    /*
+    * 下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的, 这里把它们实现成为static final是表示了只读,切能在同一个进程空间内的多个 Instance间共享
+    */
+    static final int S11 = 7;
+
+    static final int S12 = 12;
+
+    static final int S13 = 17;
+
+    static final int S14 = 22;
+
+    static final int S21 = 5;
+
+    static final int S22 = 9;
+
+    static final int S23 = 14;
+
+    static final int S24 = 20;
+
+    static final int S31 = 4;
+
+    static final int S32 = 11;
+
+    static final int S33 = 16;
+
+    static final int S34 = 23;
+
+    static final int S41 = 6;
+
+    static final int S42 = 10;
+
+    static final int S43 = 15;
+
+    static final int S44 = 21;
+
+    static final byte[] PADDING = {-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+    /*
+     * 下面的三个成员是keyBean计算过程中用到的3个核心数据,在原始的C实现中 被定义到keyBean_CTX结构中
+     */
+    private static long[] state = new long[4]; // state (ABCD)
+
+    private static long[] count = new long[2]; // number of bits, modulo 2^64 (lsb
+
+    // first)
+
+    private static byte[] buffer = new byte[64]; // input buffer
+
+      /*
+     * digestHexStr是keyBean的唯一一个公共成员,是最新一次计算结果的 16进制ASCII表示.
+     */
+
+     String digestHexStr;
+
+    /*
+     * digest,是最新一次计算结果的2进制内部表示,表示128bit的keyBean值.
+     */
+    private byte[] digest = new byte[16];
+
+    /*
+     * getkeyBeanofStr是类keyBean最主要的公共方法,入口参数是你想要进行keyBean变换的字符串 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的.
+     */
+     String getkeyBeanofStr(String inbuf) {
+        keyBeanInit();
+        keyBeanUpdate(inbuf.getBytes(), inbuf.length());
+        keyBeanFinal();
+        digestHexStr = "";
+        for (int i = 0; i < 16; i++) {
+            digestHexStr += byteHEX(digest[i]);
+        }
+        return digestHexStr;
+    }
+
+     static MD5keyUtil mBean = null;
+
+    static MD5keyUtil newInstance() {
+        if (mBean == null) {
+            mBean = new MD5keyUtil();
+        }
+        keyBeanInit();
+        return mBean;
+    }
+
+
+    // 这是keyBean这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数
+     MD5keyUtil() {
+        keyBeanInit();
+        return;
+    }
+
+    /* keyBeanInit是一个初始化函数,初始化核心变量,装入标准的幻数 */
+    private static void keyBeanInit() {
+        count[0] = 0L;
+        count[1] = 0L;
+        // /* Load magic initialization constants.
+        state[0] = 0x67452301L;
+        state[1] = 0xefcdab89L;
+        state[2] = 0x98badcfeL;
+        state[3] = 0x10325476L;
+        return;
+    }
+
+    /*
+     * F, G, H ,I 是4个基本的keyBean函数,在原始的keyBean的C实现中,由于它们是 简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们 实现成了private方法,名字保持了原来C中的。
+     */
+    private long F(long x, long y, long z) {
+        return (x & y) | ((~x) & z);
+    }
+
+    private long G(long x, long y, long z) {
+        return (x & z) | (y & (~z));
+    }
+
+    private long H(long x, long y, long z) {
+        return x ^ y ^ z;
+    }
+
+    private long I(long x, long y, long z) {
+        return y ^ (x | (~z));
+    }
+
+    /*
+     * FF,GG,HH和II将调用F,G,H,I进行近一步变换 FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate
+     * from addition to prevent recomputation.
+     */
+    private long FF(long a, long b, long c, long d, long x, long s, long ac) {
+        a += F(b, c, d) + x + ac;
+        a = ((int) a << s) | ((int) a >>> (32 - s));
+        a += b;
+        return a;
+    }
+
+    private long GG(long a, long b, long c, long d, long x, long s, long ac) {
+        a += G(b, c, d) + x + ac;
+        a = ((int) a << s) | ((int) a >>> (32 - s));
+        a += b;
+        return a;
+    }
+
+    private long HH(long a, long b, long c, long d, long x, long s, long ac) {
+        a += H(b, c, d) + x + ac;
+        a = ((int) a << s) | ((int) a >>> (32 - s));
+        a += b;
+        return a;
+    }
+
+    private long II(long a, long b, long c, long d, long x, long s, long ac) {
+        a += I(b, c, d) + x + ac;
+        a = ((int) a << s) | ((int) a >>> (32 - s));
+        a += b;
+        return a;
+    }
+
+    /*
+     * keyBeanUpdate是keyBean的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个 函数由getkeyBeanofStr调用,调用之前需要调用keyBeaninit,因此把它设计成private的
+     */
+    private void keyBeanUpdate(byte[] inbuf, int inputLen) {
+        int i, index, partLen;
+        byte[] block = new byte[64];
+        index = (int) (count[0] >>> 3) & 0x3F;
+        // /* Update number of bits */
+        if ((count[0] += (inputLen << 3)) < (inputLen << 3))
+            count[1]++;
+        count[1] += (inputLen >>> 29);
+        partLen = 64 - index;
+        // Transform as many times as possible.
+        if (inputLen >= partLen) {
+            keyBeanMemcpy(buffer, inbuf, index, 0, partLen);
+            keyBeanTransform(buffer);
+            for (i = partLen; i + 63 < inputLen; i += 64) {
+                keyBeanMemcpy(block, inbuf, 0, i, 64);
+                keyBeanTransform(block);
+            }
+            index = 0;
+        } else
+            i = 0;
+        // /* Buffer remaining input */
+        keyBeanMemcpy(buffer, inbuf, index, i, inputLen - i);
+    }
+
+    /*
+     * keyBeanFinal整理和填写输出结果
+     */
+    private void keyBeanFinal() {
+        byte[] bits = new byte[8];
+        int index, padLen;
+        // /* Save number of bits */
+        Encode(bits, count, 8);
+        // /* Pad out to 56 mod 64.
+        index = (int) (count[0] >>> 3) & 0x3f;
+        padLen = (index < 56) ? (56 - index) : (120 - index);
+        keyBeanUpdate(PADDING, padLen);
+        // /* Append length (before padding) */
+        keyBeanUpdate(bits, 8);
+        // /* Store state in digest */
+        Encode(digest, state, 16);
+    }
+
+    /*
+     * keyBeanMemcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的 字节拷贝到output的outpos位置开始
+     */
+    private void keyBeanMemcpy(byte[] output, byte[] input, int outpos, int inpos, int len) {
+        int i;
+        for (i = 0; i < len; i++)
+            output[outpos + i] = input[inpos + i];
+    }
+
+    /*
+     * keyBeanTransform是keyBean核心变换程序,有keyBeanUpdate调用,block是分块的原始字节
+     */
+    private void keyBeanTransform(byte block[]) {
+        long a = state[0], b = state[1], c = state[2], d = state[3];
+        long[] x = new long[16];
+        Decode(x, block, 64);
+        /* Round 1 */
+        a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
+        d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
+        c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
+        b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
+        a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
+        d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
+        c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
+        b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
+        a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
+        d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
+        c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
+        b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
+        a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
+        d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
+        c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
+        b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */
+        /* Round 2 */
+        a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
+        d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
+        c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
+        b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
+        a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
+        d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
+        c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
+        b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
+        a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
+        d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
+        c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
+        b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
+        a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
+        d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
+        c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
+        b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */
+        /* Round 3 */
+        a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
+        d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
+        c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
+        b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
+        a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
+        d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
+        c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
+        b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
+        a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
+        d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
+        c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
+        b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
+        a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
+        d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
+        c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
+        b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */
+        /* Round 4 */
+        a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
+        d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
+        c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
+        b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
+        a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
+        d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
+        c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
+        b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
+        a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
+        d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
+        c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
+        b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
+        a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
+        d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
+        c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
+        b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */
+        state[0] += a;
+        state[1] += b;
+        state[2] += c;
+        state[3] += d;
+    }
+
+    /*
+     * Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的, 只拆低32bit,以适应原始C实现的用途
+     */
+    private void Encode(byte[] output, long[] input, int len) {
+        int i, j;
+        for (i = 0, j = 0; j < len; i++, j += 4) {
+            output[j] = (byte) (input[i] & 0xffL);
+            output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL);
+            output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL);
+            output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL);
+        }
+    }
+
+    /*
+     * Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的, 只合成低32bit,高32bit清零,以适应原始C实现的用途
+     */
+    private void Decode(long[] output, byte[] input, int len) {
+        int i, j;
+
+        for (i = 0, j = 0; j < len; i++, j += 4)
+            output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8) | (b2iu(input[j + 2]) << 16) | (b2iu(input[j + 3]) << 24);
+        return;
+    }
+
+    /*
+     * b2iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算
+     */
+     static long b2iu(byte b) {
+        return b < 0 ? b & 0x7F + 128 : b;
+    }
+
+    /*
+     * byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示, 因为java中的byte的toString无法实现这一点,我们又没有C语言中的 sprintf(outbuf,"%02X",ib)
+     */
+     static String byteHEX(byte ib) {
+        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+        char[] ob = new char[2];
+        ob[0] = Digit[(ib >>> 4) & 0X0F];
+        ob[1] = Digit[ib & 0X0F];
+        String s = new String(ob);
+        return s;
+    }
+}

+ 223 - 0
okhttp2/src/main/java/com/mylove/okhttp/ObservableRequest.java

@@ -0,0 +1,223 @@
+package com.mylove.okhttp;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+
+import com.mylove.baselib.log.JLog;
+import com.mylove.baselib.utils.FormatUtil;
+
+import java.io.File;
+import java.util.Map;
+
+import okhttp3.FormBody;
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import rx.Observable;
+import rx.Subscriber;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
+
+/**
+ * @author myLove
+ * @time 2017/11/15 14:19
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+class ObservableRequest {
+
+    @SuppressLint("StaticFieldLeak")
+    private static ObservableRequest instance;
+    @SuppressLint("StaticFieldLeak")
+    private static Context mContext;
+    private static RequestType requestType;
+    private static CallType callType;
+
+    static ObservableRequest getInstance(Context context, RequestType type1, CallType type2) {
+        if (instance == null) {
+            synchronized (ObservableRequest.class) {
+                if (instance == null) {
+                    instance = new ObservableRequest();
+                    mContext = context;
+                    requestType = type1;
+                    callType = type2;
+                }
+            }
+        }
+        return instance;
+    }
+
+    void request(String url, Map<Object, Object> oMap, final onOkHttpListener<String, String> onOkHttpListener) {
+        getObservable(url, oMap).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Subscriber<String>() {
+                    public void onCompleted() {
+                        onOkHttpListener.onCompleted();
+                    }
+
+                    public void onError(Throwable e) {
+                        onOkHttpListener.onFailure(e.getMessage());
+                    }
+
+                    public void onNext(String s) {
+                        onOkHttpListener.onSuccess(s);
+                    }
+                });
+    }
+
+    private Observable<String> getObservable(final String url, final Map<Object, Object> oMap) {
+        return Observable.create(new Observable.OnSubscribe<String>() {
+            public void call(Subscriber<? super String> subscriber) {
+                send(url, oMap, subscriber);
+            }
+        });
+    }
+
+    private void send(final String url, final Map<Object, Object> oMap, final Subscriber<? super String> subscriber) {
+        final String mCacheUrl;
+        if (FormatUtil.isMapNotEmpty(oMap)) {
+            mCacheUrl = url + oMap.toString();
+        } else {
+            mCacheUrl = url;
+        }
+        if (Internet.ifInternet(mContext)) {
+            Request request = getRequest(url, oMap);
+            OkCall.getInstance(mContext, mCacheUrl, request, subscriber, callType).sendCall();
+        } else {
+            String json = CacheUtils.getInstance(mContext).getCacheToLocalJson(mCacheUrl);
+            if (FormatUtil.isNotEmpty(json)) {
+                subscriber.onNext(json);
+                subscriber.onCompleted();
+            } else {
+                subscriber.onError(new Error("网络错误"));
+            }
+        }
+    }
+
+    /**
+     * 判断请求方式
+     *
+     * @param url  地址
+     * @param oMap 键值
+     * @return request
+     */
+    private Request getRequest(String url, Map<Object, Object> oMap) {
+        if (requestType == null) {
+            requestType = RequestType.POST;
+        }
+        switch (requestType) {
+            case GET:
+                return get(url, oMap);
+            case POST:
+                return post(url, oMap);
+            case UP_FILE:
+                return upFile(url, oMap);
+            case ALL:
+                return upAll(url, oMap);
+            default:
+                return post(url, oMap);
+        }
+    }
+
+    /**
+     * 上传文件
+     *
+     * @param url  地址
+     * @param oMap 键值
+     * @return request
+     */
+    private Request upFile(String url, Map<Object, Object> oMap) {
+        MultipartBody.Builder builder = new MultipartBody.Builder()
+                .setType(MultipartBody.FORM);
+        if (FormatUtil.isMapNotEmpty(oMap)) {
+            for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
+                File file = new File(entry.getValue().toString());
+                int indexOf = entry.getValue().toString().indexOf("/");
+                RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
+                String fileName = entry.getKey().toString().substring(indexOf + 1, entry.getKey().toString().length());
+                builder.addFormDataPart(entry.getKey().toString(), fileName, requestBody);
+            }
+        }
+        MultipartBody multipartBody = builder.build();
+        return new Request.Builder()
+                .url(url)
+                .post(multipartBody)
+                .build();
+    }
+
+    /**
+     * 参数和文件一起上传
+     *
+     * @param url  地址
+     * @param oMap 键值
+     * @return request
+     */
+    private Request upAll(String url, Map<Object, Object> oMap) {
+        MultipartBody.Builder builder = new MultipartBody.Builder()
+                .setType(MultipartBody.ALTERNATIVE);
+        if (FormatUtil.isMapNotEmpty(oMap)) {
+            for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
+                File file = new File(entry.getValue().toString());
+                int indexOf = entry.getValue().toString().lastIndexOf("/");
+                int indexOf1 = entry.getValue().toString().lastIndexOf(".");
+                if (indexOf > 0 && indexOf1 > 0) {
+                    RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
+                    String fileName = entry.getKey().toString().substring(indexOf + 1, entry.getKey().toString().length());
+                    builder.addFormDataPart(entry.getKey().toString(), fileName, requestBody);
+                } else {
+                    builder.addFormDataPart(entry.getKey().toString(), entry.getValue().toString());
+                }
+            }
+        }
+        MultipartBody multipartBody = builder.build();
+        return new Request.Builder()
+                .url(url)
+                .post(multipartBody)
+                .build();
+    }
+
+    /**
+     * get上传参数
+     *
+     * @param url  地址
+     * @param oMap 键值
+     * @return request
+     */
+    private Request get(String url, Map<Object, Object> oMap) {
+        StringBuilder str = new StringBuilder(url);
+        if (FormatUtil.isMapNotEmpty(oMap)) {
+            str.append("?");
+            for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
+                str.append(entry.getKey()).append("=").append(entry).append("&");
+            }
+            str = new StringBuilder(str.substring(0, str.length() - 1));
+        }
+        return new Request.Builder()
+                .url(str.toString())
+                .get()
+                .build();
+    }
+
+    /**
+     * post上传参数
+     *
+     * @param url  地址
+     * @param oMap 键值
+     * @return request
+     */
+    private Request post(String url, Map<Object, Object> oMap) {
+        FormBody.Builder builder = new FormBody.Builder();
+        if (FormatUtil.isMapNotEmpty(oMap)) {
+            for (Map.Entry<Object, Object> entry : oMap.entrySet()) {
+                builder.add(entry.getKey().toString(), entry.getValue().toString());
+                JLog.i(entry.getKey() + "\t" + entry.getValue());
+            }
+        }
+        FormBody build = builder.build();
+        return new Request.Builder()
+                .url(url)
+                .post(build)
+                .build();
+    }
+}

+ 157 - 0
okhttp2/src/main/java/com/mylove/okhttp/OkCall.java

@@ -0,0 +1,157 @@
+package com.mylove.okhttp;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.support.annotation.NonNull;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.Cache;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import rx.Subscriber;
+
+/**
+ * @author myLove
+ * @time 2017/11/15 13:52
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+class OkCall {
+    @SuppressLint("StaticFieldLeak")
+    private static Context mContext;
+    private String mCacheUrl;
+    private Subscriber<? super String> subscriber;
+    private Call call;
+    @SuppressLint("StaticFieldLeak")
+    private static OkCall instance;
+    private CallType callType;
+    private static OkHttpClient okHttpClient;
+
+    private OkCall(String mCacheUrl, Request request, Subscriber<? super String> subscriber, CallType callType) {
+        this.mCacheUrl = mCacheUrl;
+        this.subscriber = subscriber;
+        this.call = okHttpClient.newCall(request);
+        this.callType = callType;
+    }
+
+    /**
+     * okHttpClient初始化,并添加拦截及缓存
+     *
+     * @param context    上下文
+     * @param mCacheUrl  缓存地址
+     * @param request    请求
+     * @param subscriber 返回
+     * @param callType   请求类型
+     * @return
+     */
+    public static OkCall getInstance(Context context, String mCacheUrl, Request request, Subscriber<? super String> subscriber, CallType callType) {
+        if (instance == null) {
+            synchronized (OkCall.class) {
+                if (instance == null) {
+                    mContext = context;
+                    OkHttpClient httpClient = new OkHttpClient();
+                    okHttpClient = httpClient.newBuilder()
+                            .addNetworkInterceptor(new CacheInterceptor())
+                            .cache(privateCache())
+                            .connectTimeout(30, TimeUnit.SECONDS)
+                            .readTimeout(30, TimeUnit.SECONDS)
+                            .build();
+                    instance = new OkCall(mCacheUrl, request, subscriber, callType);
+                }
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * 请求
+     */
+    void sendCall() {
+        if (callType == CallType.SYNC) {
+            sync();
+        } else if (callType == CallType.ASYNC) {
+            async();
+        }
+    }
+
+    /**
+     * 异步请求
+     */
+    private void sync() {
+        try {
+            Response execute = call.execute();
+            if (execute.isSuccessful()) {
+                String str = execute.body().string();
+                if (str.contains("<!DOCTYPE html>")) {
+                    subscriber.onError(new Exception("接口错误"));
+                } else {
+                    if (FormatUtil.isNotEmpty(mCacheUrl)) {
+                        CacheUtils.getInstance(mContext).setCacheToLocalJson(mCacheUrl, str);
+                    }
+                    subscriber.onNext(str);
+                    subscriber.onCompleted();
+                }
+            } else {
+                String json = CacheUtils.getInstance(mContext).getCacheToLocalJson(mCacheUrl);
+                if (FormatUtil.isNotEmpty(json)) {
+                    subscriber.onNext(json);
+                    subscriber.onCompleted();
+                } else {
+                    subscriber.onError(new Exception("请求失败"));
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            String json = CacheUtils.getInstance(mContext).getCacheToLocalJson(mCacheUrl);
+            if (FormatUtil.isNotEmpty(json)) {
+                subscriber.onNext(json);
+                subscriber.onCompleted();
+            } else {
+                subscriber.onError(new Exception(e));
+            }
+        }
+    }
+
+    /**
+     * 同步请求
+     */
+    private void async() {
+        call.enqueue(new Callback() {
+            public void onFailure(@NonNull Call call, @NonNull IOException e) {
+                String json = CacheUtils.getInstance(mContext).getCacheToLocalJson(mCacheUrl);
+                if (FormatUtil.isNotEmpty(json)) {
+                    subscriber.onNext(json);
+                    subscriber.onCompleted();
+                } else {
+                    subscriber.onError(new Exception(e));
+                }
+            }
+
+            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
+                String str = response.body().string();
+                if (str.contains("<!DOCTYPE html>")) {
+                    subscriber.onError(new Exception("接口错误"));
+                } else {
+                    if (FormatUtil.isNotEmpty(mCacheUrl)) {
+                        CacheUtils.getInstance(mContext).setCacheToLocalJson(mCacheUrl, str);
+                    }
+                    subscriber.onNext(str);
+                    subscriber.onCompleted();
+                }
+            }
+        });
+    }
+
+    /**
+     * 设置缓存路径,以及缓存文件大小
+     */
+    private static Cache privateCache() {
+        return new Cache(mContext.getCacheDir(), 1024 * 1024);
+    }
+}

+ 54 - 0
okhttp2/src/main/java/com/mylove/okhttp/OkHttpUtil.java

@@ -0,0 +1,54 @@
+package com.mylove.okhttp;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+
+import java.util.Map;
+
+/**
+ * @author myLove
+ * @time 2017/11/2 14:41
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+public class OkHttpUtil {
+    @SuppressLint("StaticFieldLeak")
+    private static OkHttpUtil instance;
+    @SuppressLint("StaticFieldLeak")
+    private static Context mContext;
+
+    public static OkHttpUtil getInstance(Context context) {
+        if (instance == null) {
+            synchronized (OkHttpUtil.class) {
+                if (instance == null) {
+                    instance = new OkHttpUtil();
+                    mContext = context;
+                }
+            }
+        }
+        return instance;
+    }
+
+    public AutoRequest get(String url) {
+        return AutoRequest.getInstance(mContext, url, RequestType.GET);
+    }
+
+    public AutoRequest post(String url) {
+//        request(url, oMap, onOkHttpListener);
+        return AutoRequest.getInstance(mContext, url, RequestType.POST);
+    }
+
+    public AutoRequest postUpFile(String url) {
+        return AutoRequest.getInstance(mContext, url, RequestType.UP_FILE);
+    }
+
+    public AutoRequest postAll(String url) {
+        return AutoRequest.getInstance(mContext, url, RequestType.UP_FILE);
+    }
+
+    @Deprecated
+    public void postRequest(String url, Map<Object, Object> oMap, final onOkHttpListener<String, String> onOkHttpListener) {
+//        request(url, oMap, onOkHttpListener);
+    }
+}

+ 15 - 0
okhttp2/src/main/java/com/mylove/okhttp/RequestType.java

@@ -0,0 +1,15 @@
+package com.mylove.okhttp;
+
+/**
+ * @author myLove
+ * @time 2017/11/15 14:15
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+enum RequestType {
+    GET,
+    POST,
+    UP_FILE,
+    ALL
+}

+ 39 - 0
okhttp2/src/main/java/com/mylove/okhttp/ShowToast.java

@@ -0,0 +1,39 @@
+package com.mylove.okhttp;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.widget.Toast;
+
+/**
+ * @author myLove
+ * @time 2017/10/31 12:24
+ * @e-mail mylove.520.y@gmail.com
+ * @overview 吐司工具类
+ */
+
+class ShowToast {
+    @SuppressLint("StaticFieldLeak")
+    private static ShowToast instance;
+    private static Context mContext;
+    private static boolean visibleBoo = true;
+
+
+    public static ShowToast getInstance(Context context) {
+        if (mContext != null) {
+            visibleBoo = mContext != context;
+        }
+        mContext = context;
+        if (instance == null) {
+            synchronized (ShowToast.class) {
+                instance = new ShowToast();
+            }
+        }
+        return instance;
+    }
+
+    void show(String msg) {
+        if (visibleBoo) {
+            Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
+        }
+    }
+}

+ 16 - 0
okhttp2/src/main/java/com/mylove/okhttp/onOkHttpListener.java

@@ -0,0 +1,16 @@
+package com.mylove.okhttp;
+
+/**
+ * @author myLove
+ * @time 2017/11/2 14:51
+ * @e-mail mylove.520.y@gmail.com
+ * @overview
+ */
+
+public interface onOkHttpListener<K, T> {
+    void onCompleted();
+
+    void onSuccess(K k);
+
+    void onFailure(T t);
+}

+ 3 - 0
okhttp2/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">okhttp</string>
+</resources>

+ 17 - 0
okhttp2/src/test/java/com/mylove/okhttp/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.mylove.okhttp;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() throws Exception {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 1 - 0
settings.gradle

@@ -0,0 +1 @@
+include ':app', ':okhttp2'