diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4057b66 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Built application files +*.apk +*.ap_ +# Files for the ART/Dalvik VM +*.dex +# Java class files +*.class +# Generated files +bin/ +gen/ +out/ +# Gradle files +.gradle/ +build/ +# Local configuration file (sdk path, etc) +local.properties +# Proguard folder generated by Eclipse +proguard/ +# Log Files +*.log +# Android Studio Navigation editor temp files +.navigation/ +# Android Studio captures folder +captures/ +# Intellij +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/libraries +.idea/ +# Keystore files +*.jks +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..2765586 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,46 @@ +apply plugin: 'com.android.application' +android { + compileSdkVersion 27 + buildToolsVersion "27.0.2" + defaultConfig { + applicationId "com.huitian.im" + minSdkVersion rootProject.ext.android["minSdkVersion"] + targetSdkVersion rootProject.ext.android["targetSdkVersion"] + versionCode rootProject.ext.android["versionCode"] + versionName rootProject.ext.android["versionName"] + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + multiDexEnabled true + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + lintOptions { + checkReleaseBuilds false + abortOnError false + } + + packagingOptions { + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/NOTICE' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/LICENSE' + exclude 'META-INF/LICENSE.txt' + } + + +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile project(':dmvp') + compile 'com.android.support.constraint:constraint-layout:1.0.2' + testCompile 'junit:junit:4.12' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..d60781b --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,33 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in D:\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# 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 + +# 极光推送 +-dontoptimize +-dontpreverify +-dontwarn cn.jpush.** +-keep class cn.jpush.** { *; } +-dontwarn cn.jiguang.** +-keep class cn.jiguang.** { *; } diff --git a/app/src/androidTest/java/com/huitian/chen/oamanager/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/huitian/chen/oamanager/ExampleInstrumentedTest.java new file mode 100644 index 0000000..f98e3c0 --- /dev/null +++ b/app/src/androidTest/java/com/huitian/chen/oamanager/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.huitian.chen.oamanager; + +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.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.example.chen.oamanager", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..43b143a --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/huitian/ui/activity/TestFragmentActivity.java b/app/src/main/java/com/huitian/ui/activity/TestFragmentActivity.java new file mode 100644 index 0000000..66204e0 --- /dev/null +++ b/app/src/main/java/com/huitian/ui/activity/TestFragmentActivity.java @@ -0,0 +1,36 @@ +package com.huitian.ui.activity; + +import android.os.Bundle; +import android.widget.FrameLayout; + +import com.chen.common.base.BaseActivity; +import com.chen.common.di.component.AppComponent; +import com.huitian.chen.R; + +import butterknife.Bind; + +/** + * @author :ChenYangYi + * @time :2018/4/3 + * @desc : + */ + +public class TestFragmentActivity extends BaseActivity { + @Bind(R.id.fl_container) + FrameLayout flContainer; + + @Override + public int getLayoutId() { + return R.layout.activity_fragment; + } + + @Override + public void initData(Bundle savedInstanceState) { + + } + + @Override + public void setupActivityComponent(AppComponent appComponent) { + + } +} diff --git a/app/src/main/res/drawable-xhdpi/jpush_notification_icon.png b/app/src/main/res/drawable-xhdpi/jpush_notification_icon.png new file mode 100644 index 0000000..74bae9b Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/jpush_notification_icon.png differ diff --git a/app/src/main/res/drawable/deadpool.png b/app/src/main/res/drawable/deadpool.png new file mode 100644 index 0000000..250af95 Binary files /dev/null and b/app/src/main/res/drawable/deadpool.png differ diff --git a/app/src/main/res/drawable/ironman.png b/app/src/main/res/drawable/ironman.png new file mode 100644 index 0000000..11d0a4e Binary files /dev/null and b/app/src/main/res/drawable/ironman.png differ diff --git a/app/src/main/res/drawable/shape_btn.xml b/app/src/main/res/drawable/shape_btn.xml new file mode 100644 index 0000000..bcf87b1 --- /dev/null +++ b/app/src/main/res/drawable/shape_btn.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_fragment.xml b/app/src/main/res/layout/activity_fragment.xml new file mode 100644 index 0000000..3aee8a6 --- /dev/null +++ b/app/src/main/res/layout/activity_fragment.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..cde69bc Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..9a078e3 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c133a0c Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..efc028a Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..324e72c Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..9bec2e6 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..aee44e1 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..34947cd Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..60782e5 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,30 @@ + + + #208af2 + #303F9F + #FF4081 + #208af2 + #F8F8F8 + #D3D1D1 + #403F3F + #72A3F4 + #F66565 + #E6A321 + #2A2A2A + #393939 + #91DFC5 + #EE4949 + #BEBCBC + #3383DD + #363636 + #C7C4C4 + #3383DD + #D3D1D1 + #F7F4F4 + #FD0001 + #479AF7 + #CACACA + #AFAFAF + #208af2 + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..5fc82c2 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,7 @@ + + + 11dp + 12dp + 14dp + 15dp + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..4094174 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,14 @@ + + 回天IM + + + 你好! + hi,你好! + 今天去玩吗? + 老司机又开车? + 呵呵 + 去就去 + 可以 + gogogo + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..ccb0dbd --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/app/src/test/java/com/huitian/chen/oamanager/ExampleUnitTest.java b/app/src/test/java/com/huitian/chen/oamanager/ExampleUnitTest.java new file mode 100644 index 0000000..6e597f8 --- /dev/null +++ b/app/src/test/java/com/huitian/chen/oamanager/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.huitian.chen.oamanager; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..d4732be --- /dev/null +++ b/build.gradle @@ -0,0 +1,25 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply from: "config.gradle" +buildscript { + repositories { + jcenter() + google() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.3' + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + maven { url "https://jitpack.io" } + google() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/config.gradle b/config.gradle new file mode 100644 index 0000000..53d4085 --- /dev/null +++ b/config.gradle @@ -0,0 +1,110 @@ +ext { + + android = [ + compileSdkVersion : 27, + buildToolsVersion : "27.0.3", + minSdkVersion : 15, + targetSdkVersion : 27, + versionCode : 1, + versionName : "1.0.0" + ] + + version = [ + androidSupportSdkVersion: "27.0.2", + retrofitSdkVersion : "2.3.0", + dagger2SdkVersion : "2.14.1", + glideSdkVersion : "4.5.0", + butterknifeSdkVersion : "8.8.1", + rxlifecycleSdkVersion : "1.0", + rxlifecycle2SdkVersion : "2.2.1", + espressoSdkVersion : "3.0.1", + canarySdkVersion : "1.5.4" + ] + + dependencies = [ + //support + "appcompat-v7" : "com.android.support:appcompat-v7:${version["androidSupportSdkVersion"]}", + "design" : "com.android.support:design:${version["androidSupportSdkVersion"]}", + "support-v4" : "com.android.support:support-v4:${version["androidSupportSdkVersion"]}", + "cardview-v7" : "com.android.support:cardview-v7:${version["androidSupportSdkVersion"]}", + "annotations" : "com.android.support:support-annotations:${version["androidSupportSdkVersion"]}", + "recyclerview-v7" : "com.android.support:recyclerview-v7:${version["androidSupportSdkVersion"]}", + + //network + "retrofit" : "com.squareup.retrofit2:retrofit:${version["retrofitSdkVersion"]}", + "retrofit-converter-gson" : "com.squareup.retrofit2:converter-gson:${version["retrofitSdkVersion"]}", + "retrofit-adapter-rxjava" : "com.squareup.retrofit2:adapter-rxjava:${version["retrofitSdkVersion"]}", + "retrofit-adapter-rxjava2" : "com.squareup.retrofit2:adapter-rxjava2:${version["retrofitSdkVersion"]}", + "okhttp3" : "com.squareup.okhttp3:okhttp:3.9.1", + "okhttp-urlconnection" : "com.squareup.okhttp:okhttp-urlconnection:2.0.0", + "glide" : "com.github.bumptech.glide:glide:${version["glideSdkVersion"]}", + "glide-compiler" : "com.github.bumptech.glide:compiler:${version["glideSdkVersion"]}", + "glide-loader-okhttp3" : "com.github.bumptech.glide:okhttp3-integration:${version["glideSdkVersion"]}", + "picasso" : "com.squareup.picasso:picasso:2.5.2", + + //view + "autolayout" : "com.zhy:autolayout:1.4.5", + "butterknife" : "com.jakewharton:butterknife:${version["butterknifeSdkVersion"]}", + "butterknife-compiler" : "com.jakewharton:butterknife-compiler:${version["butterknifeSdkVersion"]}", + "pickerview" : "com.contrarywind:Android-PickerView:3.2.5", + "photoview" : "com.github.chrisbanes.photoview:library:1.2.3", + "numberprogressbar" : "com.daimajia.numberprogressbar:library:1.2@aar", + "nineoldandroids" : "com.nineoldandroids:library:2.4.0", + "paginate" : "com.github.markomilos:paginate:0.5.1", + "vlayout" : "com.alibaba.android:vlayout:1.1.0@aar", + + //rx1 + "rxandroid" : "io.reactivex:rxandroid:1.2.1", + "rxjava" : "io.reactivex:rxjava:1.3.0", + "rxlifecycle" : "com.trello:rxlifecycle:${version["rxlifecycleSdkVersion"]}", + "rxlifecycle-components" : "com.trello:rxlifecycle-components:${version["rxlifecycleSdkVersion"]}", + "rxcache" : "com.github.VictorAlbertos.RxCache:runtime:1.7.0-1.x", + "rxcache-jolyglot-gson" : "com.github.VictorAlbertos.Jolyglot:gson:0.0.3", + "rxbinding-recyclerview-v7": "com.jakewharton.rxbinding:rxbinding-recyclerview-v7:1.0.1", + "rxpermissions" : "com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar", + "rxerrorhandler" : "me.jessyan:rxerrorhandler:1.0.1", + + //rx2 + "rxandroid2" : "io.reactivex.rxjava2:rxandroid:2.0.1", + "rxjava2" : "io.reactivex.rxjava2:rxjava:2.1.8", + "rxlifecycle2" : "com.trello.rxlifecycle2:rxlifecycle:${version["rxlifecycle2SdkVersion"]}", + "rxlifecycle2-android" : "com.trello.rxlifecycle2:rxlifecycle-android:${version["rxlifecycle2SdkVersion"]}", + "rxlifecycle2-components" : "com.trello.rxlifecycle2:rxlifecycle-components:${version["rxlifecycle2SdkVersion"]}", + "rxcache2" : "com.github.VictorAlbertos.RxCache:runtime:1.8.3-2.x", + "rxpermissions2" : "com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar", + "rxerrorhandler2" : "me.jessyan:rxerrorhandler:2.1.0", + + //tools + "dagger2" : "com.google.dagger:dagger:${version["dagger2SdkVersion"]}", + "dagger2-android" : "com.google.dagger:dagger-android:${version["dagger2SdkVersion"]}", + "dagger2-android-support" : "com.google.dagger:dagger-android-support:${version["dagger2SdkVersion"]}", + "dagger2-compiler" : "com.google.dagger:dagger-compiler:${version["dagger2SdkVersion"]}", + "dagger2-android-processor": "com.google.dagger:dagger-android-processor:${version["dagger2SdkVersion"]}", + "androideventbus" : "org.simple:androideventbus:1.0.5.1", + "otto" : "com.squareup:otto:1.3.8", + "gson" : "com.google.code.gson:gson:2.8.2", + "multidex" : "com.android.support:multidex:1.0.1", + "javax.annotation" : "javax.annotation:jsr250-api:1.0", + "arouter" : "com.alibaba:arouter-api:1.3.0", + "arouter-compiler" : "com.alibaba:arouter-compiler:1.1.4", + "progressmanager" : "me.jessyan:progressmanager:1.5.0", + "retrofit-url-manager" : "me.jessyan:retrofit-url-manager:1.1.0", + "lifecyclemodel" : "me.jessyan:lifecyclemodel:1.0.1", + + //test + "junit" : "junit:junit:4.12", + "androidJUnitRunner" : "android.support.test.runner.AndroidJUnitRunner", + "runner" : "com.android.support.test:runner:1.0.1", + "espresso-core" : "com.android.support.test.espresso:espresso-core:${version["espressoSdkVersion"]}", + "espresso-contrib" : "com.android.support.test.espresso:espresso-contrib:${version["espressoSdkVersion"]}", + "espresso-intents" : "com.android.support.test.espresso:espresso-intents:${version["espressoSdkVersion"]}", + "mockito-core" : "org.mockito:mockito-core:1.+", + "timber" : "com.jakewharton.timber:timber:4.6.0", + "logger" : "com.orhanobut:logger:2.1.1", + "canary-debug" : "com.squareup.leakcanary:leakcanary-android:${version["canarySdkVersion"]}", + "canary-release" : "com.squareup.leakcanary:leakcanary-android-no-op:${version["canarySdkVersion"]}", + "umeng-analytics" : "com.umeng.analytics:analytics:6.0.1" + ] + + +} diff --git a/dmvp/.gitignore b/dmvp/.gitignore new file mode 100644 index 0000000..4877b12 --- /dev/null +++ b/dmvp/.gitignore @@ -0,0 +1,2 @@ +/build +/*.iml \ No newline at end of file diff --git a/dmvp/build.gradle b/dmvp/build.gradle new file mode 100644 index 0000000..74a4e7d --- /dev/null +++ b/dmvp/build.gradle @@ -0,0 +1,65 @@ +apply plugin: 'com.android.library' + + +android { + compileSdkVersion rootProject.ext.android["compileSdkVersion"] + buildToolsVersion rootProject.ext.android["buildToolsVersion"] + + defaultConfig { + minSdkVersion rootProject.ext.android["minSdkVersion"] + targetSdkVersion rootProject.ext.android["targetSdkVersion"] + versionCode rootProject.ext.android["versionCode"] + versionName rootProject.ext.android["versionName"] + } + buildTypes { + release { + buildConfigField "boolean", "LOG_DEBUG", "false" + } + debug { + buildConfigField "boolean", "LOG_DEBUG", "true" + } + } +} + + +ext { + isLibrary = true + pomArtifactId = "Common" + pomDescription = "Common of android picker" +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + + //support + compile(rootProject.ext.dependencies["support-v4"]) { + exclude module: 'support-annotations' + } + compile(rootProject.ext.dependencies["appcompat-v7"]) { + exclude module: 'support-annotations' + exclude module: 'support-v4' + } + compile(rootProject.ext.dependencies["design"]) { + exclude module: 'support-annotations' + exclude module: 'appcompat-v7' + exclude module: 'support-v4' + } + compile rootProject.ext.dependencies["annotations"] + + //retrofit和rxjava + compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3' + compile 'com.squareup.okhttp3:logging-interceptor:3.1.2' + compile 'io.reactivex:rxjava:1.0.1' + compile 'io.reactivex:rxandroid:1.0.1' + compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4' + compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4' + compile 'com.jakewharton:butterknife:7.0.1'//view注解 + compile 'com.jaeger.statusbaruitl:library:1.3.6' // 沉浸式状态栏 + compile 'com.android.support:multidex:1.0.1' + + + compile rootProject.ext.dependencies["dagger2"] + annotationProcessor rootProject.ext.dependencies["dagger2-compiler"] +} + + diff --git a/dmvp/src/main/AndroidManifest.xml b/dmvp/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8e4e839 --- /dev/null +++ b/dmvp/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/dmvp/src/main/java/com/chen/common/app/App.java b/dmvp/src/main/java/com/chen/common/app/App.java new file mode 100644 index 0000000..778f1f8 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/app/App.java @@ -0,0 +1,35 @@ +package com.chen.common.app; + +import android.support.annotation.NonNull; + +import com.chen.common.di.component.AppComponent; +import com.chen.common.di.component.DaggerAppComponent; +import com.chen.common.di.module.AppModule; +import com.chen.common.di.module.NetModule; + + +/** + * Created by Chen on 2017/4/17. + */ + +public class App extends BaseApplication implements IApp { + + private AppComponent appComponent; + public static final String SERVICE_URL = "http://gank.io/api/"; + + @Override + public void onCreate() { + super.onCreate(); + appComponent = DaggerAppComponent + .builder() + .appModule(new AppModule(this)) + .netModule(new NetModule(SERVICE_URL)) + .build(); + } + + @NonNull + @Override + public AppComponent getAppComponent() { + return appComponent; + } +} diff --git a/dmvp/src/main/java/com/chen/common/app/AppManager.java b/dmvp/src/main/java/com/chen/common/app/AppManager.java new file mode 100644 index 0000000..9ae8037 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/app/AppManager.java @@ -0,0 +1,180 @@ + +package com.chen.common.app; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; + +import java.util.Stack; + +/** + * activity管理 + */ +public class AppManager { + private static Stack activityStack; + private volatile static AppManager instance; + + private AppManager() { + + } + /** + * 单一实例 + */ + public static AppManager getAppManager() { + if (instance == null) { + synchronized (AppManager.class){ + if(instance==null){ + instance = new AppManager(); + instance.activityStack = new Stack(); + } + } + + } + return instance; + } + + /** + * 添加Activity到堆栈 + */ + public void addActivity(Activity activity) { + if (activityStack == null) { + activityStack = new Stack(); + } + activityStack.add(activity); + } + + /** + * 获取当前Activity(堆栈中最后一个压入的) + */ + public Activity currentActivity() { + try { + Activity activity = activityStack.lastElement(); + return activity; + } catch (Exception e) { +// e.printStackTrace(); + return null; + } + } + + /** + * 获取当前Activity的前一个Activity + */ + public Activity preActivity() { + int index = activityStack.size() - 2; + if (index < 0) { + return null; + } + Activity activity = activityStack.get(index); + return activity; + } + + /** + * 结束当前Activity(堆栈中最后一个压入的) + */ + public void finishActivity() { + Activity activity = activityStack.lastElement(); + finishActivity(activity); + } + + /** + * 结束指定的Activity + */ + public void finishActivity(Activity activity) { + if (activity != null) { + activityStack.remove(activity); + activity.finish(); + activity = null; + } + } + + /** + * 移除指定的Activity + */ + public void removeActivity(Activity activity) { + if (activity != null) { + activityStack.remove(activity); + activity = null; + } + } + + /** + * 结束指定类名的Activity + */ + public void finishActivity(Class cls) { + try { + for (Activity activity : activityStack) { + if (activity.getClass().equals(cls)) { + finishActivity(activity); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + + /** + * 结束所有Activity + */ + public void finishAllActivity() { + for (int i = 0, size = activityStack.size(); i < size; i++) { + if (null != activityStack.get(i)) { + activityStack.get(i).finish(); + } + } + activityStack.clear(); + } + + /** + * 返回到指定的activity + * + * @param cls + */ + public void returnToActivity(Class cls) { + while (activityStack.size() != 0) + if (activityStack.peek().getClass() == cls) { + break; + } else { + finishActivity(activityStack.peek()); + } + } + + + /** + * 是否已经打开指定的activity + * @param cls + * @return + */ + public boolean isOpenActivity(Class cls) { + if (activityStack!=null){ + for (int i = 0, size = activityStack.size(); i < size; i++) { + if (cls == activityStack.peek().getClass()) { + return true; + } + } + } + return false; + } + + /** + * 退出应用程序 + * + * @param context 上下文 + * @param isBackground 是否开开启后台运行 + */ + public void AppExit(Context context, Boolean isBackground) { + try { + finishAllActivity(); + ActivityManager activityMgr = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + activityMgr.restartPackage(context.getPackageName()); + } catch (Exception e) { + + } finally { + // 注意,如果您有后台程序运行,请不要支持此句子 + if (!isBackground) { + System.exit(0); + } + } + } +} \ No newline at end of file diff --git a/dmvp/src/main/java/com/chen/common/app/BaseApplication.java b/dmvp/src/main/java/com/chen/common/app/BaseApplication.java new file mode 100644 index 0000000..a8bb39e --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/app/BaseApplication.java @@ -0,0 +1,42 @@ +package com.chen.common.app; + +import android.content.Context; +import android.content.res.Resources; +import android.support.multidex.MultiDex; +import android.support.multidex.MultiDexApplication; + +/** + * APPLICATION + */ +public class BaseApplication extends MultiDexApplication { + + private static BaseApplication baseApplication; + + @Override + public void onCreate() { + super.onCreate(); + baseApplication = this; + } + + public static Context getAppContext() { + return baseApplication; + } + public static Resources getAppResources() { + return baseApplication.getResources(); + } + @Override + public void onTerminate() { + super.onTerminate(); + } + + /** + * 分包 + * @param base + */ + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + MultiDex.install(this); + } + +} diff --git a/dmvp/src/main/java/com/chen/common/app/IApp.java b/dmvp/src/main/java/com/chen/common/app/IApp.java new file mode 100644 index 0000000..9611051 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/app/IApp.java @@ -0,0 +1,35 @@ +/** + * Copyright 2017 JessYan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.chen.common.app; + +import android.support.annotation.NonNull; + +import com.chen.common.di.component.AppComponent; + + +/** + * ================================================ + * 框架要求框架中的每个 {@link android.app.Application} 都需要实现此类,以满足规范 + * + * Created by JessYan on 25/04/2017 14:54 + * Contact me + * Follow me + * ================================================ + */ +public interface IApp { + @NonNull + AppComponent getAppComponent(); +} diff --git a/dmvp/src/main/java/com/chen/common/base/BaseActivity.java b/dmvp/src/main/java/com/chen/common/base/BaseActivity.java new file mode 100644 index 0000000..883878f --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/base/BaseActivity.java @@ -0,0 +1,187 @@ +package com.chen.common.base; + + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.os.Bundle; +import android.support.annotation.ColorInt; +import android.support.v7.app.AppCompatActivity; +import android.view.Window; + +import com.jaeger.library.StatusBarUtil; +import com.chen.common.R; +import com.chen.common.app.AppManager; +import com.chen.common.rx.RxManager; +import com.chen.common.utils.CUtils; +import com.chen.common.utils.ToastUitl; +import com.chen.common.widget.LoadingDialog; +import com.chen.common.di.component.AppComponent; + +import javax.inject.Inject; + +import butterknife.ButterKnife; + +/** + * Activity基类 + */ +public abstract class BaseActivity extends AppCompatActivity { + @Inject + public T mPresenter; // 注入得到presenter的实例对象 + @Inject + public RxManager mRxManager; + public Context mContext; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + doBeforeSetcontentView(); + setContentView(getLayoutId()); + ButterKnife.bind(this); + mContext = this; + setupActivityComponent(CUtils.obtainAppComponentFromContext(mContext)); // dagger2注入 + this.initData(savedInstanceState); + } + + /** + * 设置layout前配置 + */ + private void doBeforeSetcontentView() { + // 把actvity放到application栈中管理 + AppManager.getAppManager().addActivity(this); + // 无标题 + requestWindowFeature(Window.FEATURE_NO_TITLE); + // 设置竖屏 + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + // 沉浸式状态栏 + setStatusBar(); + } + + /** + * 默认沉浸式主题色, + */ + private void setStatusBar() { + StatusBarUtil.setColor(this, getResources().getColor(R.color.colorPrimary), 0); + } + + /** + * 默认沉浸式主题色, + */ + private void setStatusBar(@ColorInt int color) { + StatusBarUtil.setColor(this, color, 0); + } + + /*********************子类实现*****************************/ + //获取布局文件 + public abstract int getLayoutId(); + + //初始化view + public abstract void initData(Bundle savedInstanceState); + + //这里提供 AppComponent 对象给 BaseActivity 的子类, 用于 Dagger2 的依赖注入 + public abstract void setupActivityComponent(AppComponent appComponent); + + /** + * 通过Class跳转界面 + **/ + public void startActivity(Class cls) { + startActivity(cls, null); + } + + /** + * 含有Bundle通过Class跳转界面 + **/ + public void startActivityForResult(Class cls, Bundle bundle, + int requestCode) { + Intent intent = new Intent(); + intent.setClass(this, cls); + if (bundle != null) { + intent.putExtras(bundle); + } + startActivityForResult(intent, requestCode); + } + + /** + * 含有Bundle通过Class跳转界面 + **/ + public void startActivity(Class cls, Bundle bundle) { + Intent intent = new Intent(); + intent.setClass(this, cls); + if (bundle != null) { + intent.putExtras(bundle); + } + startActivity(intent); + } + + /** + * 开启浮动加载进度条 + */ + public void startProgressDialog() { + LoadingDialog.showDialogForLoading(this); + } + + /** + * 开启浮动加载进度条 + * + * @param msg + */ + public void startProgressDialog(String msg) { + LoadingDialog.showDialogForLoading(this, msg, true); + } + + /** + * 停止浮动加载进度条 + */ + public void stopProgressDialog() { + LoadingDialog.cancelDialogForLoading(); + } + + /** + * 短暂显示Toast提示(来自String) + **/ + public void showShortToast(String text) { + ToastUitl.showShort(text); + } + + /** + * 短暂显示Toast提示(id) + **/ + public void showShortToast(int resId) { + ToastUitl.showShort(resId); + } + + /** + * 长时间显示Toast提示(来自res) + **/ + public void showLongToast(int resId) { + ToastUitl.showLong(resId); + } + + /** + * 长时间显示Toast提示(来自String) + **/ + public void showLongToast(String text) { + ToastUitl.showLong(text); + } + + /** + * 带图片的toast + * + * @param text + * @param res + */ + public void showToastWithImg(String text, int res) { + ToastUitl.showToastWithImg(text, res); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (mPresenter != null) + mPresenter.onDestroy(); + if (mRxManager != null) + mRxManager.clear(); + ButterKnife.unbind(this); + AppManager.getAppManager().finishActivity(this); + } +} diff --git a/dmvp/src/main/java/com/chen/common/base/BaseFragment.java b/dmvp/src/main/java/com/chen/common/base/BaseFragment.java new file mode 100644 index 0000000..6206b0f --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/base/BaseFragment.java @@ -0,0 +1,174 @@ +package com.chen.common.base; + +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.chen.common.R; +import com.chen.common.widget.LoadingDialog; +import com.chen.common.di.component.AppComponent; +import com.chen.common.rx.RxManager; +import com.chen.common.utils.CUtils; +import com.chen.common.utils.ToastUitl; + +import javax.inject.Inject; + +import butterknife.ButterKnife; + +/** + * des:基类fragment + * Created by xsf + * on 2016.07.12:38 + */ +public abstract class BaseFragment extends Fragment { + protected View rootView; + @Inject + public T mPresenter; + @Inject + public RxManager mRxManager; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + if (rootView == null) + rootView = inflater.inflate(getLayoutResource(), container, false); + ButterKnife.bind(this, rootView); + setupActivityComponent(CUtils.obtainAppComponentFromContext(getActivity())); // dagger2注入 + this.initData(savedInstanceState); + return rootView; + } + + //获取布局文件 + protected abstract int getLayoutResource(); + + //初始化view + public abstract void initData(Bundle savedInstanceState); + + //这里提供 AppComponent 对象给 BaseActivity 的子类, 用于 Dagger2 的依赖注入 + public abstract void setupActivityComponent(AppComponent appComponent); + + + /** + * 通过Class跳转界面 + **/ + public void startActivity(Class cls) { + startActivity(cls, null); + } + + /** + * 通过Class跳转界面 + **/ + public void startActivityForResult(Class cls, int requestCode) { + startActivityForResult(cls, null, requestCode); + } + + /** + * 含有Bundle通过Class跳转界面 + **/ + public void startActivityForResult(Class cls, Bundle bundle, + int requestCode) { + Intent intent = new Intent(); + intent.setClass(getActivity(), cls); + if (bundle != null) { + intent.putExtras(bundle); + } + startActivityForResult(intent, requestCode); + } + + /** + * 含有Bundle通过Class跳转界面 + **/ + public void startActivity(Class cls, Bundle bundle) { + Intent intent = new Intent(); + intent.setClass(getActivity(), cls); + if (bundle != null) { + intent.putExtras(bundle); + } + startActivity(intent); + } + + + /** + * 开启加载进度条 + */ + public void startProgressDialog() { + LoadingDialog.showDialogForLoading(getActivity()); + } + + /** + * 开启加载进度条 + * + * @param msg + */ + public void startProgressDialog(String msg) { + LoadingDialog.showDialogForLoading(getActivity(), msg, true); + } + + /** + * 停止加载进度条 + */ + public void stopProgressDialog() { + LoadingDialog.cancelDialogForLoading(); + } + + + /** + * 短暂显示Toast提示(来自String) + **/ + public void showShortToast(String text) { + ToastUitl.showShort(text); + } + + /** + * 短暂显示Toast提示(id) + **/ + public void showShortToast(int resId) { + ToastUitl.showShort(resId); + } + + /** + * 长时间显示Toast提示(来自res) + **/ + public void showLongToast(int resId) { + ToastUitl.showLong(resId); + } + + /** + * 长时间显示Toast提示(来自String) + **/ + public void showLongToast(String text) { + ToastUitl.showLong(text); + } + + + public void showToastWithImg(String text, int res) { + ToastUitl.showToastWithImg(text, res); + } + + /** + * 网络访问错误提醒 + */ + public void showNetErrorTip() { + ToastUitl.showToastWithImg(getText(R.string.net_error).toString(), R.drawable.ic_wifi_off); + } + + public void showNetErrorTip(String error) { + ToastUitl.showToastWithImg(error, R.drawable.ic_wifi_off); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + ButterKnife.unbind(this); + if (mPresenter != null) + mPresenter.onDestroy(); + if (mPresenter != null) + mRxManager.clear(); + } + + +} diff --git a/dmvp/src/main/java/com/chen/common/base/BaseModel.java b/dmvp/src/main/java/com/chen/common/base/BaseModel.java new file mode 100644 index 0000000..f10454d --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/base/BaseModel.java @@ -0,0 +1,9 @@ +package com.chen.common.base; + +/** + * des:baseModel + * Created by xsf + * on 2016.08.14:50 + */ +public interface BaseModel { +} diff --git a/dmvp/src/main/java/com/chen/common/base/BasePresenter.java b/dmvp/src/main/java/com/chen/common/base/BasePresenter.java new file mode 100644 index 0000000..d09ee6d --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/base/BasePresenter.java @@ -0,0 +1,39 @@ +package com.chen.common.base; + +import android.content.Context; + +import com.chen.common.rx.RxManager; +import com.chen.common.utils.Preconditions; + +/** + * des:基类presenter + * Created by xsf + * on 2016.07.11:55 + */ +public abstract class BasePresenter { + public Context mContext; + public E mModel; + public T mView; + public RxManager mRxManage = new RxManager(); + + /** + * 如果当前页面同时需要 Model 层和 View 层,则使用此构造函数(默认) + * + * @param model + * @param rootView + */ + public BasePresenter(E model, T rootView) { + Preconditions.checkNotNull(model, "%s cannot be null", BaseModel.class.getName()); + Preconditions.checkNotNull(rootView, "%s cannot be null", BaseView.class.getName()); + this.mModel = model; + this.mView = rootView; + onStart(); + } + + public void onStart() { + } + + public void onDestroy() { + mRxManage.clear(); + } +} diff --git a/dmvp/src/main/java/com/chen/common/base/BaseView.java b/dmvp/src/main/java/com/chen/common/base/BaseView.java new file mode 100644 index 0000000..f483b19 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/base/BaseView.java @@ -0,0 +1,11 @@ +package com.chen.common.base; + +/** + * des:baseview + * Created by xsf + * on 2016.07.11:53 + */ +public interface BaseView { + /*******内嵌加载*******/ + void showErrorTip(String msg); +} diff --git a/dmvp/src/main/java/com/chen/common/di/ActivityScope.java b/dmvp/src/main/java/com/chen/common/di/ActivityScope.java new file mode 100644 index 0000000..628ffdf --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/di/ActivityScope.java @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2015 Fernando Cejas Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Copyright 2017 JessYan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.chen.common.di; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Scope; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * A scoping annotation to permit objects whose lifetime should + * conform to the life of the activity to be memorized in the + * correct component. + */ +@Scope +@Documented +@Retention(RUNTIME) +public @interface ActivityScope {} diff --git a/dmvp/src/main/java/com/chen/common/di/FragmentScope.java b/dmvp/src/main/java/com/chen/common/di/FragmentScope.java new file mode 100644 index 0000000..a497ff4 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/di/FragmentScope.java @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2015 Fernando Cejas Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Copyright 2017 JessYan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.chen.common.di; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Scope; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * A scoping annotation to permit objects whose lifetime should + * conform to the life of the activity to be memorized in the + * correct component. + */ +@Scope +@Documented +@Retention(RUNTIME) +public @interface FragmentScope {} diff --git a/dmvp/src/main/java/com/chen/common/di/component/AppComponent.java b/dmvp/src/main/java/com/chen/common/di/component/AppComponent.java new file mode 100644 index 0000000..67fac54 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/di/component/AppComponent.java @@ -0,0 +1,25 @@ +package com.chen.common.di.component; + +import android.app.Application; + +import com.chen.common.rx.IRetrofitManager; +import com.chen.common.di.module.AppModule; +import com.chen.common.di.module.NetModule; + +import javax.inject.Singleton; + +import dagger.Component; + +/** + * @author :ChenYangYi + * @time :2018/4/2 + * @desc :拥有此接口的实现类即可调用对应的方法拿到 Dagger 提供的对应实例 + */ +@Singleton +@Component(modules = {AppModule.class, NetModule.class}) +public interface AppComponent { + Application application(); + + //用于管理网络请求层,以及数据缓存层 + IRetrofitManager repositoryManager(); +} diff --git a/dmvp/src/main/java/com/chen/common/di/module/AppModule.java b/dmvp/src/main/java/com/chen/common/di/module/AppModule.java new file mode 100644 index 0000000..d663353 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/di/module/AppModule.java @@ -0,0 +1,29 @@ +package com.chen.common.di.module; + +import android.app.Application; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +/** + * @author :ChenYangYi + * @time :2018/4/2 + * @desc : 提供一些框架必须的实例 + */ + +@Module +public class AppModule { + private Application application; + + public AppModule(Application application) { + this.application = application; + } + + @Singleton + @Provides + Application provideApplication() { + return application; + } +} diff --git a/dmvp/src/main/java/com/chen/common/di/module/NetModule.java b/dmvp/src/main/java/com/chen/common/di/module/NetModule.java new file mode 100644 index 0000000..7b97319 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/di/module/NetModule.java @@ -0,0 +1,89 @@ +package com.chen.common.di.module; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.chen.common.rx.IRetrofitManager; +import com.chen.common.rx.RetrofitManager; + +import java.util.concurrent.TimeUnit; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * @author :ChenYangYi + * @time :2018/4/2 + * @desc :提供一些三方库客户端实例 + */ + +@Module +public class NetModule { + /** + * 超时时间 + */ + private static final int TIME_OUT = 1000 * 20; + /** + * 域名 + */ + private String httpUrl; + + public NetModule(String httpUrl) { + this.httpUrl = httpUrl; + } + + @Provides + String provideHttpUrl() { + return this.httpUrl; + } + + @Singleton + @Provides + Retrofit provideRetrofit(OkHttpClient okHttpClient, Gson gson) { + return new Retrofit.Builder() + .client(okHttpClient) + .addConverterFactory(GsonConverterFactory.create(gson)) + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .baseUrl(httpUrl) + .build(); + } + + @Singleton + @Provides + Gson provideGson() { + return new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").serializeNulls().create(); + } + + @Singleton + @Provides + OkHttpClient provideOkhttpClient(Interceptor logInterceptor) { + return new OkHttpClient.Builder() + .readTimeout(TIME_OUT, TimeUnit.MILLISECONDS) + .connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS) + .addInterceptor(logInterceptor) + .build(); + } + + @Singleton + @Provides + Interceptor provideLogInterceptor() { + HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(); + logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + return logInterceptor; + } + + @Singleton + @Provides + public IRetrofitManager provideRepositoryManager(RetrofitManager repositoryManager) { + return repositoryManager; + } + + +} diff --git a/dmvp/src/main/java/com/chen/common/rx/IRetrofitManager.java b/dmvp/src/main/java/com/chen/common/rx/IRetrofitManager.java new file mode 100644 index 0000000..b5ba87d --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/rx/IRetrofitManager.java @@ -0,0 +1,18 @@ +package com.chen.common.rx; + +/** + * @author :ChenYangYi + * @time :2018/4/3 + * @desc : Retrofit管理,用于获取service接口实现类 + */ + +public interface IRetrofitManager { + /** + * 根据传入的 Class 获取对应的 Retrofit service + * + * @param service + * @param + * @return + */ + T obtainRetrofitService(Class service); +} diff --git a/dmvp/src/main/java/com/chen/common/rx/RetrofitManager.java b/dmvp/src/main/java/com/chen/common/rx/RetrofitManager.java new file mode 100644 index 0000000..1f435b7 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/rx/RetrofitManager.java @@ -0,0 +1,48 @@ +package com.chen.common.rx; + +import android.app.Application; + +import java.util.HashMap; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import dagger.Lazy; +import retrofit2.Retrofit; + +/** + * @author :ChenYangYi + * @time :2018/4/3 + * @desc : 根据传入的 Class 获取对应的 Retrofit service,单例 + */ +@Singleton +public class RetrofitManager implements IRetrofitManager { + private Lazy mRetrofit; // Lazy(懒加载) + private Application mApplication; + private HashMap mRetrofitServiceCache; // 保存service,防止重复创建 + + + @Inject + public RetrofitManager(Lazy mRetrofit, Application mApplication) { + this.mRetrofit = mRetrofit; + this.mApplication = mApplication; + mRetrofitServiceCache = new HashMap<>(); + } + + /** + * 根据传入的 Class 获取对应的 Retrofit service + * + * @param service + * @param + * @return + */ + @Override + public T obtainRetrofitService(Class service) { + if (mRetrofitServiceCache.containsKey(service.getName())) { // 如果map集合中存在改字节码对应的service对象,直接取出 + return (T) mRetrofitServiceCache.get(service.getName()); + } else { // map中不存在 + mRetrofitServiceCache.put(service.getName(), mRetrofit.get().create(service)); + return (T) mRetrofitServiceCache.get(service.getName()); + } + } +} diff --git a/dmvp/src/main/java/com/chen/common/rx/RxBus.java b/dmvp/src/main/java/com/chen/common/rx/RxBus.java new file mode 100644 index 0000000..b4cd7c4 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/rx/RxBus.java @@ -0,0 +1,127 @@ +package com.chen.common.rx; + +import android.support.annotation.NonNull; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; +import rx.subjects.PublishSubject; +import rx.subjects.Subject; + +/** + * 用RxJava实现的EventBus + * Created by xsf + * on 2016.08.14:50 + */ +public class RxBus { + private static RxBus instance; + + public static synchronized RxBus getInstance() { + if (null == instance) { + instance = new RxBus(); + } + return instance; + } + + private RxBus() { + } + + @SuppressWarnings("rawtypes") + private ConcurrentHashMap> subjectMapper = new ConcurrentHashMap>(); + + /** + * 订阅事件源 + * + * @param mObservable + * @param mAction1 + * @return + */ + public RxBus OnEvent(Observable mObservable, Action1 mAction1) { + mObservable.observeOn(AndroidSchedulers.mainThread()).subscribe(mAction1, new Action1() { + @Override + public void call(Throwable throwable) { + throwable.printStackTrace(); + } + }); + return getInstance(); + } + + /** + * 注册事件源 + * + * @param tag + * @return + */ + @SuppressWarnings({"rawtypes"}) + public Observable register(@NonNull Object tag) { + List subjectList = subjectMapper.get(tag); + if (null == subjectList) { + subjectList = new ArrayList(); + subjectMapper.put(tag, subjectList); + } + Subject subject; + subjectList.add(subject = PublishSubject.create()); + return subject; + } + + @SuppressWarnings("rawtypes") + public void unregister(@NonNull Object tag) { + List subjects = subjectMapper.get(tag); + if (null != subjects) { + subjectMapper.remove(tag); + } + } + + /** + * 取消监听 + * + * @param tag + * @param observable + * @return + */ + @SuppressWarnings("rawtypes") + public RxBus unregister(@NonNull Object tag, + @NonNull Observable observable) { + if (null == observable) + return getInstance(); + List subjects = subjectMapper.get(tag); + if (null != subjects) { + subjects.remove((Subject) observable); + if (isEmpty(subjects)) { + subjectMapper.remove(tag); + } + } + return getInstance(); + } + + public void post(@NonNull Object content) { + post(content.getClass().getName(), content); + } + + /** + * 触发事件 + * + * @param content + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public void post(@NonNull Object tag, @NonNull Object content) { + List subjectList = subjectMapper.get(tag); + if (!isEmpty(subjectList)) { + for (Subject subject : subjectList) { + subject.onNext(content); + } + } + } + + @SuppressWarnings("rawtypes") + public static boolean isEmpty(Collection collection) { + return null == collection || collection.isEmpty(); + } + +} diff --git a/dmvp/src/main/java/com/chen/common/rx/RxManager.java b/dmvp/src/main/java/com/chen/common/rx/RxManager.java new file mode 100644 index 0000000..96d58c9 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/rx/RxManager.java @@ -0,0 +1,70 @@ +package com.chen.common.rx; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import rx.Observable; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; +import rx.subscriptions.CompositeSubscription; + +/** + * 用于管理单个presenter的RxBus的事件和Rxjava相关代码的生命周期处理 + * Created by xsf + * on 2016.08.14:50 + */ +public class RxManager { + + @Inject + public RxManager() { + } + + public RxBus mRxBus = RxBus.getInstance(); + //管理rxbus订阅 + private Map> mObservables = new HashMap<>(); + /*管理Observables 和 Subscribers订阅*/ + private CompositeSubscription mCompositeSubscription = new CompositeSubscription(); + + /** + * RxBus注入监听 + * @param eventName + * @param action1 + */ + public void on(String eventName, Action1 action1) { + Observable mObservable = mRxBus.register(eventName); + mObservables.put(eventName, mObservable); + /*订阅管理*/ + mCompositeSubscription.add(mObservable.observeOn(AndroidSchedulers.mainThread()) + .subscribe(action1, new Action1() { + @Override + public void call(Throwable throwable) { + throwable.printStackTrace(); + } + })); + } + + /** + * 单纯的Observables 和 Subscribers管理 + * @param m + */ + public void add(Subscription m) { + /*订阅管理*/ + mCompositeSubscription.add(m); + } + /** + * 单个presenter生命周期结束,取消订阅和所有rxbus观察 + */ + public void clear() { + mCompositeSubscription.unsubscribe();// 取消所有订阅 + for (Map.Entry> entry : mObservables.entrySet()) { + mRxBus.unregister(entry.getKey(), entry.getValue());// 移除rxbus观察 + } + } + //发送rxbus + public void post(Object tag, Object content) { + mRxBus.post(tag, content); + } +} diff --git a/dmvp/src/main/java/com/chen/common/rx/RxSchedulers.java b/dmvp/src/main/java/com/chen/common/rx/RxSchedulers.java new file mode 100644 index 0000000..feb2508 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/rx/RxSchedulers.java @@ -0,0 +1,22 @@ +package com.chen.common.rx; + +import rx.Observable; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +/** + * RxJava调度管理 + * Created by xsf + * on 2016.08.14:50 + */ +public class RxSchedulers { + public static Observable.Transformer io_main() { + return new Observable.Transformer() { + @Override + public Observable call(Observable observable) { + return observable.subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + }; + } +} diff --git a/dmvp/src/main/java/com/chen/common/rx/RxSubscriber.java b/dmvp/src/main/java/com/chen/common/rx/RxSubscriber.java new file mode 100644 index 0000000..d2890f3 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/rx/RxSubscriber.java @@ -0,0 +1,111 @@ +package com.chen.common.rx; + +import android.app.Activity; +import android.content.Context; + +import com.chen.common.R; +import com.chen.common.app.BaseApplication; +import com.chen.common.utils.NetWorkUtils; +import com.chen.common.widget.LoadingDialog; + +import rx.Subscriber; + +/** + * des:订阅封装 + * Created by xsf + * on 2016.09.10:16 + */ + +/********************使用例子********************/ +/*_apiService.login(mobile, verifyCode) + .//省略 + .subscribe(new RxSubscriber(mContext,false) { +@Override +public void _onNext(User user) { + // 处理user + } + +@Override +public void _onError(String msg) { + ToastUtil.showShort(mActivity, msg); + });*/ +public abstract class RxSubscriber extends Subscriber { + + private Context mContext; + private String msg; + private boolean showDialog = true; + + /** + * 是否显示浮动dialog + */ + public void showDialog() { + this.showDialog = true; + } + + public void hideDialog() { + this.showDialog = true; + } + + public RxSubscriber(Context context, String msg, boolean showDialog) { + this.mContext = context; + this.msg = msg; + this.showDialog = showDialog; + } + + public RxSubscriber(Context context) { + this(context, BaseApplication.getAppContext().getString(R.string.loading), true); + } + + public RxSubscriber(Context context, boolean showDialog) { + this(context, BaseApplication.getAppContext().getString(R.string.loading), showDialog); + } + + @Override + public void onCompleted() { + if (showDialog) + LoadingDialog.cancelDialogForLoading(); + } + + @Override + public void onStart() { + super.onStart(); + if (showDialog) { + try { + LoadingDialog.showDialogForLoading((Activity) mContext, msg, true); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + + @Override + public void onNext(T t) { + _onNext(t); + } + + @Override + public void onError(Throwable e) { + if (showDialog) + LoadingDialog.cancelDialogForLoading(); + e.printStackTrace(); + //网络 + if (!NetWorkUtils.isNetConnected(BaseApplication.getAppContext())) { + _onError(BaseApplication.getAppContext().getString(R.string.no_net)); + } + //服务器 + else if (e instanceof ServerException) { // 得到自定义Error,取得失败信息 + ServerException err = (ServerException) e; + _onError(err.getMessage()); + } + //其它 + else { + _onError(BaseApplication.getAppContext().getString(R.string.net_error)); + } + } + + protected abstract void _onNext(T t); + + protected abstract void _onError(String message); + +} diff --git a/dmvp/src/main/java/com/chen/common/rx/ServerException.java b/dmvp/src/main/java/com/chen/common/rx/ServerException.java new file mode 100644 index 0000000..077a746 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/rx/ServerException.java @@ -0,0 +1,14 @@ +package com.chen.common.rx; + +/** + * des:服务器请求异常 + * Created by xsf + * on 2016.09.10:16 + */ +public class ServerException extends Exception{ + + public ServerException(String msg){ + super(msg); + } + +} diff --git a/dmvp/src/main/java/com/chen/common/utils/CUtils.java b/dmvp/src/main/java/com/chen/common/utils/CUtils.java new file mode 100644 index 0000000..078848b --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/utils/CUtils.java @@ -0,0 +1,22 @@ +package com.chen.common.utils; + +import android.content.Context; + +import com.chen.common.app.App; +import com.chen.common.di.component.AppComponent; + + +/** + * @author :ChenYangYi + * @time :2018/4/2 + * @desc :常用的方法工具类 + */ + +public class CUtils { + + public static AppComponent obtainAppComponentFromContext(Context context) { + Preconditions.checkNotNull(context, "%s cannot be null", Context.class.getName()); + Preconditions.checkState(context.getApplicationContext() instanceof App, "Application does not implements App"); + return ((App) context.getApplicationContext()).getAppComponent(); + } +} diff --git a/dmvp/src/main/java/com/chen/common/utils/DisplayUtil.java b/dmvp/src/main/java/com/chen/common/utils/DisplayUtil.java new file mode 100644 index 0000000..b86c95e --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/utils/DisplayUtil.java @@ -0,0 +1,261 @@ +package com.chen.common.utils; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.util.DisplayMetrics; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.view.WindowManager; +import android.widget.LinearLayout; + +import com.chen.common.app.BaseApplication; + + +/** + * 屏幕相关的辅助类 + */ +public class DisplayUtil { + private DisplayUtil() { + /* cannot be instantiated */ + throw new UnsupportedOperationException("cannot be instantiated"); + } + + + /** + * 将px值转换为dip或dp值,保证尺寸大小不变 + * + * @param pxValue + * (DisplayMetrics类中属性density) + * @return + */ + public static int px2dip(float pxValue) { + final float scale = BaseApplication.getAppContext().getResources().getDisplayMetrics().density; + return (int) (pxValue / scale + 0.5f); + } + + /** + * 将dip或dp值转换为px值,保证尺寸大小不变 + * + * @param dipValue + * (DisplayMetrics类中属性density) + * @return + */ + public static int dip2px( float dipValue) { + final float scale = BaseApplication.getAppContext().getResources().getDisplayMetrics().density; + return (int) (dipValue * scale + 0.5f); + } + + /** + * 将px值转换为sp值,保证文字大小不变 + * + * @param pxValue + * (DisplayMetrics类中属性scaledDensity) + * @return + */ + public static int px2sp(float pxValue) { + final float fontScale = BaseApplication.getAppContext().getResources().getDisplayMetrics().scaledDensity; + return (int) (pxValue / fontScale + 0.5f); + } + + /** + * 将sp值转换为px值,保证文字大小不变 + * + * @param spValue + * (DisplayMetrics类中属性scaledDensity) + * @return + */ + public static int sp2px(float spValue) { + final float fontScale = BaseApplication.getAppContext().getResources().getDisplayMetrics().scaledDensity; + return (int) (spValue * fontScale + 0.5f); + } + + /** + * 直接获取控件的宽、高 + * @param view + * @return int[] + */ + public static int[] getWidgetWH(final View view){ + ViewTreeObserver vto2 = view.getViewTreeObserver(); + vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + view.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } + }); + return new int[]{view.getWidth(),view.getHeight()}; + } + + /** + * 直接获取控件的宽、高 + * @param view + * @return int[] + */ + public static int getViewHeight(final View view){ + ViewTreeObserver vto2 = view.getViewTreeObserver(); + vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + view.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } + }); + return view.getHeight(); + } + + /** + * 直接获取控件的宽、高 + * @param view + * @return int[] + */ + public static int getViewWidth(final View view){ + ViewTreeObserver vto2 = view.getViewTreeObserver(); + vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + view.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } + }); + return view.getWidth(); + } + + /** + * 获得屏幕宽度 + * + * @param context + * @return + */ + public static int getScreenWidth(Context context) { + WindowManager wm = (WindowManager) context + .getSystemService(Context.WINDOW_SERVICE); + DisplayMetrics outMetrics = new DisplayMetrics(); + wm.getDefaultDisplay().getMetrics(outMetrics); + return outMetrics.widthPixels; + } + + /** + * 获得屏幕高度 + * + * @param context + * @return + */ + public static int getScreenHeight(Context context) { + WindowManager wm = (WindowManager) context + .getSystemService(Context.WINDOW_SERVICE); + DisplayMetrics outMetrics = new DisplayMetrics(); + wm.getDefaultDisplay().getMetrics(outMetrics); + return outMetrics.heightPixels; + } + + /** + * 获得状态栏的高度 + * 注意:该方法只能在Activity类中使用,在测试模式下失败 + * @param context + * @return + */ + public static int getStatusBarHeight(Context context) { + int statusBarHeight = -1; + try { + Class clazz = Class.forName("com.android.internal.R$dimen"); + Object object = clazz.newInstance(); + int height = Integer.parseInt(clazz.getField("status_bar_height") + .get(object).toString()); + statusBarHeight = context.getResources().getDimensionPixelSize(height); + } catch (Exception e) { + e.printStackTrace(); + } + return statusBarHeight; + } + + /** + * 获取控件的宽 + * @param view + * @return + */ + public static int getWidgetWidth(View view){ + int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + view.measure(w, h);//先度量 + int width = view.getMeasuredWidth(); + return width; + } + /** + * 获取控件的高 + * @param view + * @return + */ + public static int getWidgetHeight(View view){ + int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + view.measure(w, h);//先度量 + int height = view.getMeasuredHeight(); + return height; + } + /** + * 设置控件宽 + * @param view + * @param width + */ + public static void setWidgetWidth(View view, int width){ + LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); + params.width = width; + view.setLayoutParams(params); + } + /** + * 设置控件高 + * @param view + * @param height + */ + public static void setWidgetHeight(View view, int height){ + LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); + params.height = height; + view.setLayoutParams(params); + } + + + //---------------------------------------------- + + /** + * 获取当前屏幕截图,包含状态栏(这个方法没测试通过) + * + * @param activity + * @return Bitmap + */ + public static Bitmap snapShotWithStatusBar(Activity activity) { + View view = activity.getWindow().getDecorView(); + view.setDrawingCacheEnabled(true); + view.buildDrawingCache(); + Bitmap bmp = view.getDrawingCache(); + int width = getScreenWidth(activity); + int height = getScreenHeight(activity); + Bitmap bp = null; + bp = Bitmap.createBitmap(bmp, 0, 0, width, height); + view.destroyDrawingCache(); + return bp; + } + + /** + * 获取当前屏幕截图,不包含状态栏(这个方法没测试通过) + * + * @param activity + * @return Bitmap + */ + public static Bitmap snapShotWithoutStatusBar(Activity activity) { + View view = activity.getWindow().getDecorView(); + view.setDrawingCacheEnabled(true); + view.buildDrawingCache(); + Bitmap bmp = view.getDrawingCache(); + Rect frame = new Rect(); + activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); + int statusBarHeight = frame.top; + + int width = getScreenWidth(activity); + int height = getScreenHeight(activity); + Bitmap bp = null; + bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height + - statusBarHeight); + view.destroyDrawingCache(); + return bp; + } +} diff --git a/dmvp/src/main/java/com/chen/common/utils/NetWorkUtils.java b/dmvp/src/main/java/com/chen/common/utils/NetWorkUtils.java new file mode 100644 index 0000000..26d80a0 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/utils/NetWorkUtils.java @@ -0,0 +1,70 @@ +package com.chen.common.utils; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * des:网络管理工具 + * Created by xsf + * on 2016.04.10:34 + */ +public class NetWorkUtils { + + /** + * 检查网络是否可用 + * + * @param paramContext + * @return + */ + public static boolean isNetConnected(Context paramContext) { + boolean i = false; + NetworkInfo localNetworkInfo = ((ConnectivityManager) paramContext + .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo(); + if ((localNetworkInfo != null) && (localNetworkInfo.isAvailable())) + return true; + return false; + } + /** + * 检测wifi是否连接 + */ + public static boolean isWifiConnected(Context context) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm != null) { + NetworkInfo networkInfo = cm.getActiveNetworkInfo(); + if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { + return true; + } + } + return false; + } + + /** + * 检测3G是否连接 + */ + public static boolean is3gConnected(Context context) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm != null) { + NetworkInfo networkInfo = cm.getActiveNetworkInfo(); + if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) { + return true; + } + } + return false; + } + + /** + * 判断网址是否有效 + */ + public static boolean isLinkAvailable(String link) { + Pattern pattern = Pattern.compile("^(http://|https://)?((?:[A-Za-z0-9]+-[A-Za-z0-9]+|[A-Za-z0-9]+)\\.)+([A-Za-z]+)[/\\?\\:]?.*$", Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(link); + if (matcher.matches()) { + return true; + } + return false; + } +} diff --git a/dmvp/src/main/java/com/chen/common/utils/Preconditions.java b/dmvp/src/main/java/com/chen/common/utils/Preconditions.java new file mode 100644 index 0000000..26e58b7 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/utils/Preconditions.java @@ -0,0 +1,179 @@ +/** + * Copyright 2017 JessYan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.chen.common.utils; + +import android.support.annotation.Nullable; + +/** + * ================================================ + * Created by JessYan on 26/09/2016 13:59 + * Contact me + * Follow me + * ================================================ + */ +public final class Preconditions { + + private Preconditions() { + throw new IllegalStateException("you can't instantiate me!"); + } + + public static void checkArgument(boolean expression) { + if(!expression) { + throw new IllegalArgumentException(); + } + } + + public static void checkArgument(boolean expression, @Nullable Object errorMessage) { + if(!expression) { + throw new IllegalArgumentException(String.valueOf(errorMessage)); + } + } + + public static void checkArgument(boolean expression, @Nullable String errorMessageTemplate, @Nullable Object... errorMessageArgs) { + if(!expression) { + throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs)); + } + } + + public static void checkState(boolean expression) { + if(!expression) { + throw new IllegalStateException(); + } + } + + public static void checkState(boolean expression, @Nullable Object errorMessage) { + if(!expression) { + throw new IllegalStateException(String.valueOf(errorMessage)); + } + } + + public static void checkState(boolean expression, @Nullable String errorMessageTemplate, @Nullable Object... errorMessageArgs) { + if(!expression) { + throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs)); + } + } + + public static T checkNotNull(T reference) { + if(reference == null) { + throw new NullPointerException(); + } else { + return reference; + } + } + + public static T checkNotNull(T reference, @Nullable Object errorMessage) { + if(reference == null) { + throw new NullPointerException(String.valueOf(errorMessage)); + } else { + return reference; + } + } + + public static T checkNotNull(T reference, @Nullable String errorMessageTemplate, @Nullable Object... errorMessageArgs) { + if(reference == null) { + throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs)); + } else { + return reference; + } + } + + public static int checkElementIndex(int index, int size) { + return checkElementIndex(index, size, "index"); + } + + public static int checkElementIndex(int index, int size, @Nullable String desc) { + if(index >= 0 && index < size) { + return index; + } else { + throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); + } + } + + private static String badElementIndex(int index, int size, String desc) { + if(index < 0) { + return format("%s (%s) must not be negative", new Object[]{desc, Integer.valueOf(index)}); + } else if(size < 0) { + throw new IllegalArgumentException((new StringBuilder(26)).append("negative size: ").append(size).toString()); + } else { + return format("%s (%s) must be less than size (%s)", new Object[]{desc, Integer.valueOf(index), Integer.valueOf(size)}); + } + } + + public static int checkPositionIndex(int index, int size) { + return checkPositionIndex(index, size, "index"); + } + + public static int checkPositionIndex(int index, int size, @Nullable String desc) { + if(index >= 0 && index <= size) { + return index; + } else { + throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); + } + } + + private static String badPositionIndex(int index, int size, String desc) { + if(index < 0) { + return format("%s (%s) must not be negative", new Object[]{desc, Integer.valueOf(index)}); + } else if(size < 0) { + throw new IllegalArgumentException((new StringBuilder(26)).append("negative size: ").append(size).toString()); + } else { + return format("%s (%s) must not be greater than size (%s)", new Object[]{desc, Integer.valueOf(index), Integer.valueOf(size)}); + } + } + + public static void checkPositionIndexes(int start, int end, int size) { + if(start < 0 || end < start || end > size) { + throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size)); + } + } + + private static String badPositionIndexes(int start, int end, int size) { + return start >= 0 && start <= size?(end >= 0 && end <= size?format("end index (%s) must not be less than start index (%s)", new Object[]{Integer.valueOf(end), Integer.valueOf(start)}):badPositionIndex(end, size, "end index")):badPositionIndex(start, size, "start index"); + } + + static String format(String template, @Nullable Object... args) { + template = String.valueOf(template); + StringBuilder builder = new StringBuilder(template.length() + 16 * args.length); + int templateStart = 0; + + int i; + int placeholderStart; + for(i = 0; i < args.length; templateStart = placeholderStart + 2) { + placeholderStart = template.indexOf("%s", templateStart); + if(placeholderStart == -1) { + break; + } + + builder.append(template.substring(templateStart, placeholderStart)); + builder.append(args[i++]); + } + + builder.append(template.substring(templateStart)); + if(i < args.length) { + builder.append(" ["); + builder.append(args[i++]); + + while(i < args.length) { + builder.append(", "); + builder.append(args[i++]); + } + + builder.append(']'); + } + + return builder.toString(); + } +} diff --git a/dmvp/src/main/java/com/chen/common/utils/TUtil.java b/dmvp/src/main/java/com/chen/common/utils/TUtil.java new file mode 100644 index 0000000..5cb2dc0 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/utils/TUtil.java @@ -0,0 +1,32 @@ +package com.chen.common.utils; + +import java.lang.reflect.ParameterizedType; + +/** + * 类转换初始化 + */ +public class TUtil { + public static T getT(Object o, int i) { + try { + return ((Class) ((ParameterizedType) (o.getClass() + .getGenericSuperclass())).getActualTypeArguments()[i]) + .newInstance(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (ClassCastException e) { + e.printStackTrace(); + } + return null; + } + + public static Class forName(String className) { + try { + return Class.forName(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/dmvp/src/main/java/com/chen/common/utils/ToastUitl.java b/dmvp/src/main/java/com/chen/common/utils/ToastUitl.java new file mode 100644 index 0000000..9bbf29b --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/utils/ToastUitl.java @@ -0,0 +1,121 @@ +package com.chen.common.utils; + +import android.content.Context; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.chen.common.app.BaseApplication; +import com.chen.common.R; + + +/** + * Toast统一管理类 + */ +public class ToastUitl { + + + private static Toast toast; + private static Toast toast2; + + private static Toast initToast(CharSequence message, int duration) { + if (toast == null) { + toast = Toast.makeText(BaseApplication.getAppContext(), message, duration); + } else { + toast.setText(message); + toast.setDuration(duration); + } + return toast; + } + + /** + * 短时间显示Toast + * + * @param message + */ + public static void showShort(CharSequence message) { + initToast(message, Toast.LENGTH_SHORT).show(); + } + + + /** + * 短时间显示Toast + * + * @param strResId + */ + public static void showShort(int strResId) { +// Toast.makeText(context, strResId, Toast.LENGTH_SHORT).show(); + initToast(BaseApplication.getAppContext().getResources().getText(strResId), Toast.LENGTH_SHORT).show(); + } + + /** + * 长时间显示Toast + * + * @param message + */ + public static void showLong(CharSequence message) { + initToast(message, Toast.LENGTH_LONG).show(); + } + + /** + * 长时间显示Toast + * + * @param strResId + */ + public static void showLong(int strResId) { + initToast(BaseApplication.getAppContext().getResources().getText(strResId), Toast.LENGTH_LONG).show(); + } + + /** + * 自定义显示Toast时间 + * + * @param message + * @param duration + */ + public static void show(CharSequence message, int duration) { + initToast(message, duration).show(); + } + + /** + * 自定义显示Toast时间 + * + * @param context + * @param strResId + * @param duration + */ + public static void show(Context context, int strResId, int duration) { + initToast(context.getResources().getText(strResId), duration).show(); + } + + /** + * 显示有image的toast + * + * @param tvStr + * @param imageResource + * @return + */ + public static Toast showToastWithImg(final String tvStr, final int imageResource) { + if (toast2 == null) { + toast2 = new Toast(BaseApplication.getAppContext()); + } + View view = LayoutInflater.from(BaseApplication.getAppContext()).inflate(R.layout.toast_custom, null); + TextView tv = (TextView) view.findViewById(R.id.toast_custom_tv); + tv.setText(TextUtils.isEmpty(tvStr) ? "" : tvStr); + ImageView iv = (ImageView) view.findViewById(R.id.toast_custom_iv); + if (imageResource > 0) { + iv.setVisibility(View.VISIBLE); + iv.setImageResource(imageResource); + } else { + iv.setVisibility(View.GONE); + } + toast2.setView(view); + toast2.setGravity(Gravity.CENTER, 0, 0); + toast2.show(); + return toast2; + + } +} diff --git a/dmvp/src/main/java/com/chen/common/widget/LoadingDialog.java b/dmvp/src/main/java/com/chen/common/widget/LoadingDialog.java new file mode 100644 index 0000000..4d65da8 --- /dev/null +++ b/dmvp/src/main/java/com/chen/common/widget/LoadingDialog.java @@ -0,0 +1,61 @@ +package com.chen.common.widget; + +import android.app.Activity; +import android.app.Dialog; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.chen.common.R; + + +/** + * description:弹窗浮动加载进度条 + * Created by xsf + * on 2016.07.17:22 + */ +public class LoadingDialog { + /** 加载数据对话框 */ + private static Dialog mLoadingDialog; + /** + * 显示加载对话框 + * @param context 上下文 + * @param msg 对话框显示内容 + * @param cancelable 对话框是否可以取消 + */ + public static Dialog showDialogForLoading(Activity context, String msg, boolean cancelable) { + View view = LayoutInflater.from(context).inflate(R.layout.dialog_loading, null); + TextView loadingText = (TextView)view.findViewById(R.id.id_tv_loading_dialog_text); + loadingText.setText(msg); + + mLoadingDialog = new Dialog(context, R.style.CustomProgressDialog); + mLoadingDialog.setCancelable(cancelable); + mLoadingDialog.setCanceledOnTouchOutside(false); + mLoadingDialog.setContentView(view, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); + mLoadingDialog.show(); + return mLoadingDialog; + } + + public static Dialog showDialogForLoading(Activity context) { + View view = LayoutInflater.from(context).inflate(R.layout.dialog_loading, null); + TextView loadingText = (TextView)view.findViewById(R.id.id_tv_loading_dialog_text); + loadingText.setText("加载中..."); + + mLoadingDialog = new Dialog(context, R.style.CustomProgressDialog); + mLoadingDialog.setCancelable(true); + mLoadingDialog.setCanceledOnTouchOutside(false); + mLoadingDialog.setContentView(view, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); + mLoadingDialog.show(); + return mLoadingDialog; + } + + /** + * 关闭加载对话框 + */ + public static void cancelDialogForLoading() { + if(mLoadingDialog != null) { + mLoadingDialog.cancel(); + } + } +} diff --git a/dmvp/src/main/res/anim/act_fade_in_center.xml b/dmvp/src/main/res/anim/act_fade_in_center.xml new file mode 100644 index 0000000..042999a --- /dev/null +++ b/dmvp/src/main/res/anim/act_fade_in_center.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/anim/act_fade_out_center.xml b/dmvp/src/main/res/anim/act_fade_out_center.xml new file mode 100644 index 0000000..cbf96d7 --- /dev/null +++ b/dmvp/src/main/res/anim/act_fade_out_center.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/anim/fade_in.xml b/dmvp/src/main/res/anim/fade_in.xml new file mode 100644 index 0000000..8452da4 --- /dev/null +++ b/dmvp/src/main/res/anim/fade_in.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/dmvp/src/main/res/anim/fade_out.xml b/dmvp/src/main/res/anim/fade_out.xml new file mode 100644 index 0000000..8861e8f --- /dev/null +++ b/dmvp/src/main/res/anim/fade_out.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/dmvp/src/main/res/drawable-xhdpi/back1.png b/dmvp/src/main/res/drawable-xhdpi/back1.png new file mode 100644 index 0000000..b7aea82 Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/back1.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/ic_empty_picture.png b/dmvp/src/main/res/drawable-xhdpi/ic_empty_picture.png new file mode 100644 index 0000000..47b7c92 Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/ic_empty_picture.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/ic_image_loading.png b/dmvp/src/main/res/drawable-xhdpi/ic_image_loading.png new file mode 100644 index 0000000..5097dff Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/ic_image_loading.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/ic_success.png b/dmvp/src/main/res/drawable-xhdpi/ic_success.png new file mode 100644 index 0000000..a254afd Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/ic_success.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/ic_warm.png b/dmvp/src/main/res/drawable-xhdpi/ic_warm.png new file mode 100644 index 0000000..d2ba6c7 Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/ic_warm.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/ic_wifi_off.png b/dmvp/src/main/res/drawable-xhdpi/ic_wifi_off.png new file mode 100644 index 0000000..2cdc8b8 Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/ic_wifi_off.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/ic_wrong.png b/dmvp/src/main/res/drawable-xhdpi/ic_wrong.png new file mode 100644 index 0000000..828eb4b Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/ic_wrong.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/loading_progress.png b/dmvp/src/main/res/drawable-xhdpi/loading_progress.png new file mode 100644 index 0000000..d705934 Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/loading_progress.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/no_content_tip.png b/dmvp/src/main/res/drawable-xhdpi/no_content_tip.png new file mode 100644 index 0000000..565b63c Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/no_content_tip.png differ diff --git a/dmvp/src/main/res/drawable-xhdpi/toux2.png b/dmvp/src/main/res/drawable-xhdpi/toux2.png new file mode 100644 index 0000000..576425a Binary files /dev/null and b/dmvp/src/main/res/drawable-xhdpi/toux2.png differ diff --git a/dmvp/src/main/res/drawable/circle_drawable.xml b/dmvp/src/main/res/drawable/circle_drawable.xml new file mode 100644 index 0000000..7b84f98 --- /dev/null +++ b/dmvp/src/main/res/drawable/circle_drawable.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/drawable/circle_drawable_pressed.xml b/dmvp/src/main/res/drawable/circle_drawable_pressed.xml new file mode 100644 index 0000000..3c0231f --- /dev/null +++ b/dmvp/src/main/res/drawable/circle_drawable_pressed.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/drawable/dot_selector.xml b/dmvp/src/main/res/drawable/dot_selector.xml new file mode 100644 index 0000000..57f74e1 --- /dev/null +++ b/dmvp/src/main/res/drawable/dot_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/drawable/loading_dialog_progressbar.xml b/dmvp/src/main/res/drawable/loading_dialog_progressbar.xml new file mode 100644 index 0000000..21100f4 --- /dev/null +++ b/dmvp/src/main/res/drawable/loading_dialog_progressbar.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/dmvp/src/main/res/drawable/selector_gray.xml b/dmvp/src/main/res/drawable/selector_gray.xml new file mode 100644 index 0000000..371a1c7 --- /dev/null +++ b/dmvp/src/main/res/drawable/selector_gray.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/drawable/selector_guide_bg.xml b/dmvp/src/main/res/drawable/selector_guide_bg.xml new file mode 100644 index 0000000..375c0fa --- /dev/null +++ b/dmvp/src/main/res/drawable/selector_guide_bg.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/drawable/shape_loading_dialog.xml b/dmvp/src/main/res/drawable/shape_loading_dialog.xml new file mode 100644 index 0000000..5943c9e --- /dev/null +++ b/dmvp/src/main/res/drawable/shape_loading_dialog.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/dmvp/src/main/res/drawable/tv_rounded_corners.xml b/dmvp/src/main/res/drawable/tv_rounded_corners.xml new file mode 100644 index 0000000..0fd8da2 --- /dev/null +++ b/dmvp/src/main/res/drawable/tv_rounded_corners.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/layout/dialog_loading.xml b/dmvp/src/main/res/layout/dialog_loading.xml new file mode 100644 index 0000000..4dada7a --- /dev/null +++ b/dmvp/src/main/res/layout/dialog_loading.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/layout/toast_custom.xml b/dmvp/src/main/res/layout/toast_custom.xml new file mode 100644 index 0000000..14c8294 --- /dev/null +++ b/dmvp/src/main/res/layout/toast_custom.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/values/attrs.xml b/dmvp/src/main/res/values/attrs.xml new file mode 100644 index 0000000..20e07ea --- /dev/null +++ b/dmvp/src/main/res/values/attrs.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dmvp/src/main/res/values/colors.xml b/dmvp/src/main/res/values/colors.xml new file mode 100644 index 0000000..300d5a6 --- /dev/null +++ b/dmvp/src/main/res/values/colors.xml @@ -0,0 +1,87 @@ + + + #1296DB + #FA7C20 + #FA7C20 + + #FFFFFFFF + #FF000000 + #c9000000 + #8A9599 + + #3F3F3F + #FFbbbbbb + #8A9599 + #8A9599 + + #FA7C20 + #FA8C20 + #FF000000 + #FF0288ce + #FFbbbbbb + #FF000000 + #FFFFFFFF + #FFFF0000 + #FF00FF00 + #99FFFFFF + #FFF0F0F0 + #c9000000 + #00000000 + #929292 + #33CC99 + #929292 + #f2f2f2 + #FFB3B3B3 + #FFEEEEEE + #808080 + #33ffffff + #FFcccccc + #5CA3E5 + #3598db + #3493d4 + #ffffff + #99d4d4d4 + + + #0DFFFFFF + #1AFFFFFF + #26FFFFFF + #33FFFFFF + #40FFFFFF + #4DFFFFFF + #59FFFFFF + #66FFFFFF + #73FFFFFF + #80FFFFFF + #8CFFFFFF + #99FFFFFF + #A6FFFFFF + #B3FFFFFF + #BFFFFFFF + #CCFFFFFF + #D9FFFFFF + #E6FFFFFF + #F2FFFFFF + + #0D000000 + #1A000000 + #26000000 + #33000000 + #40000000 + #4D000000 + #59000000 + #66000000 + #73000000 + #80000000 + #8C000000 + #99000000 + #A6000000 + #B3000000 + #BF000000 + #CC000000 + #D9000000 + #E6000000 + #F2000000 + + + \ No newline at end of file diff --git a/dmvp/src/main/res/values/dimens.xml b/dmvp/src/main/res/values/dimens.xml new file mode 100644 index 0000000..e6bf4cb --- /dev/null +++ b/dmvp/src/main/res/values/dimens.xml @@ -0,0 +1,17 @@ + + + + 16dp + 16dp + 6dp + 6dp + + + 10sp + 12sp + 14sp + 16sp + 20sp + 24sp + + diff --git a/dmvp/src/main/res/values/strings.xml b/dmvp/src/main/res/values/strings.xml new file mode 100644 index 0000000..229e3a1 --- /dev/null +++ b/dmvp/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + ERROR + 还没有数据哦 + 请稍后... + 重新尝试 + 网络不可用,请检查你的网络 + \ No newline at end of file diff --git a/dmvp/src/main/res/values/styles.xml b/dmvp/src/main/res/values/styles.xml new file mode 100644 index 0000000..8148309 --- /dev/null +++ b/dmvp/src/main/res/values/styles.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..aac7c9b --- /dev/null +++ b/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 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..13372ae Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..76c3c5f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Apr 14 17:44:48 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 diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..9d82f78 --- /dev/null +++ b/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 "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/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 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..56a53e3 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app', ':dmvp'