├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── dictionaries │ └── public1.xml ├── gradle.xml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tikeyc │ │ └── tnineplacegridview_android │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── tikeyc │ │ │ └── tnineplacegridview_android │ │ │ ├── MainActivity.java │ │ │ └── libs │ │ │ └── CircleImageView.java │ └── res │ │ ├── drawable │ │ └── corners_bg.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ └── timage_listactivity_listview_item.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── beauty.jpg │ │ ├── glenceluanch.jpg │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── tikeyc │ └── tnineplacegridview_android │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle ├── tnineplacegridviewlibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── tikeyc │ │ └── tnineplacegridviewlibrary │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── tikeyc │ │ │ └── tnineplacegridviewlibrary │ │ │ └── TNinePlaceGridView │ │ │ ├── TImageGridViewAdapter.java │ │ │ ├── TImageListBgView.java │ │ │ ├── TNinePlaceGridView.java │ │ │ ├── TPageControl.java │ │ │ ├── TPageHorizatalScrollView.java │ │ │ ├── TRect.java │ │ │ ├── TScallImageView.java │ │ │ └── photoview │ │ │ ├── Compat.java │ │ │ ├── CustomGestureDetector.java │ │ │ ├── OnGestureListener.java │ │ │ ├── OnMatrixChangedListener.java │ │ │ ├── OnOutsidePhotoTapListener.java │ │ │ ├── OnPhotoTapListener.java │ │ │ ├── OnScaleChangedListener.java │ │ │ ├── OnSingleFlingListener.java │ │ │ ├── OnViewTapListener.java │ │ │ ├── PhotoView.java │ │ │ ├── PhotoViewAttacher.java │ │ │ └── Util.java │ └── res │ │ └── values │ │ ├── attrs.xml │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── tikeyc │ └── tnineplacegridviewlibrary │ └── ExampleUnitTest.java └── xutils ├── .gitignore ├── build.gradle ├── docs ├── 1.快速使用.md ├── 2.任务和回调.md ├── 3.网络请求.md ├── 4.图片绑定.md ├── 5.Sqlite数据库使用.md └── 6.View注入.md └── src └── main ├── AndroidManifest.xml └── java └── org └── xutils ├── DbManager.java ├── HttpManager.java ├── ImageManager.java ├── ViewInjector.java ├── cache ├── DiskCacheEntity.java ├── DiskCacheFile.java ├── LruCache.java └── LruDiskCache.java ├── common ├── Callback.java ├── TaskController.java ├── task │ ├── AbsTask.java │ ├── Priority.java │ ├── PriorityExecutor.java │ ├── PriorityRunnable.java │ ├── TaskControllerImpl.java │ └── TaskProxy.java └── util │ ├── DensityUtil.java │ ├── DoubleKeyValueMap.java │ ├── FileUtil.java │ ├── IOUtil.java │ ├── KeyValue.java │ ├── LogUtil.java │ ├── MD5.java │ ├── ParameterizedTypeUtil.java │ └── ProcessLock.java ├── config └── DbConfigs.java ├── db ├── CursorUtils.java ├── DbManagerImpl.java ├── DbModelSelector.java ├── Selector.java ├── annotation │ ├── Column.java │ └── Table.java ├── converter │ ├── BooleanColumnConverter.java │ ├── ByteArrayColumnConverter.java │ ├── ByteColumnConverter.java │ ├── CharColumnConverter.java │ ├── ColumnConverter.java │ ├── ColumnConverterFactory.java │ ├── DateColumnConverter.java │ ├── DoubleColumnConverter.java │ ├── FloatColumnConverter.java │ ├── IntegerColumnConverter.java │ ├── LongColumnConverter.java │ ├── ShortColumnConverter.java │ ├── SqlDateColumnConverter.java │ └── StringColumnConverter.java ├── sqlite │ ├── ColumnDbType.java │ ├── SqlInfo.java │ ├── SqlInfoBuilder.java │ └── WhereBuilder.java └── table │ ├── ColumnEntity.java │ ├── ColumnUtils.java │ ├── DbBase.java │ ├── DbModel.java │ ├── TableEntity.java │ └── TableUtils.java ├── ex ├── BaseException.java ├── DbException.java ├── FileLockedException.java ├── HttpException.java └── HttpRedirectException.java ├── http ├── BaseParams.java ├── HttpManagerImpl.java ├── HttpMethod.java ├── HttpTask.java ├── ProgressHandler.java ├── RequestParams.java ├── RequestParamsHelper.java ├── RequestTrackerWrapper.java ├── annotation │ ├── HttpRequest.java │ └── HttpResponse.java ├── app │ ├── DefaultParamsBuilder.java │ ├── HttpRetryHandler.java │ ├── InputStreamResponseParser.java │ ├── ParamsBuilder.java │ ├── RedirectHandler.java │ ├── RequestInterceptListener.java │ ├── RequestTracker.java │ └── ResponseParser.java ├── body │ ├── BodyItemWrapper.java │ ├── FileBody.java │ ├── InputStreamBody.java │ ├── MultipartBody.java │ ├── ProgressBody.java │ ├── RequestBody.java │ ├── StringBody.java │ └── UrlEncodedParamsBody.java ├── cookie │ ├── CookieEntity.java │ └── DbCookieStore.java ├── loader │ ├── BooleanLoader.java │ ├── ByteArrayLoader.java │ ├── FileLoader.java │ ├── IntegerLoader.java │ ├── JSONArrayLoader.java │ ├── JSONObjectLoader.java │ ├── Loader.java │ ├── LoaderFactory.java │ ├── ObjectLoader.java │ └── StringLoader.java └── request │ ├── AssetsRequest.java │ ├── HttpRequest.java │ ├── LocalFileRequest.java │ ├── UriRequest.java │ └── UriRequestFactory.java ├── image ├── AsyncDrawable.java ├── GifDrawable.java ├── ImageAnimationHelper.java ├── ImageDecoder.java ├── ImageLoader.java ├── ImageManagerImpl.java ├── ImageOptions.java ├── MemCacheKey.java ├── ReusableBitmapDrawable.java └── ReusableDrawable.java ├── view ├── EventListenerManager.java ├── ViewFinder.java ├── ViewInfo.java ├── ViewInjectorImpl.java └── annotation │ ├── ContentView.java │ ├── Event.java │ └── ViewInject.java └── x.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/dictionaries/public1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.0" 6 | defaultConfig { 7 | applicationId "com.tikeyc.tnineplacegridview_android" 8 | minSdkVersion 14 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:25.3.1' 28 | compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7' 29 | testCompile 'junit:junit:4.12' 30 | compile project(':tnineplacegridviewlibrary') 31 | compile project(':xutils') 32 | } 33 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/public1/Desktop/Eclipse/Android-SDK/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/tikeyc/tnineplacegridview_android/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridview_android; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.tikeyc.tnineplacegridview_android", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/timage_listactivity_listview_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 21 | 22 | 30 | 31 | 32 | 33 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/beauty.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-xhdpi/beauty.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/glenceluanch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-xhdpi/glenceluanch.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | TNinePlaceGridView_Android 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/tikeyc/tnineplacegridview_android/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridview_android; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.3.2' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jul 21 10:01:05 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':tnineplacegridviewlibrary', ':xutils' 2 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | group='com.github.tikeyc' 3 | 4 | android { 5 | compileSdkVersion 25 6 | buildToolsVersion "25.0.0" 7 | 8 | defaultConfig { 9 | minSdkVersion 14 10 | targetSdkVersion 25 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 28 | exclude group: 'com.android.support', module: 'support-annotations' 29 | }) 30 | compile 'com.android.support:appcompat-v7:25.3.1' 31 | // https://mvnrepository.com/artifact/com.squareup.picasso/picasso 32 | compile 'com.squareup.picasso:picasso:2.5.2' 33 | testCompile 'junit:junit:4.12' 34 | } 35 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/public1/Desktop/Eclipse/Android-SDK/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/androidTest/java/com/tikeyc/tnineplacegridviewlibrary/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.tikeyc.tnineplacegridviewlibrary.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/TImageGridViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import android.widget.AbsListView; 7 | import android.widget.BaseAdapter; 8 | import android.widget.ImageView; 9 | 10 | import com.squareup.picasso.Picasso; 11 | import com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview.OnViewTapListener; 12 | import com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview.PhotoView; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * Created by public1 on 2017/5/23. 18 | */ 19 | 20 | public class TImageGridViewAdapter extends BaseAdapter { 21 | 22 | Context context; 23 | public List imageIds; 24 | 25 | public TImageGridViewAdapter(Context context) { 26 | this.context = context; 27 | } 28 | 29 | @Override 30 | public int getCount() { 31 | if (this.imageIds != null) return imageIds.size(); 32 | return 0; 33 | } 34 | 35 | @Override 36 | public Object getItem(int i) { 37 | return null; 38 | } 39 | 40 | @Override 41 | public long getItemId(int i) { 42 | return 0; 43 | } 44 | 45 | @Override 46 | public View getView(final int i, View view, ViewGroup viewGroup) { 47 | 48 | if (view == null) { 49 | view = new PhotoView(context); 50 | PhotoView imageView = (PhotoView) view; 51 | imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); 52 | imageView.setMinimumScale(0.5f); 53 | imageView.setOnViewTapListener(new OnViewTapListener() { 54 | @Override 55 | public void onViewTap(View view, float x, float y) { 56 | if (onItemClickListener != null) { 57 | onItemClickListener.onItemClick(i,view); 58 | } 59 | } 60 | }); 61 | AbsListView.LayoutParams param = new AbsListView.LayoutParams(TRect.getScreenWidth(context), TRect.getScreenHeight(context)); 62 | view.setLayoutParams(param); 63 | } 64 | 65 | PhotoView imageView = (PhotoView) view; 66 | // Picasso.with(context).load("http://ww2.sinaimg.cn/mw690/9e6995c9gw1f2uu70bzohj209q06g3yw.jpg").into(imageView); 67 | if (imageIds.get(i) instanceof Integer) { 68 | imageView.setImageResource((Integer) imageIds.get(i)); 69 | } else { 70 | Picasso.with(context).load((String) imageIds.get(i)).into(imageView); 71 | } 72 | 73 | 74 | return view; 75 | } 76 | 77 | 78 | private OnItemClickListener onItemClickListener; 79 | 80 | public OnItemClickListener getOnItemClickListener() { 81 | return onItemClickListener; 82 | } 83 | 84 | public void setOnItemClickListener(OnItemClickListener onItemClickListener) { 85 | this.onItemClickListener = onItemClickListener; 86 | } 87 | 88 | public interface OnItemClickListener { 89 | void onItemClick(int i, View view); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/TPageHorizatalScrollView.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.util.DisplayMetrics; 6 | import android.view.MotionEvent; 7 | import android.widget.HorizontalScrollView; 8 | 9 | /** 10 | * Created by public1 on 2017/5/23. 11 | */ 12 | 13 | public class TPageHorizatalScrollView extends HorizontalScrollView { 14 | 15 | public int mBaseScrollX;//滑动基线。也就是点击并滑动之前的x值,以此值计算相对滑动距离。 16 | private int mScreenWidth; 17 | private int mScreenHeight; 18 | private int mPageCount;//页面数量 19 | 20 | private int mScrollX = 200;//滑动多长距离翻页 21 | 22 | 23 | public TPageHorizatalScrollView(Context context) { 24 | super(context); 25 | 26 | init(context); 27 | } 28 | 29 | public TPageHorizatalScrollView(Context context, AttributeSet attrs) { 30 | super(context, attrs); 31 | 32 | init(context); 33 | } 34 | 35 | 36 | 37 | public TPageHorizatalScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 38 | super(context, attrs, defStyleAttr); 39 | } 40 | 41 | 42 | private void init(Context context) { 43 | DisplayMetrics dm = context.getApplicationContext().getResources() 44 | .getDisplayMetrics(); 45 | mScreenWidth = dm.widthPixels; 46 | mScreenHeight = dm.heightPixels; 47 | } 48 | 49 | /** 50 | * 获取页面数量 51 | * @return 52 | */ 53 | public int getPageCount() { 54 | return mPageCount; 55 | } 56 | 57 | /** 58 | * 获取相对滑动位置。由右向左滑动,返回正值;由左向右滑动,返回负值。 59 | * @return 60 | */ 61 | private int getBaseScrollX() { 62 | return getScrollX() - mBaseScrollX; 63 | } 64 | 65 | /** 66 | * 使相对于基线移动x距离。 67 | * @param x x为正值时右移;为负值时左移。 68 | */ 69 | public void baseSmoothScrollTo(int x) { 70 | smoothScrollTo(x + mBaseScrollX, 0); 71 | if (onScrollToIndexListen != null) { 72 | int index = (x + mBaseScrollX)/mScreenWidth; 73 | onScrollToIndexListen.scrollToIndex(index); 74 | } 75 | } 76 | 77 | @Override 78 | public boolean onTouchEvent(MotionEvent ev) { 79 | int action = ev.getAction(); 80 | switch (action) { 81 | case MotionEvent.ACTION_UP: 82 | int scrollX = getBaseScrollX(); 83 | //左滑,大于一半,移到下一页 84 | if (scrollX > mScrollX) { 85 | baseSmoothScrollTo(mScreenWidth); 86 | mBaseScrollX += mScreenWidth; 87 | } 88 | //左滑,不到一半,返回原位 89 | else if (scrollX > 0) { 90 | baseSmoothScrollTo(0); 91 | } 92 | //右滑,不到一半,返回原位 93 | else if(scrollX > -mScrollX) { 94 | baseSmoothScrollTo(0); 95 | } 96 | //右滑,大于一半,移到下一页 97 | else { 98 | baseSmoothScrollTo(-mScreenWidth); 99 | mBaseScrollX -= mScreenWidth; 100 | } 101 | return false; 102 | } 103 | return super.onTouchEvent(ev); 104 | } 105 | 106 | private OnScrollToIndexListen onScrollToIndexListen; 107 | 108 | public void setOnScrollToIndexListen(OnScrollToIndexListen onScrollToIndexListen) { 109 | this.onScrollToIndexListen = onScrollToIndexListen; 110 | } 111 | 112 | public OnScrollToIndexListen getOnScrollToIndexListen() { 113 | return onScrollToIndexListen; 114 | } 115 | 116 | public interface OnScrollToIndexListen { 117 | void scrollToIndex(int index); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/TRect.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.util.DisplayMetrics; 6 | 7 | /** 8 | * Created by public1 on 2017/5/23. 9 | */ 10 | 11 | public class TRect { 12 | 13 | private int left; 14 | private int top; 15 | private int width; 16 | private int height; 17 | 18 | public TRect(int left, int top, int width, int height) { 19 | this.left = left; 20 | this.top = top; 21 | this.width = width; 22 | this.height = height; 23 | } 24 | 25 | public int getLeft() { 26 | return left; 27 | } 28 | 29 | public int getTop() { 30 | return top; 31 | } 32 | 33 | public int getWidth() { 34 | return width; 35 | } 36 | 37 | public int getHeight() { 38 | return height; 39 | } 40 | 41 | public void setLeft(int left) { 42 | this.left = left; 43 | } 44 | 45 | public void setTop(int top) { 46 | this.top = top; 47 | } 48 | 49 | public void setWidth(int width) { 50 | this.width = width; 51 | } 52 | 53 | public void setHeight(int height) { 54 | this.height = height; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return "TRect{" + 60 | "left=" + left + 61 | ", top=" + top + 62 | ", width=" + width + 63 | ", height=" + height + 64 | '}'; 65 | } 66 | 67 | 68 | public static int getScreenWidth(Context context) { 69 | Resources resources = context.getResources(); 70 | DisplayMetrics dm = resources.getDisplayMetrics(); 71 | float density = dm.density; 72 | int screenWidth = dm.widthPixels; 73 | // int screenHeight = dm.heightPixels; 74 | return screenWidth; 75 | } 76 | 77 | public static int getScreenHeight(Context context) { 78 | Resources resources = context.getResources(); 79 | DisplayMetrics dm = resources.getDisplayMetrics(); 80 | float density = dm.density; 81 | // int screenWidth = dm.widthPixels; 82 | int screenHeight = dm.heightPixels; 83 | return screenHeight; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/TScallImageView.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView; 2 | import android.content.Context; 3 | import android.util.AttributeSet; 4 | import android.util.Log; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by public1 on 2017/5/19. 13 | */ 14 | 15 | public class TScallImageView extends android.support.v7.widget.AppCompatImageView { 16 | 17 | public static final int STATE_NORMAL = 0; 18 | public static final int STATE_TRANSFORM_IN = 1; 19 | public static final int STATE_TRANSFORM_OUT = 2; 20 | 21 | public ViewGroup ninePlaceGridView;//外部设置 22 | private TRect originalRect;//得到的第一个图片相对于window的位置 23 | private List originalRects;//得到的第所有图片相对于window的位置 24 | public Object imageId;//外部设置 25 | public List imageIds;//外部设置 26 | public int currentIndex;//外部设置 27 | public TImageListBgView imageListBgView; 28 | 29 | public TScallImageView(Context context) { 30 | super(context); 31 | init(); 32 | } 33 | 34 | public TScallImageView(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | init(); 37 | } 38 | 39 | public TScallImageView(Context context, AttributeSet attrs, int defStyle) { 40 | super(context, attrs, defStyle); 41 | init(); 42 | } 43 | 44 | private void init() { 45 | setOnClickListener(new OnClickListener() { 46 | @Override 47 | public void onClick(View view) { 48 | showImageToWindow(); 49 | } 50 | }); 51 | } 52 | 53 | 54 | /**获取每个图片相对于window的位置 55 | * @return 56 | */ 57 | private List getOriginalRects() { 58 | List originalRects = new ArrayList(); 59 | int count = ninePlaceGridView.getChildCount(); 60 | for (int i = 0; i < count; i++) { 61 | if (ninePlaceGridView.getChildAt(i) instanceof TScallImageView) { 62 | TScallImageView scallImageView = (TScallImageView) ninePlaceGridView.getChildAt(i); 63 | int[] outLocation = new int[2]; 64 | scallImageView.getLocationInWindow(outLocation); 65 | Log.e("TAG","outLocation[0]:" + outLocation[0] + "outLocation[1]:" + outLocation[1]); 66 | TRect tRect = new TRect(outLocation[0],outLocation[1],scallImageView.getWidth(),scallImageView.getHeight()); 67 | originalRects.add(tRect); 68 | } else { 69 | continue; 70 | } 71 | 72 | } 73 | this.originalRects = originalRects; 74 | return originalRects; 75 | } 76 | 77 | public void showImageToWindow() { 78 | int[] outLocation = new int[2]; 79 | getLocationInWindow(outLocation); 80 | // originalRect = new TRect(getLeft(),getTop(),getWidth(),getHeight()); 81 | // originalRect = new TRect(outLocation[0],outLocation[1] - TKCUtils.getStatusBarHeight(getContext()),getWidth(),getHeight()); 82 | originalRect = new TRect(outLocation[0],outLocation[1],getWidth(),getHeight()); 83 | imageListBgView = new TImageListBgView(getContext(),originalRect,this.imageId,this.imageIds,currentIndex); 84 | imageListBgView.imageId = imageId; 85 | imageListBgView.originalRects = getOriginalRects(); 86 | imageListBgView.startTransform(TScallImageView.STATE_TRANSFORM_IN); 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/Compat.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 17 | 18 | import android.annotation.TargetApi; 19 | import android.os.Build.VERSION; 20 | import android.os.Build.VERSION_CODES; 21 | import android.view.View; 22 | 23 | class Compat { 24 | 25 | private static final int SIXTY_FPS_INTERVAL = 1000 / 60; 26 | 27 | public static void postOnAnimation(View view, Runnable runnable) { 28 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { 29 | postOnAnimationJellyBean(view, runnable); 30 | } else { 31 | view.postDelayed(runnable, SIXTY_FPS_INTERVAL); 32 | } 33 | } 34 | 35 | @TargetApi(16) 36 | private static void postOnAnimationJellyBean(View view, Runnable runnable) { 37 | view.postOnAnimation(runnable); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/OnGestureListener.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 17 | 18 | interface OnGestureListener { 19 | 20 | void onDrag(float dx, float dy); 21 | 22 | void onFling(float startX, float startY, float velocityX, 23 | float velocityY); 24 | 25 | void onScale(float scaleFactor, float focusX, float focusY); 26 | 27 | } -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/OnMatrixChangedListener.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 2 | 3 | import android.graphics.RectF; 4 | 5 | /** 6 | * Interface definition for a callback to be invoked when the internal Matrix has changed for 7 | * this View. 8 | */ 9 | public interface OnMatrixChangedListener { 10 | 11 | /** 12 | * Callback for when the Matrix displaying the Drawable has changed. This could be because 13 | * the View's bounds have changed, or the user has zoomed. 14 | * 15 | * @param rect - Rectangle displaying the Drawable's new bounds. 16 | */ 17 | void onMatrixChanged(RectF rect); 18 | } 19 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/OnOutsidePhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 2 | 3 | import android.widget.ImageView; 4 | 5 | /** 6 | * Callback when the user tapped outside of the photo 7 | */ 8 | public interface OnOutsidePhotoTapListener { 9 | 10 | /** 11 | * The outside of the photo has been tapped 12 | */ 13 | void onOutsidePhotoTap(ImageView imageView); 14 | } 15 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/OnPhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 2 | 3 | import android.widget.ImageView; 4 | 5 | /** 6 | * A callback to be invoked when the Photo is tapped with a single 7 | * tap. 8 | */ 9 | public interface OnPhotoTapListener { 10 | 11 | /** 12 | * A callback to receive where the user taps on a photo. You will only receive a callback if 13 | * the user taps on the actual photo, tapping on 'whitespace' will be ignored. 14 | * 15 | * @param view ImageView the user tapped. 16 | * @param x where the user tapped from the of the Drawable, as percentage of the 17 | * Drawable width. 18 | * @param y where the user tapped from the top of the Drawable, as percentage of the 19 | * Drawable height. 20 | */ 21 | void onPhotoTap(ImageView view, float x, float y); 22 | } 23 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/OnScaleChangedListener.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 2 | 3 | 4 | /** 5 | * Interface definition for callback to be invoked when attached ImageView scale changes 6 | */ 7 | public interface OnScaleChangedListener { 8 | 9 | /** 10 | * Callback for when the scale changes 11 | * 12 | * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in) 13 | * @param focusX focal point X position 14 | * @param focusY focal point Y position 15 | */ 16 | void onScaleChange(float scaleFactor, float focusX, float focusY); 17 | } 18 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/OnSingleFlingListener.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 2 | 3 | import android.view.MotionEvent; 4 | 5 | /** 6 | * A callback to be invoked when the ImageView is flung with a single 7 | * touch 8 | */ 9 | public interface OnSingleFlingListener { 10 | 11 | /** 12 | * A callback to receive where the user flings on a ImageView. You will receive a callback if 13 | * the user flings anywhere on the view. 14 | * 15 | * @param e1 MotionEvent the user first touch. 16 | * @param e2 MotionEvent the user last touch. 17 | * @param velocityX distance of user's horizontal fling. 18 | * @param velocityY distance of user's vertical fling. 19 | */ 20 | boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); 21 | } 22 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/OnViewTapListener.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 2 | 3 | import android.view.View; 4 | 5 | public interface OnViewTapListener { 6 | 7 | /** 8 | * A callback to receive where the user taps on a ImageView. You will receive a callback if 9 | * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored. 10 | * 11 | * @param view - View the user tapped. 12 | * @param x - where the user tapped from the left of the View. 13 | * @param y - where the user tapped from the top of the View. 14 | */ 15 | void onViewTap(View view, float x, float y); 16 | } 17 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/java/com/tikeyc/tnineplacegridviewlibrary/TNinePlaceGridView/photoview/Util.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary.TNinePlaceGridView.photoview; 2 | 3 | import android.view.MotionEvent; 4 | import android.widget.ImageView; 5 | 6 | class Util { 7 | 8 | static void checkZoomLevels(float minZoom, float midZoom, 9 | float maxZoom) { 10 | if (minZoom >= midZoom) { 11 | throw new IllegalArgumentException( 12 | "Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value"); 13 | } else if (midZoom >= maxZoom) { 14 | throw new IllegalArgumentException( 15 | "Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value"); 16 | } 17 | } 18 | 19 | static boolean hasDrawable(ImageView imageView) { 20 | return imageView.getDrawable() != null; 21 | } 22 | 23 | static boolean isSupportedScaleType(final ImageView.ScaleType scaleType) { 24 | if (scaleType == null) { 25 | return false; 26 | } 27 | switch (scaleType) { 28 | case MATRIX: 29 | throw new IllegalStateException("Matrix scale type is not supported"); 30 | } 31 | return true; 32 | } 33 | 34 | static int getPointerIndex(int action) { 35 | return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | TNinePlaceGridViewLibrary 3 | 4 | -------------------------------------------------------------------------------- /tnineplacegridviewlibrary/src/test/java/com/tikeyc/tnineplacegridviewlibrary/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.tikeyc.tnineplacegridviewlibrary; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /xutils/.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Eclipse project files 30 | .classpath 31 | .project 32 | project.properties 33 | 34 | # IDEA project files 35 | *.iml 36 | .idea/ 37 | 38 | # OS generated files 39 | .DS_Store 40 | .DS_Store? 41 | ._* 42 | .Spotlight-V100 43 | .Trashes 44 | ehthumbs.db 45 | Thumbs.db 46 | 47 | # others 48 | ant.properties 49 | build.xml 50 | map.txt -------------------------------------------------------------------------------- /xutils/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | //apply plugin: 'com.github.dcendents.android-maven' 3 | //apply plugin: 'com.jfrog.bintray' 4 | // 5 | //def siteUrl = 'https://github.com/wyouflf/xUtils3' 6 | //def gitUrl = 'https://github.com/wyouflf/xUtils3.git' 7 | //group = "org.xutils" 8 | version = "3.5.0" 9 | 10 | android { 11 | compileSdkVersion 25 12 | buildToolsVersion '25.0.0' 13 | 14 | defaultConfig { 15 | minSdkVersion 14 16 | targetSdkVersion 25 17 | versionCode 20170405 18 | versionName version 19 | } 20 | buildTypes { 21 | debug { 22 | minifyEnabled false 23 | debuggable true 24 | } 25 | release { 26 | minifyEnabled false 27 | debuggable true 28 | } 29 | } 30 | sourceSets { 31 | main { 32 | jniLibs.srcDirs = ['libs'] 33 | java.srcDirs = ['src/main/java'] 34 | } 35 | } 36 | compileOptions { 37 | sourceCompatibility JavaVersion.VERSION_1_6 38 | targetCompatibility JavaVersion.VERSION_1_6 39 | } 40 | } 41 | 42 | //install { 43 | // repositories.mavenInstaller { 44 | // // This generates POM.xml with proper parameters 45 | // pom { 46 | // project { 47 | // packaging 'aar' 48 | // name 'xUtils' 49 | // description 'android orm, bitmap, http, view inject... ' 50 | // // #CONFIG# // project title 51 | // url siteUrl 52 | // // Set your license 53 | // licenses { 54 | // license { 55 | // name 'The Apache Software License, Version 2.0' 56 | // url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 57 | // } 58 | // } 59 | // developers { 60 | // developer { 61 | // id 'wyouflf' 62 | // // #CONFIG# // your user id (you can write your nickname) 63 | // name 'lei.jiao' 64 | // // #CONFIG# // your user name 65 | // email 'wyouflf@qq.com' 66 | // // #CONFIG# // your email 67 | // } 68 | // } 69 | // scm { 70 | // connection gitUrl 71 | // developerConnection gitUrl 72 | // url siteUrl 73 | // } 74 | // } 75 | // } 76 | // } 77 | //} 78 | //task sourcesJar(type: Jar) { 79 | // from android.sourceSets.main.java.srcDirs 80 | // classifier = 'sources' 81 | //} 82 | //task javadoc(type: Javadoc) { 83 | // options.encoding = "UTF-8" 84 | // source = android.sourceSets.main.java.srcDirs 85 | // classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 86 | //} 87 | //task javadocJar(type: Jar, dependsOn: javadoc) { 88 | // classifier = 'javadoc' 89 | // from javadoc.destinationDir 90 | //} 91 | //artifacts { 92 | // archives javadocJar 93 | // archives sourcesJar 94 | //} 95 | //Properties properties = new Properties() 96 | //properties.load(project.rootProject.file('local.properties').newDataInputStream()) 97 | //bintray { 98 | // user = properties.getProperty("bintray.user") 99 | // key = properties.getProperty("bintray.apikey") 100 | // configurations = ['archives'] 101 | // pkg { 102 | // repo = "maven" 103 | // name = "xUtils" 104 | // // #CONFIG# project name in jcenter 105 | // websiteUrl = siteUrl 106 | // vcsUrl = gitUrl 107 | // licenses = ["Apache-2.0"] 108 | // publish = true 109 | // } 110 | //} -------------------------------------------------------------------------------- /xutils/docs/1.快速使用.md: -------------------------------------------------------------------------------- 1 | ##xUtils快速使用说明 2 | 3 | 1. 导入依赖 4 | #### 使用Gradle构建时添加一下依赖即可: 5 | ```javascript 6 | compile 'org.xutils:xutils:3.3.22' 7 | ``` 8 | ##### 如果使用eclipse可以 [点击这里下载aar文件](http://dl.bintray.com/wyouflf/maven/org/xutils/xutils/), 然后用zip解压, 取出jar包和so文件. 9 | 10 | 2. 添加配置混淆设置 11 | ################### region for xUtils 12 | -keepattributes Signature,*Annotation* 13 | -keep public class org.xutils.** { 14 | public protected *; 15 | } 16 | -keep public interface org.xutils.** { 17 | public protected *; 18 | } 19 | -keepclassmembers class * extends org.xutils.** { 20 | public protected *; 21 | } 22 | -keepclassmembers @org.xutils.db.annotation.* class * {*;} 23 | -keepclassmembers @org.xutils.http.annotation.* class * {*;} 24 | -keepclassmembers class * { 25 | @org.xutils.view.annotation.Event ; 26 | } 27 | #################### end region 28 | 29 | 3. 配置权限 30 | ##### 需要的权限 31 | ```xml 32 | 33 | 34 | ``` 35 | 36 | 4. 初始化 37 | 如果为初始化会报 `RuntimeException`: "please invoke x.Ext.init(app) on Application#onCreate() 38 | and register your Application in manifest." 39 | #### 在`AndroidManifest.xml`中注册`自定义Application`, 之后加入下面的代码. 40 | ```java 41 | // 在application的onCreate中初始化 42 | @Override 43 | public void onCreate() { 44 | super.onCreate(); 45 | x.Ext.init(this); // 这一步之后, 我们就可以在任何地方使用x.app()来获取Application的实例了. 46 | x.Ext.setDebug(true); // 是否输出debug日志 47 | ... 48 | } 49 | ``` 50 | 51 | ## 现在可以开始使用xUtils了 52 | 常用的API可以参考 [README](http://) 53 | 接下来我们较为详细的介绍没一个模块的api和特性. -------------------------------------------------------------------------------- /xutils/docs/2.任务和回调.md: -------------------------------------------------------------------------------- 1 | ## xUtils中的任务和回调接口 2 | 任务和回调是网络请求的基础接口, xUtils的任务接口支持异步和同步任务的实现. 3 | 4 | 1. 为什么要设计新的接口, 而不使用Android系统API `AsyncTask`? 5 | 原因有几个方面, AsyncTask在各个版本系统中表现不一致, 包括默认任务的并发数, 是否可在子线程中使用等. 6 | 2. xUtils中的任务和回调接口特点是什么? 7 | * 可以在任何线程中直接使用. 8 | * 支持设置优先级. 9 | * 支持异步调用和同步调用. 10 | * 默认支持FIFO和FILO, 也可以使用自定义Executor. 11 | * 异步任务中所有错误(包括异步过程和回调操作)都会进入onError, 安全可靠. 12 | 13 | 3. 使用xUtils中的任务使用 14 | ```java 15 | x.task().start(task); // 执行一个异步任务 16 | result = x.task().startSync(task); // 同步执行该任务 17 | ``` 18 | 看到上面的接口是不是很简单, 定义一个任务后可以很方便的异步执行或同步执行. 接下来我们开始接受怎样定义一个任务. 19 | ```java 20 | // task的hello world 21 | x.task().start(new AbsTask() { 22 | @Override 23 | protected String doBackground() throws Throwable { 24 | return "hello world!"; 25 | } 26 | 27 | @Override 28 | protected void onSuccess(String result) { 29 | Log.d("test", result); 30 | } 31 | 32 | @Override 33 | protected void onError(Throwable ex, boolean isCallbackError) { 34 | Log.e("test", ex.getMessage(), ex); 35 | } 36 | }); 37 | ``` 38 | 实例中使用task的基类AbsTask定义了一个task的实例, 39 | 并使用异步的方式调用, `doBackground`在默认线程池中进行(后面会介绍怎样自定义线程池). 40 | `start`的返回值类型为`AbsTask`(示例中T为String), 41 | 但它并非被执行的task的实例, 而是task的代理, 对代理实例的所有方法调用不必关心线程的问题, 框架会自动处理. 42 | 如果使用`startSync`执行这个任务, 则`doBackground`在当前线程同步执行, 并且`doBackground`的返回值作为`startSync`的返回值. 43 | 44 | 4. AbsTask的重要属性和方法(以`on`开头的方法为UI线程的回调方法, 简称`回调方法`) 45 | * `doBackground` 执行任务的主要, 上面已经介绍了它的特性, 虽然它可以同步执行但仍然被这样命名. 46 | * `onWaiting` 任务`start`或`startSync`之后会立即执行, 任务尚未被分配执行线程. 47 | * `onStarted` 任务被分配执行线程后立即执行, 接下来会执行`doBackground`. 48 | * `onSuccess` 在`doBackground`执行完成后立即执行. 49 | * `onCancelled` 任务`onSuccess`之前任何线程调用`AbsTask#cancel`或`doBackground`中抛出`CancelledException`之后执行. 50 | * `onUpdate(int flag, Object... args)` 任何线程调用了`AbsTask#update(int flag, Object... args)`之后执行. 51 | * `onError(Throwable ex, boolean isCallbackError)` 以上任何方法中出现异常时执行, 参数isCallbackError表示是否`回调方法`中的错误. 52 | * `onFinished` 总是在最终调用, 即使任务出现error会被cancel. 53 | 54 | 5. 取消任务 AbsTask#cancel() 55 | 示例: 56 | ```java 57 | AbsTask proxy = x.task().start(task); 58 | ... 59 | proxy.cancel(); // 在任何线程调用 60 | // 如果在任务内部取消, 建议使用抛出CancelledException的方法, 这样可以使用message或自定义的CancelledException表明取消的原因. 61 | ... 62 | ``` 63 | 64 | 6. 自定义更新通知 AbsTask#update(int flag, Object... args) 65 | 示例: 66 | ```java 67 | x.task().start(new AbsTask() { 68 | 69 | private static final int FLAG_UPDATE = 1; 70 | 71 | @Override 72 | protected String doBackground() throws Throwable { 73 | this.update(FLAG_UPDATE, 0); 74 | ... 75 | this.update(FLAG_UPDATE, 50); 76 | ... 77 | this.update(FLAG_UPDATE, 100); 78 | return "hello world!"; 79 | } 80 | 81 | @Override 82 | protected void onUpdate(int flag, Object... args) { 83 | switch (flag) { 84 | case FLAG_UPDATE: { 85 | if (args == null || args.length != 1) return; 86 | int value = (Integer) args[0]; 87 | ... 88 | break; 89 | } 90 | default: { 91 | break; 92 | } 93 | } 94 | } 95 | 96 | ... 97 | }); 98 | ``` 99 | 100 | 7. 设置优先级, 覆盖方法 AbsTask#getPriority 101 | 102 | 8. 设置自定义线程池, 覆盖方法 AbsTask#getExecutor 103 | 104 | 9. 取消任务时是否不等待任务彻底结束, 立即收到取消的通知, 覆盖方法 AbsTask#isCancelFast 105 | 106 | 10. 任务是否被取消 `final` AbsTask#isCancelled, 107 | 108 | 11. 任务是都已经执行完成 `final` AbsTask#isFinished 109 | 110 | 12. 获取任务的状态 `final` AbsTask#getState 111 | 112 | 13. 获取执行结果 `final` AbsTask#getResult 113 | 114 | 14. 其他, 使用AbsTask(Callback.Cancelable cancelHandler)构造函数可自定义可扩展的取消逻辑. -------------------------------------------------------------------------------- /xutils/docs/3.网络请求.md: -------------------------------------------------------------------------------- 1 | ## xUtils中的网络请求使用 2 | 网络请求接口主要分两部分介绍, 基础请求的实现和自定义参数和返回值模板的应用. 3 | 4 | 5 | 6 | ### 基础请求的实现 7 | 8 | 9 | 10 | 11 | ### 自定义参数和返回值模板的应用 -------------------------------------------------------------------------------- /xutils/docs/4.图片绑定.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/xutils/docs/4.图片绑定.md -------------------------------------------------------------------------------- /xutils/docs/5.Sqlite数据库使用.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/xutils/docs/5.Sqlite数据库使用.md -------------------------------------------------------------------------------- /xutils/docs/6.View注入.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tikeyc/TNinePlaceGridView_Android/1bfe0fbd4677f762c11af8448c0440c1818da29b/xutils/docs/6.View注入.md -------------------------------------------------------------------------------- /xutils/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/HttpManager.java: -------------------------------------------------------------------------------- 1 | package org.xutils; 2 | 3 | import org.xutils.common.Callback; 4 | import org.xutils.http.HttpMethod; 5 | import org.xutils.http.RequestParams; 6 | 7 | /** 8 | * Created by wyouflf on 15/6/17. 9 | * http请求接口 10 | */ 11 | public interface HttpManager { 12 | 13 | /** 14 | * 异步GET请求 15 | * 16 | * @param entity 17 | * @param callback 18 | * @param 19 | * @return 20 | */ 21 | Callback.Cancelable get(RequestParams entity, Callback.CommonCallback callback); 22 | 23 | /** 24 | * 异步POST请求 25 | * 26 | * @param entity 27 | * @param callback 28 | * @param 29 | * @return 30 | */ 31 | Callback.Cancelable post(RequestParams entity, Callback.CommonCallback callback); 32 | 33 | /** 34 | * 异步请求 35 | * 36 | * @param method 37 | * @param entity 38 | * @param callback 39 | * @param 40 | * @return 41 | */ 42 | Callback.Cancelable request(HttpMethod method, RequestParams entity, Callback.CommonCallback callback); 43 | 44 | 45 | /** 46 | * 同步GET请求 47 | * 48 | * @param entity 49 | * @param resultType 50 | * @param 51 | * @return 52 | * @throws Throwable 53 | */ 54 | T getSync(RequestParams entity, Class resultType) throws Throwable; 55 | 56 | /** 57 | * 同步POST请求 58 | * 59 | * @param entity 60 | * @param resultType 61 | * @param 62 | * @return 63 | * @throws Throwable 64 | */ 65 | T postSync(RequestParams entity, Class resultType) throws Throwable; 66 | 67 | /** 68 | * 同步请求 69 | * 70 | * @param method 71 | * @param entity 72 | * @param resultType 73 | * @param 74 | * @return 75 | * @throws Throwable 76 | */ 77 | T requestSync(HttpMethod method, RequestParams entity, Class resultType) throws Throwable; 78 | 79 | /** 80 | * 同步请求 81 | * 82 | * @param method 83 | * @param entity 84 | * @param callback 85 | * @param 86 | * @return 87 | * @throws Throwable 88 | */ 89 | T requestSync(HttpMethod method, RequestParams entity, Callback.TypedCallback callback) throws Throwable; 90 | } 91 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/ImageManager.java: -------------------------------------------------------------------------------- 1 | package org.xutils; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.widget.ImageView; 5 | 6 | import org.xutils.common.Callback; 7 | import org.xutils.image.ImageOptions; 8 | 9 | import java.io.File; 10 | 11 | /** 12 | * Created by wyouflf on 15/6/17. 13 | * 图片绑定接口 14 | */ 15 | public interface ImageManager { 16 | 17 | void bind(ImageView view, String url); 18 | 19 | void bind(ImageView view, String url, ImageOptions options); 20 | 21 | void bind(ImageView view, String url, Callback.CommonCallback callback); 22 | 23 | void bind(ImageView view, String url, ImageOptions options, Callback.CommonCallback callback); 24 | 25 | Callback.Cancelable loadDrawable(String url, ImageOptions options, Callback.CommonCallback callback); 26 | 27 | Callback.Cancelable loadFile(String url, ImageOptions options, Callback.CacheCallback callback); 28 | 29 | void clearMemCache(); 30 | 31 | void clearCacheFiles(); 32 | } 33 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/ViewInjector.java: -------------------------------------------------------------------------------- 1 | package org.xutils; 2 | 3 | import android.app.Activity; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | /** 9 | * Created by wyouflf on 15/10/29. 10 | * view注入接口 11 | */ 12 | public interface ViewInjector { 13 | 14 | /** 15 | * 注入view 16 | * 17 | * @param view 18 | */ 19 | void inject(View view); 20 | 21 | /** 22 | * 注入activity 23 | * 24 | * @param activity 25 | */ 26 | void inject(Activity activity); 27 | 28 | /** 29 | * 注入view holder 30 | * 31 | * @param handler view holder 32 | * @param view 33 | */ 34 | void inject(Object handler, View view); 35 | 36 | /** 37 | * 注入fragment 38 | * 39 | * @param fragment 40 | * @param inflater 41 | * @param container 42 | * @return 43 | */ 44 | View inject(Object fragment, LayoutInflater inflater, ViewGroup container); 45 | } 46 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/cache/DiskCacheEntity.java: -------------------------------------------------------------------------------- 1 | package org.xutils.cache; 2 | 3 | import org.xutils.db.annotation.Column; 4 | import org.xutils.db.annotation.Table; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * Created by wyouflf on 15/8/2. 10 | * 磁盘缓存对象 11 | */ 12 | @Table(name = "disk_cache") 13 | public final class DiskCacheEntity { 14 | 15 | @Column(name = "id", isId = true) 16 | private long id; 17 | 18 | @Column(name = "key", property = "UNIQUE") 19 | private String key; 20 | 21 | @Column(name = "path") 22 | private String path; 23 | 24 | @Column(name = "textContent") 25 | private String textContent; 26 | 27 | // from "max-age" (since http 1.1) 28 | @Column(name = "expires") 29 | private long expires = Long.MAX_VALUE; 30 | 31 | @Column(name = "etag") 32 | private String etag; 33 | 34 | @Column(name = "hits") 35 | private long hits; 36 | 37 | @Column(name = "lastModify") 38 | private Date lastModify; 39 | 40 | @Column(name = "lastAccess") 41 | private long lastAccess; 42 | 43 | 44 | public DiskCacheEntity() { 45 | } 46 | 47 | public long getId() { 48 | return id; 49 | } 50 | 51 | public void setId(long id) { 52 | this.id = id; 53 | } 54 | 55 | public String getKey() { 56 | return key; 57 | } 58 | 59 | public void setKey(String key) { 60 | this.key = key; 61 | } 62 | 63 | /*package*/ String getPath() { 64 | return path; 65 | } 66 | 67 | /*package*/ void setPath(String path) { 68 | this.path = path; 69 | } 70 | 71 | public String getTextContent() { 72 | return textContent; 73 | } 74 | 75 | public void setTextContent(String textContent) { 76 | this.textContent = textContent; 77 | } 78 | 79 | public long getExpires() { 80 | return expires; 81 | } 82 | 83 | public void setExpires(long expires) { 84 | this.expires = expires; 85 | } 86 | 87 | public String getEtag() { 88 | return etag; 89 | } 90 | 91 | public void setEtag(String etag) { 92 | this.etag = etag; 93 | } 94 | 95 | public long getHits() { 96 | return hits; 97 | } 98 | 99 | public void setHits(long hits) { 100 | this.hits = hits; 101 | } 102 | 103 | public Date getLastModify() { 104 | return lastModify; 105 | } 106 | 107 | public void setLastModify(Date lastModify) { 108 | this.lastModify = lastModify; 109 | } 110 | 111 | public long getLastAccess() { 112 | return lastAccess == 0 ? System.currentTimeMillis() : lastAccess; 113 | } 114 | 115 | public void setLastAccess(long lastAccess) { 116 | this.lastAccess = lastAccess; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/cache/DiskCacheFile.java: -------------------------------------------------------------------------------- 1 | package org.xutils.cache; 2 | 3 | import org.xutils.common.util.IOUtil; 4 | import org.xutils.common.util.ProcessLock; 5 | 6 | import java.io.Closeable; 7 | import java.io.File; 8 | import java.io.IOException; 9 | 10 | /** 11 | * Created by wyouflf on 15/8/3. 12 | * 磁盘缓存文件, 操作完成后必须及时调用close()方法关闭. 13 | */ 14 | public final class DiskCacheFile extends File implements Closeable { 15 | 16 | /*package*/ DiskCacheEntity cacheEntity; 17 | /*package*/ ProcessLock lock; 18 | 19 | /** 20 | * @param cacheEntity 21 | * @param path 22 | * @param lock lock name: path 23 | */ 24 | /*package*/ DiskCacheFile(DiskCacheEntity cacheEntity, String path, ProcessLock lock) { 25 | super(path); 26 | this.cacheEntity = cacheEntity; 27 | this.lock = lock; 28 | } 29 | 30 | @Override 31 | public void close() throws IOException { 32 | IOUtil.closeQuietly(lock); 33 | } 34 | 35 | public DiskCacheFile commit() throws IOException { 36 | return getDiskCache().commitDiskCacheFile(this); 37 | } 38 | 39 | public LruDiskCache getDiskCache() { 40 | String dirName = this.getParentFile().getName(); 41 | return LruDiskCache.getDiskCache(dirName); 42 | } 43 | 44 | public DiskCacheEntity getCacheEntity() { 45 | return cacheEntity; 46 | } 47 | 48 | @Override 49 | protected void finalize() throws Throwable { 50 | super.finalize(); 51 | this.close(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/Callback.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | /** 6 | * Created by wyouflf on 15/6/5. 7 | * 通用回调接口 8 | */ 9 | public interface Callback { 10 | 11 | public interface CommonCallback extends Callback { 12 | void onSuccess(ResultType result); 13 | 14 | void onError(Throwable ex, boolean isOnCallback); 15 | 16 | void onCancelled(CancelledException cex); 17 | 18 | void onFinished(); 19 | } 20 | 21 | public interface TypedCallback extends CommonCallback { 22 | Type getLoadType(); 23 | } 24 | 25 | public interface CacheCallback extends CommonCallback { 26 | boolean onCache(ResultType result); 27 | } 28 | 29 | public interface ProxyCacheCallback extends CacheCallback { 30 | boolean onlyCache(); 31 | } 32 | 33 | public interface PrepareCallback extends CommonCallback { 34 | ResultType prepare(PrepareType rawData); 35 | } 36 | 37 | public interface ProgressCallback extends CommonCallback { 38 | void onWaiting(); 39 | 40 | void onStarted(); 41 | 42 | void onLoading(long total, long current, boolean isDownloading); 43 | } 44 | 45 | public interface GroupCallback extends Callback { 46 | void onSuccess(ItemType item); 47 | 48 | void onError(ItemType item, Throwable ex, boolean isOnCallback); 49 | 50 | void onCancelled(ItemType item, CancelledException cex); 51 | 52 | void onFinished(ItemType item); 53 | 54 | void onAllFinished(); 55 | } 56 | 57 | public interface Callable { 58 | void call(ResultType result); 59 | } 60 | 61 | public interface Cancelable { 62 | void cancel(); 63 | 64 | boolean isCancelled(); 65 | } 66 | 67 | public static class CancelledException extends RuntimeException { 68 | public CancelledException(String detailMessage) { 69 | super(detailMessage); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/TaskController.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common; 2 | 3 | import org.xutils.common.task.AbsTask; 4 | 5 | /** 6 | * Created by wyouflf on 15/6/11. 7 | * 任务管理接口 8 | */ 9 | public interface TaskController { 10 | 11 | /** 12 | * 在UI线程执行runnable. 13 | * 如果已在UI线程, 则直接执行. 14 | * 15 | * @param runnable 16 | */ 17 | void autoPost(Runnable runnable); 18 | 19 | /** 20 | * 在UI线程执行runnable. 21 | * post到msg queue. 22 | * 23 | * @param runnable 24 | */ 25 | void post(Runnable runnable); 26 | 27 | /** 28 | * 在UI线程执行runnable. 29 | * 30 | * @param runnable 31 | * @param delayMillis 延迟时间(单位毫秒) 32 | */ 33 | void postDelayed(Runnable runnable, long delayMillis); 34 | 35 | /** 36 | * 在后台线程执行runnable 37 | * 38 | * @param runnable 39 | */ 40 | void run(Runnable runnable); 41 | 42 | /** 43 | * 移除post或postDelayed提交的, 未执行的runnable 44 | * 45 | * @param runnable 46 | */ 47 | void removeCallbacks(Runnable runnable); 48 | 49 | /** 50 | * 开始一个异步任务 51 | * 52 | * @param task 53 | * @param 54 | * @return 55 | */ 56 | AbsTask start(AbsTask task); 57 | 58 | /** 59 | * 同步执行一个任务 60 | * 61 | * @param task 62 | * @param 63 | * @return 64 | * @throws Throwable 65 | */ 66 | T startSync(AbsTask task) throws Throwable; 67 | 68 | /** 69 | * 批量执行异步任务 70 | * 71 | * @param groupCallback 72 | * @param tasks 73 | * @param 74 | * @return 75 | */ 76 | > Callback.Cancelable startTasks(Callback.GroupCallback groupCallback, T... tasks); 77 | } 78 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/task/AbsTask.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common.task; 2 | 3 | import org.xutils.common.Callback; 4 | 5 | import java.util.concurrent.Executor; 6 | 7 | 8 | /** 9 | * Created by wyouflf on 15/6/5. 10 | * 异步任务基类 11 | * 12 | * @param 13 | */ 14 | public abstract class AbsTask implements Callback.Cancelable { 15 | 16 | private TaskProxy taskProxy = null; 17 | private final Callback.Cancelable cancelHandler; 18 | 19 | private volatile boolean isCancelled = false; 20 | private volatile State state = State.IDLE; 21 | private ResultType result; 22 | 23 | public AbsTask() { 24 | this(null); 25 | } 26 | 27 | public AbsTask(Callback.Cancelable cancelHandler) { 28 | this.cancelHandler = cancelHandler; 29 | } 30 | 31 | protected abstract ResultType doBackground() throws Throwable; 32 | 33 | protected abstract void onSuccess(ResultType result); 34 | 35 | protected abstract void onError(Throwable ex, boolean isCallbackError); 36 | 37 | protected void onWaiting() { 38 | } 39 | 40 | protected void onStarted() { 41 | } 42 | 43 | protected void onUpdate(int flag, Object... args) { 44 | } 45 | 46 | protected void onCancelled(Callback.CancelledException cex) { 47 | } 48 | 49 | protected void onFinished() { 50 | } 51 | 52 | public Priority getPriority() { 53 | return null; 54 | } 55 | 56 | public Executor getExecutor() { 57 | return null; 58 | } 59 | 60 | protected final void update(int flag, Object... args) { 61 | if (taskProxy != null) { 62 | taskProxy.onUpdate(flag, args); 63 | } 64 | } 65 | 66 | /** 67 | * invoked via cancel() 68 | */ 69 | protected void cancelWorks() { 70 | } 71 | 72 | /** 73 | * 取消任务时是否不等待任务彻底结束, 立即收到取消的通知. 74 | * 75 | * @return 76 | */ 77 | protected boolean isCancelFast() { 78 | return false; 79 | } 80 | 81 | @Override 82 | public final synchronized void cancel() { 83 | if (!this.isCancelled) { 84 | this.isCancelled = true; 85 | cancelWorks(); 86 | if (cancelHandler != null && !cancelHandler.isCancelled()) { 87 | cancelHandler.cancel(); 88 | } 89 | if (this.state == State.WAITING || (this.state == State.STARTED && isCancelFast())) { 90 | if (taskProxy != null) { 91 | taskProxy.onCancelled(new Callback.CancelledException("cancelled by user")); 92 | taskProxy.onFinished(); 93 | } else if (this instanceof TaskProxy) { 94 | this.onCancelled(new Callback.CancelledException("cancelled by user")); 95 | this.onFinished(); 96 | } 97 | } 98 | } 99 | } 100 | 101 | @Override 102 | public final boolean isCancelled() { 103 | return isCancelled || state == State.CANCELLED || 104 | (cancelHandler != null && cancelHandler.isCancelled()); 105 | } 106 | 107 | public final boolean isFinished() { 108 | return this.state.value() > State.STARTED.value(); 109 | } 110 | 111 | public final State getState() { 112 | return state; 113 | } 114 | 115 | public final ResultType getResult() { 116 | return result; 117 | } 118 | 119 | /*package*/ 120 | void setState(State state) { 121 | this.state = state; 122 | } 123 | 124 | /*package*/ 125 | final void setTaskProxy(TaskProxy taskProxy) { 126 | this.taskProxy = taskProxy; 127 | } 128 | 129 | /*package*/ 130 | final void setResult(ResultType result) { 131 | this.result = result; 132 | } 133 | 134 | public enum State { 135 | IDLE(0), WAITING(1), STARTED(2), SUCCESS(3), CANCELLED(4), ERROR(5); 136 | private final int value; 137 | 138 | private State(int value) { 139 | this.value = value; 140 | } 141 | 142 | public int value() { 143 | return value; 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/task/Priority.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common.task; 2 | 3 | /** 4 | * Created by wyouflf on 15/6/5. 5 | * 任务的优先级 6 | */ 7 | public enum Priority { 8 | UI_TOP, UI_NORMAL, UI_LOW, DEFAULT, BG_TOP, BG_NORMAL, BG_LOW; 9 | } 10 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/task/PriorityExecutor.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common.task; 2 | 3 | import java.util.Comparator; 4 | import java.util.concurrent.BlockingQueue; 5 | import java.util.concurrent.Executor; 6 | import java.util.concurrent.PriorityBlockingQueue; 7 | import java.util.concurrent.ThreadFactory; 8 | import java.util.concurrent.ThreadPoolExecutor; 9 | import java.util.concurrent.TimeUnit; 10 | import java.util.concurrent.atomic.AtomicInteger; 11 | import java.util.concurrent.atomic.AtomicLong; 12 | 13 | /** 14 | * Created by wyouflf on 15/6/5. 15 | * 支持优先级的线程池管理类 16 | */ 17 | public class PriorityExecutor implements Executor { 18 | 19 | private static final int CORE_POOL_SIZE = 5; 20 | private static final int MAXIMUM_POOL_SIZE = 256; 21 | private static final int KEEP_ALIVE = 1; 22 | private static final AtomicLong SEQ_SEED = new AtomicLong(0); 23 | 24 | private static final ThreadFactory sThreadFactory = new ThreadFactory() { 25 | private final AtomicInteger mCount = new AtomicInteger(1); 26 | 27 | @Override 28 | public Thread newThread(Runnable runnable) { 29 | return new Thread(runnable, "xTID#" + mCount.getAndIncrement()); 30 | } 31 | }; 32 | 33 | private static final Comparator FIFO_CMP = new Comparator() { 34 | @Override 35 | public int compare(Runnable lhs, Runnable rhs) { 36 | if (lhs instanceof PriorityRunnable && rhs instanceof PriorityRunnable) { 37 | PriorityRunnable lpr = ((PriorityRunnable) lhs); 38 | PriorityRunnable rpr = ((PriorityRunnable) rhs); 39 | int result = lpr.priority.ordinal() - rpr.priority.ordinal(); 40 | return result == 0 ? (int) (lpr.SEQ - rpr.SEQ) : result; 41 | } else { 42 | return 0; 43 | } 44 | } 45 | }; 46 | 47 | private static final Comparator FILO_CMP = new Comparator() { 48 | @Override 49 | public int compare(Runnable lhs, Runnable rhs) { 50 | if (lhs instanceof PriorityRunnable && rhs instanceof PriorityRunnable) { 51 | PriorityRunnable lpr = ((PriorityRunnable) lhs); 52 | PriorityRunnable rpr = ((PriorityRunnable) rhs); 53 | int result = lpr.priority.ordinal() - rpr.priority.ordinal(); 54 | return result == 0 ? (int) (rpr.SEQ - lpr.SEQ) : result; 55 | } else { 56 | return 0; 57 | } 58 | } 59 | }; 60 | 61 | private final ThreadPoolExecutor mThreadPoolExecutor; 62 | 63 | /** 64 | * 默认工作线程数5 65 | * 66 | * @param fifo 优先级相同时, 等待队列的是否优先执行先加入的任务. 67 | */ 68 | public PriorityExecutor(boolean fifo) { 69 | this(CORE_POOL_SIZE, fifo); 70 | } 71 | 72 | /** 73 | * @param poolSize 工作线程数 74 | * @param fifo 优先级相同时, 等待队列的是否优先执行先加入的任务. 75 | */ 76 | public PriorityExecutor(int poolSize, boolean fifo) { 77 | BlockingQueue mPoolWorkQueue = 78 | new PriorityBlockingQueue(MAXIMUM_POOL_SIZE, fifo ? FIFO_CMP : FILO_CMP); 79 | mThreadPoolExecutor = new ThreadPoolExecutor( 80 | poolSize, 81 | MAXIMUM_POOL_SIZE, 82 | KEEP_ALIVE, 83 | TimeUnit.SECONDS, 84 | mPoolWorkQueue, 85 | sThreadFactory); 86 | } 87 | 88 | public int getPoolSize() { 89 | return mThreadPoolExecutor.getCorePoolSize(); 90 | } 91 | 92 | public void setPoolSize(int poolSize) { 93 | if (poolSize > 0) { 94 | mThreadPoolExecutor.setCorePoolSize(poolSize); 95 | } 96 | } 97 | 98 | public ThreadPoolExecutor getThreadPoolExecutor() { 99 | return mThreadPoolExecutor; 100 | } 101 | 102 | public boolean isBusy() { 103 | return mThreadPoolExecutor.getActiveCount() >= mThreadPoolExecutor.getCorePoolSize(); 104 | } 105 | 106 | @Override 107 | public void execute(Runnable runnable) { 108 | if (runnable instanceof PriorityRunnable) { 109 | ((PriorityRunnable) runnable).SEQ = SEQ_SEED.getAndIncrement(); 110 | } 111 | mThreadPoolExecutor.execute(runnable); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/task/PriorityRunnable.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common.task; 2 | 3 | /** 4 | * Created by wyouflf on 15/6/5. 5 | * 带有优先级的Runnable类型(仅在task包内可用) 6 | */ 7 | /*package*/ class PriorityRunnable implements Runnable { 8 | 9 | /*package*/ long SEQ; 10 | 11 | public final Priority priority; 12 | private final Runnable runnable; 13 | 14 | public PriorityRunnable(Priority priority, Runnable runnable) { 15 | this.priority = priority == null ? Priority.DEFAULT : priority; 16 | this.runnable = runnable; 17 | } 18 | 19 | @Override 20 | public final void run() { 21 | this.runnable.run(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/util/DensityUtil.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common.util; 2 | 3 | import org.xutils.x; 4 | 5 | 6 | public final class DensityUtil { 7 | 8 | private static float density = -1F; 9 | private static int widthPixels = -1; 10 | private static int heightPixels = -1; 11 | 12 | private DensityUtil() { 13 | } 14 | 15 | public static float getDensity() { 16 | if (density <= 0F) { 17 | density = x.app().getResources().getDisplayMetrics().density; 18 | } 19 | return density; 20 | } 21 | 22 | public static int dip2px(float dpValue) { 23 | return (int) (dpValue * getDensity() + 0.5F); 24 | } 25 | 26 | public static int px2dip(float pxValue) { 27 | return (int) (pxValue / getDensity() + 0.5F); 28 | } 29 | 30 | public static int getScreenWidth() { 31 | if (widthPixels <= 0) { 32 | widthPixels = x.app().getResources().getDisplayMetrics().widthPixels; 33 | } 34 | return widthPixels; 35 | } 36 | 37 | 38 | public static int getScreenHeight() { 39 | if (heightPixels <= 0) { 40 | heightPixels = x.app().getResources().getDisplayMetrics().heightPixels; 41 | } 42 | return heightPixels; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common.util; 2 | 3 | import android.os.Environment; 4 | import android.os.StatFs; 5 | 6 | import org.xutils.x; 7 | 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.FileOutputStream; 11 | 12 | public class FileUtil { 13 | 14 | private FileUtil() { 15 | } 16 | 17 | public static File getCacheDir(String dirName) { 18 | File result; 19 | if (existsSdcard()) { 20 | File cacheDir = x.app().getExternalCacheDir(); 21 | if (cacheDir == null) { 22 | result = new File(Environment.getExternalStorageDirectory(), 23 | "Android/data/" + x.app().getPackageName() + "/cache/" + dirName); 24 | } else { 25 | result = new File(cacheDir, dirName); 26 | } 27 | } else { 28 | result = new File(x.app().getCacheDir(), dirName); 29 | } 30 | if (result.exists() || result.mkdirs()) { 31 | return result; 32 | } else { 33 | return null; 34 | } 35 | } 36 | 37 | /** 38 | * 检查磁盘空间是否大于10mb 39 | * 40 | * @return true 大于 41 | */ 42 | public static boolean isDiskAvailable() { 43 | long size = getDiskAvailableSize(); 44 | return size > 10 * 1024 * 1024; // > 10bm 45 | } 46 | 47 | /** 48 | * 获取磁盘可用空间 49 | * 50 | * @return byte 单位 kb 51 | */ 52 | public static long getDiskAvailableSize() { 53 | if (!existsSdcard()) return 0; 54 | File path = Environment.getExternalStorageDirectory(); // 取得sdcard文件路径 55 | StatFs stat = new StatFs(path.getAbsolutePath()); 56 | long blockSize = stat.getBlockSize(); 57 | long availableBlocks = stat.getAvailableBlocks(); 58 | return availableBlocks * blockSize; 59 | // (availableBlocks * blockSize)/1024 KIB 单位 60 | // (availableBlocks * blockSize)/1024 /1024 MIB单位 61 | } 62 | 63 | public static Boolean existsSdcard() { 64 | return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); 65 | } 66 | 67 | public static long getFileOrDirSize(File file) { 68 | if (!file.exists()) return 0; 69 | if (!file.isDirectory()) return file.length(); 70 | 71 | long length = 0; 72 | File[] list = file.listFiles(); 73 | if (list != null) { // 文件夹被删除时, 子文件正在被写入, 文件属性异常返回null. 74 | for (File item : list) { 75 | length += getFileOrDirSize(item); 76 | } 77 | } 78 | 79 | return length; 80 | } 81 | 82 | /** 83 | * 复制文件到指定文件 84 | * 85 | * @param fromPath 源文件 86 | * @param toPath 复制到的文件 87 | * @return true 成功,false 失败 88 | */ 89 | public static boolean copy(String fromPath, String toPath) { 90 | boolean result = false; 91 | File from = new File(fromPath); 92 | if (!from.exists()) { 93 | return result; 94 | } 95 | 96 | File toFile = new File(toPath); 97 | IOUtil.deleteFileOrDir(toFile); 98 | File toDir = toFile.getParentFile(); 99 | if (toDir.exists() || toDir.mkdirs()) { 100 | FileInputStream in = null; 101 | FileOutputStream out = null; 102 | try { 103 | in = new FileInputStream(from); 104 | out = new FileOutputStream(toFile); 105 | IOUtil.copy(in, out); 106 | result = true; 107 | } catch (Throwable ex) { 108 | LogUtil.d(ex.getMessage(), ex); 109 | result = false; 110 | } finally { 111 | IOUtil.closeQuietly(in); 112 | IOUtil.closeQuietly(out); 113 | } 114 | } 115 | return result; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/util/KeyValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.common.util; 17 | 18 | public class KeyValue { 19 | public final String key; 20 | public final Object value; 21 | 22 | public KeyValue(String key, Object value) { 23 | this.key = key; 24 | this.value = value; 25 | } 26 | 27 | public String getValueStr() { 28 | return value == null ? null : value.toString(); 29 | } 30 | 31 | @Override 32 | public boolean equals(Object o) { 33 | if (this == o) return true; 34 | if (o == null || getClass() != o.getClass()) return false; 35 | 36 | KeyValue keyValue = (KeyValue) o; 37 | 38 | return key == null ? keyValue.key == null : key.equals(keyValue.key); 39 | 40 | } 41 | 42 | @Override 43 | public int hashCode() { 44 | return key != null ? key.hashCode() : 0; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return "KeyValue{" + "key='" + key + '\'' + ", value=" + value + '}'; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/util/MD5.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common.util; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.UnsupportedEncodingException; 7 | import java.nio.MappedByteBuffer; 8 | import java.nio.channels.FileChannel; 9 | import java.security.MessageDigest; 10 | import java.security.NoSuchAlgorithmException; 11 | 12 | public final class MD5 { 13 | 14 | private MD5() { 15 | } 16 | 17 | private static final char hexDigits[] = 18 | {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 19 | 20 | public static String toHexString(byte[] bytes) { 21 | if (bytes == null) return ""; 22 | StringBuilder hex = new StringBuilder(bytes.length * 2); 23 | for (byte b : bytes) { 24 | hex.append(hexDigits[(b >> 4) & 0x0F]); 25 | hex.append(hexDigits[b & 0x0F]); 26 | } 27 | return hex.toString(); 28 | } 29 | 30 | public static String md5(File file) throws IOException { 31 | MessageDigest messagedigest = null; 32 | FileInputStream in = null; 33 | FileChannel ch = null; 34 | byte[] encodeBytes = null; 35 | try { 36 | messagedigest = MessageDigest.getInstance("MD5"); 37 | in = new FileInputStream(file); 38 | ch = in.getChannel(); 39 | MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); 40 | messagedigest.update(byteBuffer); 41 | encodeBytes = messagedigest.digest(); 42 | } catch (NoSuchAlgorithmException neverHappened) { 43 | throw new RuntimeException(neverHappened); 44 | } finally { 45 | IOUtil.closeQuietly(in); 46 | IOUtil.closeQuietly(ch); 47 | } 48 | 49 | return toHexString(encodeBytes); 50 | } 51 | 52 | public static String md5(String string) { 53 | byte[] encodeBytes = null; 54 | try { 55 | encodeBytes = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8")); 56 | } catch (NoSuchAlgorithmException neverHappened) { 57 | throw new RuntimeException(neverHappened); 58 | } catch (UnsupportedEncodingException neverHappened) { 59 | throw new RuntimeException(neverHappened); 60 | } 61 | 62 | return toHexString(encodeBytes); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/common/util/ParameterizedTypeUtil.java: -------------------------------------------------------------------------------- 1 | package org.xutils.common.util; 2 | 3 | import java.lang.reflect.Array; 4 | import java.lang.reflect.GenericArrayType; 5 | import java.lang.reflect.ParameterizedType; 6 | import java.lang.reflect.Type; 7 | import java.lang.reflect.TypeVariable; 8 | 9 | public class ParameterizedTypeUtil { 10 | 11 | private ParameterizedTypeUtil() { 12 | } 13 | 14 | public static Type getParameterizedType( 15 | 16 | final Type ownerType, 17 | final Class declaredClass, 18 | int paramIndex) { 19 | 20 | Class clazz = null; 21 | ParameterizedType pt = null; 22 | Type[] ats = null; 23 | TypeVariable[] tps = null; 24 | if (ownerType instanceof ParameterizedType) { 25 | pt = (ParameterizedType) ownerType; 26 | clazz = (Class) pt.getRawType(); 27 | ats = pt.getActualTypeArguments(); 28 | tps = clazz.getTypeParameters(); 29 | } else { 30 | clazz = (Class) ownerType; 31 | } 32 | if (declaredClass == clazz) { 33 | if (ats != null) { 34 | return ats[paramIndex]; 35 | } 36 | return Object.class; 37 | } 38 | 39 | Type[] types = clazz.getGenericInterfaces(); 40 | if (types != null) { 41 | for (int i = 0; i < types.length; i++) { 42 | Type t = types[i]; 43 | if (t instanceof ParameterizedType) { 44 | Class cls = (Class) ((ParameterizedType) t).getRawType(); 45 | if (declaredClass.isAssignableFrom(cls)) { 46 | try { 47 | return getTrueType(getParameterizedType(t, declaredClass, paramIndex), tps, ats); 48 | } catch (Throwable ignored) { 49 | } 50 | } 51 | } 52 | } 53 | } 54 | 55 | Class superClass = clazz.getSuperclass(); 56 | if (superClass != null) { 57 | if (declaredClass.isAssignableFrom(superClass)) { 58 | return getTrueType( 59 | getParameterizedType(clazz.getGenericSuperclass(), 60 | declaredClass, paramIndex), tps, ats); 61 | } 62 | } 63 | 64 | throw new IllegalArgumentException("FindGenericType:" + ownerType + 65 | ", declaredClass: " + declaredClass + ", index: " + paramIndex); 66 | 67 | } 68 | 69 | 70 | private static Type getTrueType( 71 | 72 | Type type, 73 | TypeVariable[] typeVariables, 74 | Type[] actualTypes) { 75 | 76 | if (type instanceof TypeVariable) { 77 | TypeVariable tv = (TypeVariable) type; 78 | String name = tv.getName(); 79 | if (actualTypes != null) { 80 | for (int i = 0; i < typeVariables.length; i++) { 81 | if (name.equals(typeVariables[i].getName())) { 82 | return actualTypes[i]; 83 | } 84 | } 85 | } 86 | return tv; 87 | // }else if (type instanceof Class) { 88 | // return type; 89 | } else if (type instanceof GenericArrayType) { 90 | Type ct = ((GenericArrayType) type).getGenericComponentType(); 91 | if (ct instanceof Class) { 92 | return Array.newInstance((Class) ct, 0).getClass(); 93 | } 94 | } 95 | return type; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/config/DbConfigs.java: -------------------------------------------------------------------------------- 1 | package org.xutils.config; 2 | 3 | import org.xutils.DbManager; 4 | import org.xutils.common.util.LogUtil; 5 | import org.xutils.ex.DbException; 6 | 7 | /** 8 | * Created by wyouflf on 15/7/31. 9 | * 全局db配置 10 | */ 11 | public enum DbConfigs { 12 | HTTP(new DbManager.DaoConfig() 13 | .setDbName("xUtils_http_cache.db") 14 | .setDbVersion(1) 15 | .setDbOpenListener(new DbManager.DbOpenListener() { 16 | @Override 17 | public void onDbOpened(DbManager db) { 18 | db.getDatabase().enableWriteAheadLogging(); 19 | } 20 | }) 21 | .setDbUpgradeListener(new DbManager.DbUpgradeListener() { 22 | @Override 23 | public void onUpgrade(DbManager db, int oldVersion, int newVersion) { 24 | try { 25 | db.dropDb(); // 默认删除所有表 26 | } catch (DbException ex) { 27 | LogUtil.e(ex.getMessage(), ex); 28 | } 29 | } 30 | })), 31 | 32 | COOKIE(new DbManager.DaoConfig() 33 | .setDbName("xUtils_http_cookie.db") 34 | .setDbVersion(1) 35 | .setDbOpenListener(new DbManager.DbOpenListener() { 36 | @Override 37 | public void onDbOpened(DbManager db) { 38 | db.getDatabase().enableWriteAheadLogging(); 39 | } 40 | }) 41 | .setDbUpgradeListener(new DbManager.DbUpgradeListener() { 42 | @Override 43 | public void onUpgrade(DbManager db, int oldVersion, int newVersion) { 44 | try { 45 | db.dropDb(); // 默认删除所有表 46 | } catch (DbException ex) { 47 | LogUtil.e(ex.getMessage(), ex); 48 | } 49 | } 50 | })); 51 | 52 | private DbManager.DaoConfig config; 53 | 54 | DbConfigs(DbManager.DaoConfig config) { 55 | this.config = config; 56 | } 57 | 58 | public DbManager.DaoConfig getConfig() { 59 | return config; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/CursorUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.db; 17 | 18 | import android.database.Cursor; 19 | 20 | import org.xutils.db.table.ColumnEntity; 21 | import org.xutils.db.table.DbModel; 22 | import org.xutils.db.table.TableEntity; 23 | 24 | import java.util.HashMap; 25 | 26 | /*package*/ final class CursorUtils { 27 | 28 | public static T getEntity(TableEntity table, final Cursor cursor) throws Throwable { 29 | T entity = table.createEntity(); 30 | HashMap columnMap = table.getColumnMap(); 31 | int columnCount = cursor.getColumnCount(); 32 | for (int i = 0; i < columnCount; i++) { 33 | String columnName = cursor.getColumnName(i); 34 | ColumnEntity column = columnMap.get(columnName); 35 | if (column != null) { 36 | column.setValueFromCursor(entity, cursor, i); 37 | } 38 | } 39 | return entity; 40 | } 41 | 42 | public static DbModel getDbModel(final Cursor cursor) { 43 | DbModel result = new DbModel(); 44 | int columnCount = cursor.getColumnCount(); 45 | for (int i = 0; i < columnCount; i++) { 46 | result.add(cursor.getColumnName(i), cursor.getString(i)); 47 | } 48 | return result; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/annotation/Column.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.FIELD) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Column { 26 | 27 | String name(); 28 | 29 | String property() default ""; 30 | 31 | boolean isId() default false; 32 | 33 | boolean autoGen() default true; 34 | } 35 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/annotation/Table.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.TYPE) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Table { 26 | 27 | String name(); 28 | 29 | String onCreated() default ""; 30 | } -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/BooleanColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class BooleanColumnConverter implements ColumnConverter { 13 | @Override 14 | public Boolean getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getInt(index) == 1; 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(Boolean fieldValue) { 20 | if (fieldValue == null) return null; 21 | return fieldValue ? 1 : 0; 22 | } 23 | 24 | @Override 25 | public ColumnDbType getColumnDbType() { 26 | return ColumnDbType.INTEGER; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/ByteArrayColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class ByteArrayColumnConverter implements ColumnConverter { 13 | @Override 14 | public byte[] getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getBlob(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(byte[] fieldValue) { 20 | return fieldValue; 21 | } 22 | 23 | @Override 24 | public ColumnDbType getColumnDbType() { 25 | return ColumnDbType.BLOB; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/ByteColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class ByteColumnConverter implements ColumnConverter { 13 | @Override 14 | public Byte getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : (byte) cursor.getInt(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(Byte fieldValue) { 20 | return fieldValue; 21 | } 22 | 23 | @Override 24 | public ColumnDbType getColumnDbType() { 25 | return ColumnDbType.INTEGER; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/CharColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class CharColumnConverter implements ColumnConverter { 13 | @Override 14 | public Character getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : (char) cursor.getInt(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(Character fieldValue) { 20 | if (fieldValue == null) return null; 21 | return (int) fieldValue; 22 | } 23 | 24 | @Override 25 | public ColumnDbType getColumnDbType() { 26 | return ColumnDbType.INTEGER; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/ColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午8:57 11 | */ 12 | public interface ColumnConverter { 13 | 14 | T getFieldValue(final Cursor cursor, int index); 15 | 16 | Object fieldValue2DbValue(T fieldValue); 17 | 18 | ColumnDbType getColumnDbType(); 19 | } 20 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/DateColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | import java.util.Date; 8 | 9 | /** 10 | * Author: wyouflf 11 | * Date: 13-11-4 12 | * Time: 下午10:51 13 | */ 14 | public class DateColumnConverter implements ColumnConverter { 15 | @Override 16 | public Date getFieldValue(final Cursor cursor, int index) { 17 | return cursor.isNull(index) ? null : new Date(cursor.getLong(index)); 18 | } 19 | 20 | @Override 21 | public Object fieldValue2DbValue(Date fieldValue) { 22 | if (fieldValue == null) return null; 23 | return fieldValue.getTime(); 24 | } 25 | 26 | @Override 27 | public ColumnDbType getColumnDbType() { 28 | return ColumnDbType.INTEGER; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/DoubleColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class DoubleColumnConverter implements ColumnConverter { 13 | @Override 14 | public Double getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getDouble(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(Double fieldValue) { 20 | return fieldValue; 21 | } 22 | 23 | @Override 24 | public ColumnDbType getColumnDbType() { 25 | return ColumnDbType.REAL; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/FloatColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class FloatColumnConverter implements ColumnConverter { 13 | @Override 14 | public Float getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getFloat(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(Float fieldValue) { 20 | return fieldValue; 21 | } 22 | 23 | @Override 24 | public ColumnDbType getColumnDbType() { 25 | return ColumnDbType.REAL; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/IntegerColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class IntegerColumnConverter implements ColumnConverter { 13 | @Override 14 | public Integer getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getInt(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(Integer fieldValue) { 20 | return fieldValue; 21 | } 22 | 23 | @Override 24 | public ColumnDbType getColumnDbType() { 25 | return ColumnDbType.INTEGER; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/LongColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class LongColumnConverter implements ColumnConverter { 13 | @Override 14 | public Long getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getLong(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(Long fieldValue) { 20 | return fieldValue; 21 | } 22 | 23 | @Override 24 | public ColumnDbType getColumnDbType() { 25 | return ColumnDbType.INTEGER; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/ShortColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class ShortColumnConverter implements ColumnConverter { 13 | @Override 14 | public Short getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getShort(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(Short fieldValue) { 20 | return fieldValue; 21 | } 22 | 23 | @Override 24 | public ColumnDbType getColumnDbType() { 25 | return ColumnDbType.INTEGER; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/SqlDateColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class SqlDateColumnConverter implements ColumnConverter { 13 | @Override 14 | public java.sql.Date getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : new java.sql.Date(cursor.getLong(index)); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(java.sql.Date fieldValue) { 20 | if (fieldValue == null) return null; 21 | return fieldValue.getTime(); 22 | } 23 | 24 | @Override 25 | public ColumnDbType getColumnDbType() { 26 | return ColumnDbType.INTEGER; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/converter/StringColumnConverter.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import org.xutils.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class StringColumnConverter implements ColumnConverter { 13 | @Override 14 | public String getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getString(index); 16 | } 17 | 18 | @Override 19 | public Object fieldValue2DbValue(String fieldValue) { 20 | return fieldValue; 21 | } 22 | 23 | @Override 24 | public ColumnDbType getColumnDbType() { 25 | return ColumnDbType.TEXT; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/sqlite/ColumnDbType.java: -------------------------------------------------------------------------------- 1 | package org.xutils.db.sqlite; 2 | 3 | /** 4 | * Created by wyouflf on 14-2-20. 5 | */ 6 | public enum ColumnDbType { 7 | 8 | INTEGER("INTEGER"), REAL("REAL"), TEXT("TEXT"), BLOB("BLOB"); 9 | 10 | private String value; 11 | 12 | ColumnDbType(String value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/table/DbModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.db.table; 17 | 18 | import android.text.TextUtils; 19 | 20 | import java.util.Date; 21 | import java.util.HashMap; 22 | 23 | public final class DbModel { 24 | 25 | /** 26 | * key: columnName 27 | * value: valueStr 28 | */ 29 | private HashMap dataMap = new HashMap(); 30 | 31 | public String getString(String columnName) { 32 | return dataMap.get(columnName); 33 | } 34 | 35 | public int getInt(String columnName) { 36 | return Integer.valueOf(dataMap.get(columnName)); 37 | } 38 | 39 | public boolean getBoolean(String columnName) { 40 | String value = dataMap.get(columnName); 41 | if (value != null) { 42 | return value.length() == 1 ? "1".equals(value) : Boolean.valueOf(value); 43 | } 44 | return false; 45 | } 46 | 47 | public double getDouble(String columnName) { 48 | return Double.valueOf(dataMap.get(columnName)); 49 | } 50 | 51 | public float getFloat(String columnName) { 52 | return Float.valueOf(dataMap.get(columnName)); 53 | } 54 | 55 | public long getLong(String columnName) { 56 | return Long.valueOf(dataMap.get(columnName)); 57 | } 58 | 59 | public Date getDate(String columnName) { 60 | long date = Long.valueOf(dataMap.get(columnName)); 61 | return new Date(date); 62 | } 63 | 64 | public java.sql.Date getSqlDate(String columnName) { 65 | long date = Long.valueOf(dataMap.get(columnName)); 66 | return new java.sql.Date(date); 67 | } 68 | 69 | public void add(String columnName, String valueStr) { 70 | dataMap.put(columnName, valueStr); 71 | } 72 | 73 | /** 74 | * @return key: columnName 75 | */ 76 | public HashMap getDataMap() { 77 | return dataMap; 78 | } 79 | 80 | /** 81 | * @param columnName 82 | * @return 83 | */ 84 | public boolean isEmpty(String columnName) { 85 | return TextUtils.isEmpty(dataMap.get(columnName)); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/table/TableEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.db.table; 17 | 18 | import android.database.Cursor; 19 | 20 | import org.xutils.DbManager; 21 | import org.xutils.common.util.IOUtil; 22 | import org.xutils.db.annotation.Table; 23 | import org.xutils.ex.DbException; 24 | 25 | import java.lang.reflect.Constructor; 26 | import java.util.LinkedHashMap; 27 | 28 | 29 | public final class TableEntity { 30 | 31 | private final DbManager db; 32 | private final String name; 33 | private final String onCreated; 34 | private ColumnEntity id; 35 | private Class entityType; 36 | private Constructor constructor; 37 | private volatile boolean checkedDatabase; 38 | 39 | /** 40 | * key: columnName 41 | */ 42 | private final LinkedHashMap columnMap; 43 | 44 | /*package*/ TableEntity(DbManager db, Class entityType) throws Throwable { 45 | this.db = db; 46 | this.entityType = entityType; 47 | this.constructor = entityType.getConstructor(); 48 | this.constructor.setAccessible(true); 49 | Table table = entityType.getAnnotation(Table.class); 50 | this.name = table.name(); 51 | this.onCreated = table.onCreated(); 52 | this.columnMap = TableUtils.findColumnMap(entityType); 53 | 54 | for (ColumnEntity column : columnMap.values()) { 55 | if (column.isId()) { 56 | this.id = column; 57 | break; 58 | } 59 | } 60 | } 61 | 62 | public T createEntity() throws Throwable { 63 | return this.constructor.newInstance(); 64 | } 65 | 66 | public boolean tableIsExist() throws DbException { 67 | if (this.isCheckedDatabase()) { 68 | return true; 69 | } 70 | 71 | Cursor cursor = db.execQuery("SELECT COUNT(*) AS c FROM sqlite_master WHERE type='table' AND name='" + name + "'"); 72 | if (cursor != null) { 73 | try { 74 | if (cursor.moveToNext()) { 75 | int count = cursor.getInt(0); 76 | if (count > 0) { 77 | this.setCheckedDatabase(true); 78 | return true; 79 | } 80 | } 81 | } catch (Throwable e) { 82 | throw new DbException(e); 83 | } finally { 84 | IOUtil.closeQuietly(cursor); 85 | } 86 | } 87 | 88 | return false; 89 | } 90 | 91 | public DbManager getDb() { 92 | return db; 93 | } 94 | 95 | public String getName() { 96 | return name; 97 | } 98 | 99 | public Class getEntityType() { 100 | return entityType; 101 | } 102 | 103 | public String getOnCreated() { 104 | return onCreated; 105 | } 106 | 107 | public ColumnEntity getId() { 108 | return id; 109 | } 110 | 111 | public LinkedHashMap getColumnMap() { 112 | return columnMap; 113 | } 114 | 115 | /*package*/ boolean isCheckedDatabase() { 116 | return checkedDatabase; 117 | } 118 | 119 | /*package*/ void setCheckedDatabase(boolean checkedDatabase) { 120 | this.checkedDatabase = checkedDatabase; 121 | } 122 | 123 | @Override 124 | public String toString() { 125 | return name; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/db/table/TableUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.db.table; 17 | 18 | import org.xutils.common.util.LogUtil; 19 | import org.xutils.db.annotation.Column; 20 | import org.xutils.db.converter.ColumnConverterFactory; 21 | 22 | import java.lang.reflect.Field; 23 | import java.lang.reflect.Modifier; 24 | import java.util.HashMap; 25 | import java.util.LinkedHashMap; 26 | 27 | /* package */ final class TableUtils { 28 | 29 | private TableUtils() { 30 | } 31 | 32 | /* package */ 33 | static synchronized LinkedHashMap findColumnMap(Class entityType) { 34 | LinkedHashMap columnMap = new LinkedHashMap(); 35 | addColumns2Map(entityType, columnMap); 36 | return columnMap; 37 | } 38 | 39 | private static void addColumns2Map(Class entityType, HashMap columnMap) { 40 | if (Object.class.equals(entityType)) return; 41 | 42 | try { 43 | Field[] fields = entityType.getDeclaredFields(); 44 | for (Field field : fields) { 45 | int modify = field.getModifiers(); 46 | if (Modifier.isStatic(modify) || Modifier.isTransient(modify)) { 47 | continue; 48 | } 49 | Column columnAnn = field.getAnnotation(Column.class); 50 | if (columnAnn != null) { 51 | if (ColumnConverterFactory.isSupportColumnConverter(field.getType())) { 52 | ColumnEntity column = new ColumnEntity(entityType, field, columnAnn); 53 | if (!columnMap.containsKey(column.getName())) { 54 | columnMap.put(column.getName(), column); 55 | } 56 | } 57 | } 58 | } 59 | 60 | addColumns2Map(entityType.getSuperclass(), columnMap); 61 | } catch (Throwable e) { 62 | LogUtil.e(e.getMessage(), e); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/ex/BaseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.ex; 17 | 18 | import java.io.IOException; 19 | 20 | /** 21 | * Author: wyouflf 22 | * Date: 13-7-24 23 | * Time: 下午3:00 24 | */ 25 | public class BaseException extends IOException { 26 | private static final long serialVersionUID = 1L; 27 | 28 | public BaseException() { 29 | super(); 30 | } 31 | 32 | public BaseException(String detailMessage) { 33 | super(detailMessage); 34 | } 35 | 36 | public BaseException(String detailMessage, Throwable throwable) { 37 | super(detailMessage); 38 | this.initCause(throwable); 39 | } 40 | 41 | public BaseException(Throwable throwable) { 42 | super(throwable.getMessage()); 43 | this.initCause(throwable); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/ex/DbException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.ex; 17 | 18 | public class DbException extends BaseException { 19 | private static final long serialVersionUID = 1L; 20 | 21 | public DbException() { 22 | } 23 | 24 | public DbException(String detailMessage) { 25 | super(detailMessage); 26 | } 27 | 28 | public DbException(String detailMessage, Throwable throwable) { 29 | super(detailMessage, throwable); 30 | } 31 | 32 | public DbException(Throwable throwable) { 33 | super(throwable); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/ex/FileLockedException.java: -------------------------------------------------------------------------------- 1 | package org.xutils.ex; 2 | 3 | /** 4 | * Created by wyouflf on 15/10/9. 5 | */ 6 | public class FileLockedException extends BaseException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | public FileLockedException(String detailMessage) { 10 | super(detailMessage); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/ex/HttpException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.ex; 17 | 18 | import android.text.TextUtils; 19 | 20 | public class HttpException extends BaseException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | private int code; 24 | private String errorCode; 25 | private String customMessage; 26 | private String result; 27 | 28 | /** 29 | * @param code The http response status code, 0 if the http request error and has no response. 30 | * @param detailMessage The http response message. 31 | */ 32 | public HttpException(int code, String detailMessage) { 33 | super(detailMessage); 34 | this.code = code; 35 | } 36 | 37 | public void setCode(int code) { 38 | this.code = code; 39 | } 40 | 41 | public void setMessage(String message) { 42 | this.customMessage = message; 43 | } 44 | 45 | /** 46 | * @return The http response status code, 0 if the http request error and has no response. 47 | */ 48 | public int getCode() { 49 | return code; 50 | } 51 | 52 | public String getErrorCode() { 53 | return errorCode == null ? String.valueOf(code) : errorCode; 54 | } 55 | 56 | public void setErrorCode(String errorCode) { 57 | this.errorCode = errorCode; 58 | } 59 | 60 | @Override 61 | public String getMessage() { 62 | if (!TextUtils.isEmpty(customMessage)) { 63 | return customMessage; 64 | } else { 65 | return super.getMessage(); 66 | } 67 | } 68 | 69 | public String getResult() { 70 | return result; 71 | } 72 | 73 | public void setResult(String result) { 74 | this.result = result; 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return "errorCode: " + getErrorCode() + ", msg: " + getMessage() + ", result: " + result; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/ex/HttpRedirectException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.ex; 17 | 18 | public class HttpRedirectException extends HttpException { 19 | private static final long serialVersionUID = 1L; 20 | 21 | public HttpRedirectException(int code, String detailMessage, String result) { 22 | super(code, detailMessage); 23 | this.setResult(result); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/HttpManagerImpl.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http; 2 | 3 | import org.xutils.HttpManager; 4 | import org.xutils.common.Callback; 5 | import org.xutils.x; 6 | 7 | import java.lang.reflect.Type; 8 | 9 | /** 10 | * Created by wyouflf on 15/7/23. 11 | * HttpManager实现 12 | */ 13 | public final class HttpManagerImpl implements HttpManager { 14 | 15 | private static final Object lock = new Object(); 16 | private static volatile HttpManagerImpl instance; 17 | 18 | private HttpManagerImpl() { 19 | } 20 | 21 | public static void registerInstance() { 22 | if (instance == null) { 23 | synchronized (lock) { 24 | if (instance == null) { 25 | instance = new HttpManagerImpl(); 26 | } 27 | } 28 | } 29 | x.Ext.setHttpManager(instance); 30 | } 31 | 32 | @Override 33 | public Callback.Cancelable get(RequestParams entity, Callback.CommonCallback callback) { 34 | return request(HttpMethod.GET, entity, callback); 35 | } 36 | 37 | @Override 38 | public Callback.Cancelable post(RequestParams entity, Callback.CommonCallback callback) { 39 | return request(HttpMethod.POST, entity, callback); 40 | } 41 | 42 | @Override 43 | public Callback.Cancelable request(HttpMethod method, RequestParams entity, Callback.CommonCallback callback) { 44 | entity.setMethod(method); 45 | Callback.Cancelable cancelable = null; 46 | if (callback instanceof Callback.Cancelable) { 47 | cancelable = (Callback.Cancelable) callback; 48 | } 49 | HttpTask task = new HttpTask(entity, cancelable, callback); 50 | return x.task().start(task); 51 | } 52 | 53 | @Override 54 | public T getSync(RequestParams entity, Class resultType) throws Throwable { 55 | return requestSync(HttpMethod.GET, entity, resultType); 56 | } 57 | 58 | @Override 59 | public T postSync(RequestParams entity, Class resultType) throws Throwable { 60 | return requestSync(HttpMethod.POST, entity, resultType); 61 | } 62 | 63 | @Override 64 | public T requestSync(HttpMethod method, RequestParams entity, Class resultType) throws Throwable { 65 | DefaultSyncCallback callback = new DefaultSyncCallback(resultType); 66 | return requestSync(method, entity, callback); 67 | } 68 | 69 | @Override 70 | public T requestSync(HttpMethod method, RequestParams entity, Callback.TypedCallback callback) throws Throwable { 71 | entity.setMethod(method); 72 | HttpTask task = new HttpTask(entity, null, callback); 73 | return x.task().startSync(task); 74 | } 75 | 76 | private class DefaultSyncCallback implements Callback.TypedCallback { 77 | 78 | private final Class resultType; 79 | 80 | public DefaultSyncCallback(Class resultType) { 81 | this.resultType = resultType; 82 | } 83 | 84 | @Override 85 | public Type getLoadType() { 86 | return resultType; 87 | } 88 | 89 | @Override 90 | public void onSuccess(T result) { 91 | 92 | } 93 | 94 | @Override 95 | public void onError(Throwable ex, boolean isOnCallback) { 96 | 97 | } 98 | 99 | @Override 100 | public void onCancelled(CancelledException cex) { 101 | 102 | } 103 | 104 | @Override 105 | public void onFinished() { 106 | 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/HttpMethod.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http; 2 | 3 | /** 4 | * Created by wyouflf on 15/8/4. 5 | * HTTP谓词枚举 6 | */ 7 | public enum HttpMethod { 8 | GET("GET"), 9 | POST("POST"), 10 | PUT("PUT"), 11 | PATCH("PATCH"), 12 | HEAD("HEAD"), 13 | MOVE("MOVE"), 14 | COPY("COPY"), 15 | DELETE("DELETE"), 16 | OPTIONS("OPTIONS"), 17 | TRACE("TRACE"), 18 | CONNECT("CONNECT"); 19 | 20 | private final String value; 21 | 22 | HttpMethod(String value) { 23 | this.value = value; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return this.value; 29 | } 30 | 31 | public static boolean permitsRetry(HttpMethod method) { 32 | return method == GET; 33 | } 34 | 35 | public static boolean permitsCache(HttpMethod method) { 36 | return method == GET || method == POST; 37 | } 38 | 39 | public static boolean permitsRequestBody(HttpMethod method) { 40 | return method == POST 41 | || method == PUT 42 | || method == PATCH 43 | || method == DELETE; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/ProgressHandler.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http; 2 | 3 | /** 4 | * 进度控制接口, updateProgress方式中ProgressCallback#onLoading. 5 | * 默认最长间隔300毫秒调用一次. 6 | * Author: wyouflf 7 | * Time: 2014/05/23 8 | */ 9 | public interface ProgressHandler { 10 | /** 11 | * @param total 12 | * @param current 13 | * @param forceUpdateUI 14 | * @return continue 15 | */ 16 | boolean updateProgress(long total, long current, boolean forceUpdateUI); 17 | } 18 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/RequestTrackerWrapper.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http; 2 | 3 | import org.xutils.common.util.LogUtil; 4 | import org.xutils.http.app.RequestTracker; 5 | import org.xutils.http.request.UriRequest; 6 | 7 | /** 8 | * Created by wyouflf on 15/11/4. 9 | * Wrapper for tracker 10 | */ 11 | /*package*/ final class RequestTrackerWrapper implements RequestTracker { 12 | 13 | private final RequestTracker base; 14 | 15 | public RequestTrackerWrapper(RequestTracker base) { 16 | this.base = base; 17 | } 18 | 19 | @Override 20 | public void onWaiting(RequestParams params) { 21 | try { 22 | base.onWaiting(params); 23 | } catch (Throwable ex) { 24 | LogUtil.e(ex.getMessage(), ex); 25 | } 26 | } 27 | 28 | @Override 29 | public void onStart(RequestParams params) { 30 | try { 31 | base.onStart(params); 32 | } catch (Throwable ex) { 33 | LogUtil.e(ex.getMessage(), ex); 34 | } 35 | } 36 | 37 | @Override 38 | public void onRequestCreated(UriRequest request) { 39 | try { 40 | base.onRequestCreated(request); 41 | } catch (Throwable ex) { 42 | LogUtil.e(ex.getMessage(), ex); 43 | } 44 | } 45 | 46 | @Override 47 | public void onCache(UriRequest request, Object result) { 48 | try { 49 | base.onCache(request, result); 50 | } catch (Throwable ex) { 51 | LogUtil.e(ex.getMessage(), ex); 52 | } 53 | } 54 | 55 | @Override 56 | public void onSuccess(UriRequest request, Object result) { 57 | try { 58 | base.onSuccess(request, result); 59 | } catch (Throwable ex) { 60 | LogUtil.e(ex.getMessage(), ex); 61 | } 62 | } 63 | 64 | @Override 65 | public void onCancelled(UriRequest request) { 66 | try { 67 | base.onCancelled(request); 68 | } catch (Throwable ex) { 69 | LogUtil.e(ex.getMessage(), ex); 70 | } 71 | } 72 | 73 | @Override 74 | public void onError(UriRequest request, Throwable ex, boolean isCallbackError) { 75 | try { 76 | base.onError(request, ex, isCallbackError); 77 | } catch (Throwable exOnError) { 78 | LogUtil.e(exOnError.getMessage(), exOnError); 79 | } 80 | } 81 | 82 | @Override 83 | public void onFinished(UriRequest request) { 84 | try { 85 | base.onFinished(request); 86 | } catch (Throwable ex) { 87 | LogUtil.e(ex.getMessage(), ex); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/annotation/HttpRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.http.annotation; 17 | 18 | import org.xutils.http.app.DefaultParamsBuilder; 19 | import org.xutils.http.app.ParamsBuilder; 20 | 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | @Target(ElementType.TYPE) 27 | @Retention(RetentionPolicy.RUNTIME) 28 | public @interface HttpRequest { 29 | 30 | String host() default ""; 31 | 32 | String path(); 33 | 34 | Class builder() default DefaultParamsBuilder.class; 35 | 36 | String[] signs() default ""; 37 | 38 | String[] cacheKeys() default ""; 39 | } -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/annotation/HttpResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.http.annotation; 17 | 18 | import org.xutils.http.app.ResponseParser; 19 | 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | @Target(ElementType.TYPE) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface HttpResponse { 28 | 29 | Class parser(); 30 | 31 | } -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/app/DefaultParamsBuilder.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.app; 2 | 3 | import org.xutils.common.util.LogUtil; 4 | import org.xutils.http.RequestParams; 5 | import org.xutils.http.annotation.HttpRequest; 6 | 7 | import java.security.cert.X509Certificate; 8 | 9 | import javax.net.ssl.SSLContext; 10 | import javax.net.ssl.SSLSocketFactory; 11 | import javax.net.ssl.TrustManager; 12 | import javax.net.ssl.X509TrustManager; 13 | 14 | /** 15 | * Created by wyouflf on 15/8/20. 16 | * 默认参数构造器 17 | */ 18 | public class DefaultParamsBuilder implements ParamsBuilder { 19 | 20 | public DefaultParamsBuilder() { 21 | } 22 | 23 | /** 24 | * 根据@HttpRequest构建请求的url 25 | * 26 | * @param params 27 | * @param httpRequest 28 | * @return 29 | */ 30 | @Override 31 | public String buildUri(RequestParams params, HttpRequest httpRequest) throws Throwable { 32 | return httpRequest.host() + "/" + httpRequest.path(); 33 | } 34 | 35 | /** 36 | * 根据注解的cacheKeys构建缓存的自定义key, 37 | * 如果返回null, 默认使用 url 和整个 query string 组成. 38 | * 39 | * @param params 40 | * @param cacheKeys 41 | * @return 42 | */ 43 | @Override 44 | public String buildCacheKey(RequestParams params, String[] cacheKeys) { 45 | String cacheKey = null; 46 | if (cacheKeys != null && cacheKeys.length > 0) { 47 | 48 | cacheKey = params.getUri() + "?"; 49 | 50 | // 添加cacheKeys对应的参数 51 | for (String key : cacheKeys) { 52 | String value = params.getStringParameter(key); 53 | if (value != null) { 54 | cacheKey += key + "=" + value + "&"; 55 | } 56 | } 57 | } 58 | return cacheKey; 59 | } 60 | 61 | /** 62 | * 自定义SSLSocketFactory 63 | * 64 | * @return 65 | */ 66 | @Override 67 | public SSLSocketFactory getSSLSocketFactory() throws Throwable { 68 | return getTrustAllSSLSocketFactory(); 69 | } 70 | 71 | /** 72 | * 为请求添加通用参数等操作 73 | * 74 | * @param params 75 | */ 76 | @Override 77 | public void buildParams(RequestParams params) throws Throwable { 78 | } 79 | 80 | /** 81 | * 自定义参数签名 82 | * 83 | * @param params 84 | * @param signs 85 | */ 86 | @Override 87 | public void buildSign(RequestParams params, String[] signs) throws Throwable { 88 | 89 | } 90 | 91 | private static SSLSocketFactory trustAllSSlSocketFactory; 92 | 93 | public static SSLSocketFactory getTrustAllSSLSocketFactory() { 94 | if (trustAllSSlSocketFactory == null) { 95 | synchronized (DefaultParamsBuilder.class) { 96 | if (trustAllSSlSocketFactory == null) { 97 | 98 | // 信任所有证书 99 | TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { 100 | @Override 101 | public X509Certificate[] getAcceptedIssuers() { 102 | return null; 103 | } 104 | 105 | @Override 106 | public void checkClientTrusted(X509Certificate[] certs, String authType) { 107 | } 108 | 109 | @Override 110 | public void checkServerTrusted(X509Certificate[] certs, String authType) { 111 | } 112 | }}; 113 | try { 114 | SSLContext sslContext = SSLContext.getInstance("TLS"); 115 | sslContext.init(null, trustAllCerts, null); 116 | trustAllSSlSocketFactory = sslContext.getSocketFactory(); 117 | } catch (Throwable ex) { 118 | LogUtil.e(ex.getMessage(), ex); 119 | } 120 | } 121 | } 122 | } 123 | 124 | return trustAllSSlSocketFactory; 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/app/HttpRetryHandler.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.app; 2 | 3 | 4 | import org.json.JSONException; 5 | import org.xutils.common.Callback; 6 | import org.xutils.common.util.LogUtil; 7 | import org.xutils.ex.HttpException; 8 | import org.xutils.http.HttpMethod; 9 | import org.xutils.http.request.UriRequest; 10 | 11 | import java.io.FileNotFoundException; 12 | import java.net.MalformedURLException; 13 | import java.net.NoRouteToHostException; 14 | import java.net.PortUnreachableException; 15 | import java.net.ProtocolException; 16 | import java.net.URISyntaxException; 17 | import java.net.UnknownHostException; 18 | import java.util.HashSet; 19 | 20 | /** 21 | * Author: wyouflf 22 | * Time: 2014/05/30 23 | */ 24 | public class HttpRetryHandler { 25 | 26 | protected int maxRetryCount = 2; 27 | 28 | protected static HashSet> blackList = new HashSet>(); 29 | 30 | static { 31 | blackList.add(HttpException.class); 32 | blackList.add(Callback.CancelledException.class); 33 | blackList.add(MalformedURLException.class); 34 | blackList.add(URISyntaxException.class); 35 | blackList.add(NoRouteToHostException.class); 36 | blackList.add(PortUnreachableException.class); 37 | blackList.add(ProtocolException.class); 38 | blackList.add(NullPointerException.class); 39 | blackList.add(FileNotFoundException.class); 40 | blackList.add(JSONException.class); 41 | blackList.add(UnknownHostException.class); 42 | blackList.add(IllegalArgumentException.class); 43 | } 44 | 45 | public HttpRetryHandler() { 46 | } 47 | 48 | public void setMaxRetryCount(int maxRetryCount) { 49 | this.maxRetryCount = maxRetryCount; 50 | } 51 | 52 | public boolean canRetry(UriRequest request, Throwable ex, int count) { 53 | 54 | LogUtil.w(ex.getMessage(), ex); 55 | 56 | if (count > maxRetryCount) { 57 | LogUtil.w(request.toString()); 58 | LogUtil.w("The Max Retry times has been reached!"); 59 | return false; 60 | } 61 | 62 | if (!HttpMethod.permitsRetry(request.getParams().getMethod())) { 63 | LogUtil.w(request.toString()); 64 | LogUtil.w("The Request Method can not be retried."); 65 | return false; 66 | } 67 | 68 | if (blackList.contains(ex.getClass())) { 69 | LogUtil.w(request.toString()); 70 | LogUtil.w("The Exception can not be retried."); 71 | return false; 72 | } 73 | 74 | return true; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/app/InputStreamResponseParser.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.app; 2 | 3 | import java.io.InputStream; 4 | import java.lang.reflect.Type; 5 | 6 | /** 7 | * Created by wyouflf on 16/2/2. 8 | */ 9 | public abstract class InputStreamResponseParser implements ResponseParser { 10 | 11 | public abstract Object parse(Type resultType, Class resultClass, InputStream result) throws Throwable; 12 | 13 | /** 14 | * Deprecated, see {@link InputStreamResponseParser#parse(Type, Class, InputStream)} 15 | * 16 | * @throws Throwable 17 | */ 18 | @Override 19 | @Deprecated 20 | public final Object parse(Type resultType, Class resultClass, String result) throws Throwable { 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/app/ParamsBuilder.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.app; 2 | 3 | import org.xutils.http.RequestParams; 4 | import org.xutils.http.annotation.HttpRequest; 5 | 6 | import javax.net.ssl.SSLSocketFactory; 7 | 8 | /** 9 | * Created by wyouflf on 15/8/20. 10 | *

11 | * {@link org.xutils.http.annotation.HttpRequest} 注解的参数构建的模板接口 12 | */ 13 | public interface ParamsBuilder { 14 | 15 | /** 16 | * 根据@HttpRequest构建请求的url 17 | * 18 | * @param params 19 | * @param httpRequest 20 | * @return 21 | */ 22 | String buildUri(RequestParams params, HttpRequest httpRequest) throws Throwable; 23 | 24 | /** 25 | * 根据注解的cacheKeys构建缓存的自定义key, 26 | * 如果返回null, 默认使用 url 和整个 query string 组成. 27 | * 28 | * @param params 29 | * @param cacheKeys 30 | * @return 31 | */ 32 | String buildCacheKey(RequestParams params, String[] cacheKeys); 33 | 34 | /** 35 | * 自定义SSLSocketFactory 36 | * 37 | * @return 38 | */ 39 | SSLSocketFactory getSSLSocketFactory() throws Throwable; 40 | 41 | /** 42 | * 为请求添加通用参数等操作 43 | * 44 | * @param params 45 | */ 46 | void buildParams(RequestParams params) throws Throwable; 47 | 48 | /** 49 | * 自定义参数签名 50 | * 51 | * @param params 52 | * @param signs 53 | */ 54 | void buildSign(RequestParams params, String[] signs) throws Throwable; 55 | } 56 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/app/RedirectHandler.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.app; 2 | 3 | import org.xutils.http.RequestParams; 4 | import org.xutils.http.request.UriRequest; 5 | 6 | /** 7 | * Created by wyouflf on 15/11/12. 8 | * 请求重定向控制接口 9 | */ 10 | public interface RedirectHandler { 11 | 12 | /** 13 | * 根据请求信息返回自定义重定向的请求参数 14 | * 15 | * @param request 16 | * @return 返回不为null时进行重定向 17 | */ 18 | RequestParams getRedirectParams(UriRequest request) throws Throwable; 19 | } 20 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/app/RequestInterceptListener.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.app; 2 | 3 | 4 | import org.xutils.http.request.UriRequest; 5 | 6 | /** 7 | * Created by wyouflf on 15/11/10. 8 | * 拦截请求响应(在后台线程工作). 9 | *

10 | * 用法: 请求的callback参数同时实现RequestInterceptListener 11 | */ 12 | public interface RequestInterceptListener { 13 | 14 | void beforeRequest(UriRequest request) throws Throwable; 15 | 16 | void afterRequest(UriRequest request) throws Throwable; 17 | } -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/app/RequestTracker.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.app; 2 | 3 | import org.xutils.http.RequestParams; 4 | import org.xutils.http.request.UriRequest; 5 | 6 | /** 7 | * Created by wyouflf on 15/9/10. 8 | * 请求过程追踪, 适合用来记录请求日志. 9 | * 所有回调方法都在主线程进行. 10 | *

11 | * 用法: 12 | * 1. 将RequestTracker实例设置给请求参数RequestParams. 13 | * 2. 请的callback参数同时实现RequestTracker接口; 14 | * 3. 注册给UriRequestFactory的默认RequestTracker. 15 | * 注意: 请求回调RequestTracker时优先级按照上面的顺序, 16 | * 找到一个RequestTracker的实现会忽略其他. 17 | */ 18 | public interface RequestTracker { 19 | 20 | void onWaiting(RequestParams params); 21 | 22 | void onStart(RequestParams params); 23 | 24 | void onRequestCreated(UriRequest request); 25 | 26 | void onCache(UriRequest request, Object result); 27 | 28 | void onSuccess(UriRequest request, Object result); 29 | 30 | void onCancelled(UriRequest request); 31 | 32 | void onError(UriRequest request, Throwable ex, boolean isCallbackError); 33 | 34 | void onFinished(UriRequest request); 35 | } 36 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/app/ResponseParser.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.app; 2 | 3 | 4 | import org.xutils.http.request.UriRequest; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | /** 9 | * Created by wyouflf on 15/8/4. 10 | * {@link org.xutils.http.annotation.HttpResponse} 注解的返回值转换模板 11 | */ 12 | public interface ResponseParser { 13 | 14 | /** 15 | * 检查请求相应头等处理 16 | * 17 | * @param request 18 | * @throws Throwable 19 | */ 20 | void checkResponse(UriRequest request) throws Throwable; 21 | 22 | /** 23 | * 转换result为resultType类型的对象 24 | * 25 | * @param resultType 返回值类型(可能带有泛型信息) 26 | * @param resultClass 返回值类型 27 | * @param result 字符串数据 28 | * @return 29 | * @throws Throwable 30 | */ 31 | Object parse(Type resultType, Class resultClass, String result) throws Throwable; 32 | } 33 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/body/BodyItemWrapper.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.body; 2 | 3 | import android.text.TextUtils; 4 | 5 | /** 6 | * Created by wyouflf on 15/8/13. 7 | * Wrapper for RequestBody value. 8 | */ 9 | public final class BodyItemWrapper { 10 | 11 | private final Object value; 12 | private final String fileName; 13 | private final String contentType; 14 | 15 | public BodyItemWrapper(Object value, String contentType) { 16 | this(value, contentType, null); 17 | } 18 | 19 | public BodyItemWrapper(Object value, String contentType, String fileName) { 20 | this.value = value; 21 | if (TextUtils.isEmpty(contentType)) { 22 | this.contentType = "application/octet-stream"; 23 | } else { 24 | this.contentType = contentType; 25 | } 26 | this.fileName = fileName; 27 | } 28 | 29 | public Object getValue() { 30 | return value; 31 | } 32 | 33 | public String getFileName() { 34 | return fileName; 35 | } 36 | 37 | public String getContentType() { 38 | return contentType; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/body/FileBody.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.body; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.IOException; 8 | import java.net.HttpURLConnection; 9 | 10 | /** 11 | * Created by wyouflf on 15/8/13. 12 | */ 13 | public class FileBody extends InputStreamBody { 14 | 15 | private File file; 16 | private String contentType; 17 | 18 | public FileBody(File file) throws IOException { 19 | this(file, null); 20 | } 21 | 22 | public FileBody(File file, String contentType) throws IOException { 23 | super(new FileInputStream(file)); 24 | this.file = file; 25 | this.contentType = contentType; 26 | } 27 | 28 | @Override 29 | public void setContentType(String contentType) { 30 | this.contentType = contentType; 31 | } 32 | 33 | @Override 34 | public String getContentType() { 35 | if (TextUtils.isEmpty(contentType)) { 36 | contentType = getFileContentType(file); 37 | } 38 | return contentType; 39 | } 40 | 41 | public static String getFileContentType(File file) { 42 | String filename = file.getName(); 43 | String contentType = HttpURLConnection.guessContentTypeFromName(filename); 44 | if (TextUtils.isEmpty(contentType)) { 45 | contentType = "application/octet-stream"; 46 | } else { 47 | contentType = contentType.replaceFirst("\\/jpg$", "/jpeg"); 48 | } 49 | return contentType; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/body/InputStreamBody.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.body; 2 | 3 | import android.text.TextUtils; 4 | 5 | import org.xutils.common.Callback; 6 | import org.xutils.common.util.IOUtil; 7 | import org.xutils.http.ProgressHandler; 8 | 9 | import java.io.ByteArrayInputStream; 10 | import java.io.FileInputStream; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.io.OutputStream; 14 | 15 | 16 | /** 17 | * Author: wyouflf 18 | * Time: 2014/05/30 19 | */ 20 | public class InputStreamBody implements ProgressBody { 21 | 22 | private InputStream content; 23 | private String contentType; 24 | 25 | private final long total; 26 | private long current = 0; 27 | 28 | private ProgressHandler callBackHandler; 29 | 30 | public InputStreamBody(InputStream inputStream) { 31 | this(inputStream, null); 32 | } 33 | 34 | public InputStreamBody(InputStream inputStream, String contentType) { 35 | this.content = inputStream; 36 | this.contentType = contentType; 37 | this.total = getInputStreamLength(inputStream); 38 | } 39 | 40 | @Override 41 | public void setProgressHandler(ProgressHandler progressHandler) { 42 | this.callBackHandler = progressHandler; 43 | } 44 | 45 | @Override 46 | public long getContentLength() { 47 | return total; 48 | } 49 | 50 | @Override 51 | public void setContentType(String contentType) { 52 | this.contentType = contentType; 53 | } 54 | 55 | @Override 56 | public String getContentType() { 57 | return TextUtils.isEmpty(contentType) ? "application/octet-stream" : contentType; 58 | } 59 | 60 | @Override 61 | public void writeTo(OutputStream out) throws IOException { 62 | if (callBackHandler != null && !callBackHandler.updateProgress(total, current, true)) { 63 | throw new Callback.CancelledException("upload stopped!"); 64 | } 65 | 66 | byte[] buffer = new byte[1024]; 67 | try { 68 | int len = 0; 69 | while ((len = content.read(buffer)) != -1) { 70 | out.write(buffer, 0, len); 71 | current += len; 72 | if (callBackHandler != null && !callBackHandler.updateProgress(total, current, false)) { 73 | throw new Callback.CancelledException("upload stopped!"); 74 | } 75 | } 76 | out.flush(); 77 | 78 | if (callBackHandler != null) { 79 | callBackHandler.updateProgress(total, total, true); 80 | } 81 | } finally { 82 | IOUtil.closeQuietly(content); 83 | } 84 | } 85 | 86 | public static long getInputStreamLength(InputStream inputStream) { 87 | try { 88 | if (inputStream instanceof FileInputStream || 89 | inputStream instanceof ByteArrayInputStream) { 90 | return inputStream.available(); 91 | } 92 | } catch (Throwable ignored) { 93 | } 94 | return -1L; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/body/ProgressBody.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.body; 2 | 3 | 4 | import org.xutils.http.ProgressHandler; 5 | 6 | /** 7 | * Created by wyouflf on 15/8/13. 8 | */ 9 | public interface ProgressBody extends RequestBody { 10 | void setProgressHandler(ProgressHandler progressHandler); 11 | } 12 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/body/RequestBody.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.body; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | /** 7 | * Created by wyouflf on 15/10/29. 8 | */ 9 | public interface RequestBody { 10 | 11 | long getContentLength(); 12 | 13 | void setContentType(String contentType); 14 | 15 | String getContentType(); 16 | 17 | void writeTo(OutputStream out) throws IOException; 18 | } 19 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/body/StringBody.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.body; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.io.IOException; 6 | import java.io.OutputStream; 7 | import java.io.UnsupportedEncodingException; 8 | 9 | /** 10 | * Author: wyouflf 11 | * Time: 2014/05/30 12 | */ 13 | public class StringBody implements RequestBody { 14 | 15 | private byte[] content; 16 | private String contentType; 17 | private String charset = "UTF-8"; 18 | 19 | public StringBody(String str, String charset) throws UnsupportedEncodingException { 20 | if (!TextUtils.isEmpty(charset)) { 21 | this.charset = charset; 22 | } 23 | this.content = str.getBytes(this.charset); 24 | } 25 | 26 | @Override 27 | public long getContentLength() { 28 | return content.length; 29 | } 30 | 31 | @Override 32 | public void setContentType(String contentType) { 33 | this.contentType = contentType; 34 | } 35 | 36 | @Override 37 | public String getContentType() { 38 | return TextUtils.isEmpty(contentType) ? "application/json;charset=" + charset : contentType; 39 | } 40 | 41 | @Override 42 | public void writeTo(OutputStream out) throws IOException { 43 | out.write(content); 44 | out.flush(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/body/UrlEncodedParamsBody.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.body; 2 | 3 | import android.net.Uri; 4 | import android.text.TextUtils; 5 | 6 | import org.xutils.common.util.KeyValue; 7 | 8 | import java.io.IOException; 9 | import java.io.OutputStream; 10 | import java.util.List; 11 | 12 | /** 13 | * Author: wyouflf 14 | * Time: 2014/05/30 15 | */ 16 | public class UrlEncodedParamsBody implements RequestBody { 17 | 18 | private byte[] content; 19 | private String charset = "UTF-8"; 20 | 21 | public UrlEncodedParamsBody(List params, String charset) throws IOException { 22 | if (!TextUtils.isEmpty(charset)) { 23 | this.charset = charset; 24 | } 25 | StringBuilder contentSb = new StringBuilder(); 26 | if (params != null) { 27 | for (KeyValue kv : params) { 28 | String name = kv.key; 29 | String value = kv.getValueStr(); 30 | if (!TextUtils.isEmpty(name) && value != null) { 31 | if (contentSb.length() > 0) { 32 | contentSb.append("&"); 33 | } 34 | contentSb.append(Uri.encode(name, this.charset)) 35 | .append("=") 36 | .append(Uri.encode(value, this.charset)); 37 | } 38 | } 39 | } 40 | 41 | this.content = contentSb.toString().getBytes(this.charset); 42 | } 43 | 44 | @Override 45 | public long getContentLength() { 46 | return content.length; 47 | } 48 | 49 | @Override 50 | public void setContentType(String contentType) { 51 | } 52 | 53 | @Override 54 | public String getContentType() { 55 | return "application/x-www-form-urlencoded;charset=" + charset; 56 | } 57 | 58 | @Override 59 | public void writeTo(OutputStream sink) throws IOException { 60 | sink.write(this.content); 61 | sink.flush(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/cookie/CookieEntity.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.cookie; 2 | 3 | import android.text.TextUtils; 4 | 5 | import org.xutils.db.annotation.Column; 6 | import org.xutils.db.annotation.Table; 7 | 8 | import java.net.HttpCookie; 9 | import java.net.URI; 10 | 11 | /** 12 | * Created by wyouflf on 15/8/20. 13 | * 数据库中的cookie实体 14 | */ 15 | @Table(name = "cookie", 16 | onCreated = "CREATE UNIQUE INDEX index_cookie_unique ON cookie(\"name\",\"domain\",\"path\")") 17 | /*package*/ final class CookieEntity { 18 | 19 | // ~ 100 year 20 | private static final long MAX_EXPIRY = System.currentTimeMillis() + 1000L * 60L * 60L * 24L * 30L * 12L * 100L; 21 | 22 | @Column(name = "id", isId = true) 23 | private long id; 24 | 25 | @Column(name = "uri") 26 | private String uri; // cookie add by this uri. 27 | 28 | @Column(name = "name") 29 | private String name; 30 | @Column(name = "value") 31 | private String value; 32 | @Column(name = "comment") 33 | private String comment; 34 | @Column(name = "commentURL") 35 | private String commentURL; 36 | @Column(name = "discard") 37 | private boolean discard; 38 | @Column(name = "domain") 39 | private String domain; 40 | @Column(name = "expiry") 41 | private long expiry = MAX_EXPIRY; 42 | @Column(name = "path") 43 | private String path; 44 | @Column(name = "portList") 45 | private String portList; 46 | @Column(name = "secure") 47 | private boolean secure; 48 | @Column(name = "version") 49 | private int version = 1; 50 | 51 | public CookieEntity() { 52 | } 53 | 54 | public CookieEntity(URI uri, HttpCookie cookie) { 55 | this.uri = uri == null ? null : uri.toString(); 56 | this.name = cookie.getName(); 57 | this.value = cookie.getValue(); 58 | this.comment = cookie.getComment(); 59 | this.commentURL = cookie.getCommentURL(); 60 | this.discard = cookie.getDiscard(); 61 | this.domain = cookie.getDomain(); 62 | long maxAge = cookie.getMaxAge(); 63 | if (maxAge != -1L && maxAge > 0) { 64 | this.expiry = (maxAge * 1000L) + System.currentTimeMillis(); 65 | if (this.expiry < 0L) { // 计算溢出? 66 | this.expiry = MAX_EXPIRY; 67 | } 68 | } else { 69 | this.expiry = -1L; 70 | } 71 | this.path = cookie.getPath(); 72 | if (!TextUtils.isEmpty(path) && path.length() > 1 && path.endsWith("/")) { 73 | this.path = path.substring(0, path.length() - 1); 74 | } 75 | this.portList = cookie.getPortlist(); 76 | this.secure = cookie.getSecure(); 77 | this.version = cookie.getVersion(); 78 | } 79 | 80 | public HttpCookie toHttpCookie() { 81 | HttpCookie cookie = new HttpCookie(name, value); 82 | cookie.setComment(comment); 83 | cookie.setCommentURL(commentURL); 84 | cookie.setDiscard(discard); 85 | cookie.setDomain(domain); 86 | if (expiry == -1L) { 87 | cookie.setMaxAge(-1L); 88 | } else { 89 | cookie.setMaxAge((expiry - System.currentTimeMillis()) / 1000L); 90 | } 91 | cookie.setPath(path); 92 | cookie.setPortlist(portList); 93 | cookie.setSecure(secure); 94 | cookie.setVersion(version); 95 | return cookie; 96 | } 97 | 98 | public long getId() { 99 | return id; 100 | } 101 | 102 | public void setId(long id) { 103 | this.id = id; 104 | } 105 | 106 | public String getUri() { 107 | return uri; 108 | } 109 | 110 | public void setUri(String uri) { 111 | this.uri = uri; 112 | } 113 | 114 | public boolean isExpired() { 115 | return expiry != -1L && expiry < System.currentTimeMillis(); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/loader/BooleanLoader.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.loader; 2 | 3 | import org.xutils.cache.DiskCacheEntity; 4 | import org.xutils.http.request.UriRequest; 5 | 6 | import java.io.InputStream; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Time: 2014/05/30 11 | */ 12 | /*package*/ class BooleanLoader extends Loader { 13 | 14 | @Override 15 | public Loader newInstance() { 16 | return new BooleanLoader(); 17 | } 18 | 19 | @Override 20 | public Boolean load(final InputStream in) throws Throwable { 21 | return false; 22 | } 23 | 24 | @Override 25 | public Boolean load(final UriRequest request) throws Throwable { 26 | request.sendRequest(); 27 | return request.getResponseCode() < 300; 28 | } 29 | 30 | @Override 31 | public Boolean loadFromCache(final DiskCacheEntity cacheEntity) throws Throwable { 32 | return null; 33 | } 34 | 35 | @Override 36 | public void save2Cache(final UriRequest request) { 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/loader/ByteArrayLoader.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.loader; 2 | 3 | import org.xutils.cache.DiskCacheEntity; 4 | import org.xutils.common.util.IOUtil; 5 | import org.xutils.http.request.UriRequest; 6 | 7 | import java.io.InputStream; 8 | 9 | /** 10 | * Author: wyouflf 11 | * Time: 2014/05/30 12 | */ 13 | /*package*/ class ByteArrayLoader extends Loader { 14 | 15 | @Override 16 | public Loader newInstance() { 17 | return new ByteArrayLoader(); 18 | } 19 | 20 | @Override 21 | public byte[] load(final InputStream in) throws Throwable { 22 | return IOUtil.readBytes(in); 23 | } 24 | 25 | @Override 26 | public byte[] load(final UriRequest request) throws Throwable { 27 | request.sendRequest(); 28 | return this.load(request.getInputStream()); 29 | } 30 | 31 | @Override 32 | public byte[] loadFromCache(final DiskCacheEntity cacheEntity) throws Throwable { 33 | return null; 34 | } 35 | 36 | @Override 37 | public void save2Cache(final UriRequest request) { 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/loader/IntegerLoader.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.loader; 2 | 3 | import org.xutils.cache.DiskCacheEntity; 4 | import org.xutils.http.request.UriRequest; 5 | 6 | import java.io.InputStream; 7 | 8 | /** 9 | * @author: wyouflf 10 | * @date: 2014/10/17 11 | */ 12 | /*package*/ class IntegerLoader extends Loader { 13 | @Override 14 | public Loader newInstance() { 15 | return new IntegerLoader(); 16 | } 17 | 18 | @Override 19 | public Integer load(InputStream in) throws Throwable { 20 | return 100; 21 | } 22 | 23 | @Override 24 | public Integer load(UriRequest request) throws Throwable { 25 | request.sendRequest(); 26 | return request.getResponseCode(); 27 | } 28 | 29 | @Override 30 | public Integer loadFromCache(final DiskCacheEntity cacheEntity) throws Throwable { 31 | return null; 32 | } 33 | 34 | @Override 35 | public void save2Cache(UriRequest request) { 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/loader/JSONArrayLoader.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.loader; 2 | 3 | import android.text.TextUtils; 4 | 5 | import org.json.JSONArray; 6 | import org.xutils.cache.DiskCacheEntity; 7 | import org.xutils.common.util.IOUtil; 8 | import org.xutils.http.RequestParams; 9 | import org.xutils.http.request.UriRequest; 10 | 11 | import java.io.InputStream; 12 | 13 | /** 14 | * Author: wyouflf 15 | * Time: 2014/06/16 16 | */ 17 | /*package*/ class JSONArrayLoader extends Loader { 18 | 19 | private String charset = "UTF-8"; 20 | private String resultStr = null; 21 | 22 | @Override 23 | public Loader newInstance() { 24 | return new JSONArrayLoader(); 25 | } 26 | 27 | @Override 28 | public void setParams(final RequestParams params) { 29 | if (params != null) { 30 | String charset = params.getCharset(); 31 | if (!TextUtils.isEmpty(charset)) { 32 | this.charset = charset; 33 | } 34 | } 35 | } 36 | 37 | @Override 38 | public JSONArray load(final InputStream in) throws Throwable { 39 | resultStr = IOUtil.readStr(in, charset); 40 | return new JSONArray(resultStr); 41 | } 42 | 43 | @Override 44 | public JSONArray load(final UriRequest request) throws Throwable { 45 | request.sendRequest(); 46 | return this.load(request.getInputStream()); 47 | } 48 | 49 | @Override 50 | public JSONArray loadFromCache(final DiskCacheEntity cacheEntity) throws Throwable { 51 | if (cacheEntity != null) { 52 | String text = cacheEntity.getTextContent(); 53 | if (!TextUtils.isEmpty(text)) { 54 | return new JSONArray(text); 55 | } 56 | } 57 | 58 | return null; 59 | } 60 | 61 | @Override 62 | public void save2Cache(UriRequest request) { 63 | saveStringCache(request, resultStr); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/loader/JSONObjectLoader.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.loader; 2 | 3 | import android.text.TextUtils; 4 | 5 | import org.json.JSONObject; 6 | import org.xutils.cache.DiskCacheEntity; 7 | import org.xutils.common.util.IOUtil; 8 | import org.xutils.http.RequestParams; 9 | import org.xutils.http.request.UriRequest; 10 | 11 | import java.io.InputStream; 12 | 13 | /** 14 | * Author: wyouflf 15 | * Time: 2014/06/16 16 | */ 17 | /*package*/ class JSONObjectLoader extends Loader { 18 | 19 | private String charset = "UTF-8"; 20 | private String resultStr = null; 21 | 22 | @Override 23 | public Loader newInstance() { 24 | return new JSONObjectLoader(); 25 | } 26 | 27 | @Override 28 | public void setParams(final RequestParams params) { 29 | if (params != null) { 30 | String charset = params.getCharset(); 31 | if (!TextUtils.isEmpty(charset)) { 32 | this.charset = charset; 33 | } 34 | } 35 | } 36 | 37 | @Override 38 | public JSONObject load(final InputStream in) throws Throwable { 39 | resultStr = IOUtil.readStr(in, charset); 40 | return new JSONObject(resultStr); 41 | } 42 | 43 | @Override 44 | public JSONObject load(final UriRequest request) throws Throwable { 45 | request.sendRequest(); 46 | return this.load(request.getInputStream()); 47 | } 48 | 49 | @Override 50 | public JSONObject loadFromCache(final DiskCacheEntity cacheEntity) throws Throwable { 51 | if (cacheEntity != null) { 52 | String text = cacheEntity.getTextContent(); 53 | if (!TextUtils.isEmpty(text)) { 54 | return new JSONObject(text); 55 | } 56 | } 57 | 58 | return null; 59 | } 60 | 61 | @Override 62 | public void save2Cache(UriRequest request) { 63 | saveStringCache(request, resultStr); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/loader/Loader.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.loader; 2 | 3 | 4 | import android.text.TextUtils; 5 | 6 | import org.xutils.cache.DiskCacheEntity; 7 | import org.xutils.cache.LruDiskCache; 8 | import org.xutils.http.ProgressHandler; 9 | import org.xutils.http.RequestParams; 10 | import org.xutils.http.request.UriRequest; 11 | 12 | import java.io.InputStream; 13 | import java.util.Date; 14 | 15 | /** 16 | * Author: wyouflf 17 | * Time: 2014/05/26 18 | */ 19 | public abstract class Loader { 20 | 21 | protected RequestParams params; 22 | protected ProgressHandler progressHandler; 23 | 24 | public void setParams(final RequestParams params) { 25 | this.params = params; 26 | } 27 | 28 | public void setProgressHandler(final ProgressHandler callbackHandler) { 29 | this.progressHandler = callbackHandler; 30 | } 31 | 32 | protected void saveStringCache(UriRequest request, String resultStr) { 33 | if (!TextUtils.isEmpty(resultStr)) { 34 | DiskCacheEntity entity = new DiskCacheEntity(); 35 | entity.setKey(request.getCacheKey()); 36 | entity.setLastAccess(System.currentTimeMillis()); 37 | entity.setEtag(request.getETag()); 38 | entity.setExpires(request.getExpiration()); 39 | entity.setLastModify(new Date(request.getLastModified())); 40 | entity.setTextContent(resultStr); 41 | LruDiskCache.getDiskCache(request.getParams().getCacheDirName()).put(entity); 42 | } 43 | } 44 | 45 | public abstract Loader newInstance(); 46 | 47 | public abstract T load(final InputStream in) throws Throwable; 48 | 49 | public abstract T load(final UriRequest request) throws Throwable; 50 | 51 | public abstract T loadFromCache(final DiskCacheEntity cacheEntity) throws Throwable; 52 | 53 | public abstract void save2Cache(final UriRequest request); 54 | } 55 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/loader/LoaderFactory.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.loader; 2 | 3 | 4 | import org.json.JSONArray; 5 | import org.json.JSONObject; 6 | import org.xutils.http.RequestParams; 7 | 8 | import java.io.File; 9 | import java.lang.reflect.Type; 10 | import java.util.HashMap; 11 | 12 | /** 13 | * Author: wyouflf 14 | * Time: 2014/05/26 15 | */ 16 | public final class LoaderFactory { 17 | 18 | private LoaderFactory() { 19 | } 20 | 21 | /** 22 | * key: loadType 23 | */ 24 | private static final HashMap converterHashMap = new HashMap(); 25 | 26 | static { 27 | converterHashMap.put(JSONObject.class, new JSONObjectLoader()); 28 | converterHashMap.put(JSONArray.class, new JSONArrayLoader()); 29 | converterHashMap.put(String.class, new StringLoader()); 30 | converterHashMap.put(File.class, new FileLoader()); 31 | converterHashMap.put(byte[].class, new ByteArrayLoader()); 32 | BooleanLoader booleanLoader = new BooleanLoader(); 33 | converterHashMap.put(boolean.class, booleanLoader); 34 | converterHashMap.put(Boolean.class, booleanLoader); 35 | IntegerLoader integerLoader = new IntegerLoader(); 36 | converterHashMap.put(int.class, integerLoader); 37 | converterHashMap.put(Integer.class, integerLoader); 38 | } 39 | 40 | @SuppressWarnings("unchecked") 41 | public static Loader getLoader(Type type, RequestParams params) { 42 | Loader result = converterHashMap.get(type); 43 | if (result == null) { 44 | result = new ObjectLoader(type); 45 | } else { 46 | result = result.newInstance(); 47 | } 48 | result.setParams(params); 49 | return result; 50 | } 51 | 52 | public static void registerLoader(Type type, Loader loader) { 53 | converterHashMap.put(type, loader); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/loader/StringLoader.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.loader; 2 | 3 | import android.text.TextUtils; 4 | 5 | import org.xutils.cache.DiskCacheEntity; 6 | import org.xutils.common.util.IOUtil; 7 | import org.xutils.http.RequestParams; 8 | import org.xutils.http.request.UriRequest; 9 | 10 | import java.io.InputStream; 11 | 12 | /** 13 | * Author: wyouflf 14 | * Time: 2014/05/30 15 | */ 16 | /*package*/ class StringLoader extends Loader { 17 | 18 | private String charset = "UTF-8"; 19 | private String resultStr = null; 20 | 21 | @Override 22 | public Loader newInstance() { 23 | return new StringLoader(); 24 | } 25 | 26 | @Override 27 | public void setParams(final RequestParams params) { 28 | if (params != null) { 29 | String charset = params.getCharset(); 30 | if (!TextUtils.isEmpty(charset)) { 31 | this.charset = charset; 32 | } 33 | } 34 | } 35 | 36 | @Override 37 | public String load(final InputStream in) throws Throwable { 38 | resultStr = IOUtil.readStr(in, charset); 39 | return resultStr; 40 | } 41 | 42 | @Override 43 | public String load(final UriRequest request) throws Throwable { 44 | request.sendRequest(); 45 | return this.load(request.getInputStream()); 46 | } 47 | 48 | @Override 49 | public String loadFromCache(final DiskCacheEntity cacheEntity) throws Throwable { 50 | if (cacheEntity != null) { 51 | return cacheEntity.getTextContent(); 52 | } 53 | 54 | return null; 55 | } 56 | 57 | @Override 58 | public void save2Cache(UriRequest request) { 59 | saveStringCache(request, resultStr); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/request/AssetsRequest.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.request; 2 | 3 | import org.xutils.cache.DiskCacheEntity; 4 | import org.xutils.cache.LruDiskCache; 5 | import org.xutils.common.util.IOUtil; 6 | import org.xutils.common.util.LogUtil; 7 | import org.xutils.http.RequestParams; 8 | import org.xutils.x; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.lang.reflect.Type; 14 | import java.util.Date; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | /** 19 | * Created by wyouflf on 15/11/4. 20 | * Assets资源文件请求 21 | */ 22 | public class AssetsRequest extends UriRequest { 23 | 24 | private long contentLength = 0; 25 | private InputStream inputStream; 26 | 27 | public AssetsRequest(RequestParams params, Type loadType) throws Throwable { 28 | super(params, loadType); 29 | } 30 | 31 | @Override 32 | public void sendRequest() throws Throwable { 33 | 34 | } 35 | 36 | @Override 37 | public boolean isLoading() { 38 | return true; 39 | } 40 | 41 | @Override 42 | public String getCacheKey() { 43 | return queryUrl; 44 | } 45 | 46 | @Override 47 | public Object loadResult() throws Throwable { 48 | return this.loader.load(this); 49 | } 50 | 51 | @Override 52 | public Object loadResultFromCache() throws Throwable { 53 | DiskCacheEntity cacheEntity = LruDiskCache.getDiskCache(params.getCacheDirName()) 54 | .setMaxSize(params.getCacheSize()) 55 | .get(this.getCacheKey()); 56 | 57 | if (cacheEntity != null) { 58 | Date lastModifiedDate = cacheEntity.getLastModify(); 59 | if (lastModifiedDate == null || lastModifiedDate.getTime() < getAssetsLastModified()) { 60 | return null; 61 | } 62 | return loader.loadFromCache(cacheEntity); 63 | } else { 64 | return null; 65 | } 66 | } 67 | 68 | @Override 69 | public void clearCacheHeader() { 70 | 71 | } 72 | 73 | @Override 74 | public InputStream getInputStream() throws IOException { 75 | if (inputStream == null) { 76 | if (callingClassLoader != null) { 77 | String assetsPath = "assets/" + queryUrl.substring("assets://".length()); 78 | inputStream = callingClassLoader.getResourceAsStream(assetsPath); 79 | contentLength = inputStream.available(); 80 | } 81 | } 82 | return inputStream; 83 | } 84 | 85 | @Override 86 | public void close() throws IOException { 87 | IOUtil.closeQuietly(inputStream); 88 | inputStream = null; 89 | } 90 | 91 | @Override 92 | public long getContentLength() { 93 | try { 94 | getInputStream(); 95 | return contentLength; 96 | } catch (Throwable ex) { 97 | LogUtil.e(ex.getMessage(), ex); 98 | } 99 | return 0; 100 | } 101 | 102 | @Override 103 | public int getResponseCode() throws IOException { 104 | return getInputStream() != null ? 200 : 404; 105 | } 106 | 107 | @Override 108 | public String getResponseMessage() throws IOException { 109 | return null; 110 | } 111 | 112 | @Override 113 | public long getExpiration() { 114 | return Long.MAX_VALUE; 115 | } 116 | 117 | @Override 118 | public long getLastModified() { 119 | return getAssetsLastModified(); 120 | } 121 | 122 | @Override 123 | public String getETag() { 124 | return null; 125 | } 126 | 127 | @Override 128 | public String getResponseHeader(String name) { 129 | return null; 130 | } 131 | 132 | @Override 133 | public Map> getResponseHeaders() { 134 | return null; 135 | } 136 | 137 | @Override 138 | public long getHeaderFieldDate(String name, long defaultValue) { 139 | return defaultValue; 140 | } 141 | 142 | /** 143 | * 如果你的应用基于插件架构, 并且插件有独立的资源管理实现, 可能需要覆盖这里的实现方式, 144 | * 并在UriRequestFactory中注册你的实现. 145 | */ 146 | protected long getAssetsLastModified() { 147 | return new File(x.app().getApplicationInfo().sourceDir).lastModified(); 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/request/LocalFileRequest.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.request; 2 | 3 | import org.xutils.common.util.IOUtil; 4 | import org.xutils.http.RequestParams; 5 | import org.xutils.http.loader.FileLoader; 6 | 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.lang.reflect.Type; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | /** 16 | * Created by wyouflf on 15/11/4. 17 | * 本地文件请求 18 | */ 19 | public class LocalFileRequest extends UriRequest { 20 | 21 | private InputStream inputStream; 22 | 23 | LocalFileRequest(RequestParams params, Type loadType) throws Throwable { 24 | super(params, loadType); 25 | } 26 | 27 | @Override 28 | public void sendRequest() throws Throwable { 29 | 30 | } 31 | 32 | @Override 33 | public boolean isLoading() { 34 | return true; 35 | } 36 | 37 | @Override 38 | public String getCacheKey() { 39 | return null; 40 | } 41 | 42 | @Override 43 | public Object loadResult() throws Throwable { 44 | if (loader instanceof FileLoader) { 45 | return getFile(); 46 | } 47 | return this.loader.load(this); 48 | } 49 | 50 | @Override 51 | public Object loadResultFromCache() throws Throwable { 52 | return null; 53 | } 54 | 55 | @Override 56 | public void clearCacheHeader() { 57 | 58 | } 59 | 60 | @Override 61 | public void save2Cache() { 62 | 63 | } 64 | 65 | private File getFile() { 66 | String filePath = null; 67 | if (queryUrl.startsWith("file:")) { 68 | filePath = queryUrl.substring("file:".length()); 69 | } else { 70 | filePath = queryUrl; 71 | } 72 | // filePath开始位置多余的"/"或被自动去掉 73 | return new File(filePath); 74 | } 75 | 76 | @Override 77 | public InputStream getInputStream() throws IOException { 78 | if (inputStream == null) { 79 | inputStream = new FileInputStream(getFile()); 80 | } 81 | return inputStream; 82 | } 83 | 84 | @Override 85 | public void close() throws IOException { 86 | IOUtil.closeQuietly(inputStream); 87 | inputStream = null; 88 | } 89 | 90 | @Override 91 | public long getContentLength() { 92 | return getFile().length(); 93 | } 94 | 95 | @Override 96 | public int getResponseCode() throws IOException { 97 | return getFile().exists() ? 200 : 404; 98 | } 99 | 100 | @Override 101 | public String getResponseMessage() throws IOException { 102 | return null; 103 | } 104 | 105 | @Override 106 | public long getExpiration() { 107 | return -1; 108 | } 109 | 110 | @Override 111 | public long getLastModified() { 112 | return getFile().lastModified(); 113 | } 114 | 115 | @Override 116 | public String getETag() { 117 | return null; 118 | } 119 | 120 | @Override 121 | public String getResponseHeader(String name) { 122 | return null; 123 | } 124 | 125 | @Override 126 | public Map> getResponseHeaders() { 127 | return null; 128 | } 129 | 130 | @Override 131 | public long getHeaderFieldDate(String name, long defaultValue) { 132 | return defaultValue; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/request/UriRequest.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.request; 2 | 3 | import org.xutils.common.util.LogUtil; 4 | import org.xutils.http.ProgressHandler; 5 | import org.xutils.http.RequestParams; 6 | import org.xutils.http.app.RequestInterceptListener; 7 | import org.xutils.http.loader.Loader; 8 | import org.xutils.http.loader.LoaderFactory; 9 | import org.xutils.x; 10 | 11 | import java.io.Closeable; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.lang.reflect.Type; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | /** 19 | * Created by wyouflf on 15/7/23. 20 | * Uri请求发送和数据接收 21 | */ 22 | public abstract class UriRequest implements Closeable { 23 | 24 | protected final String queryUrl; 25 | protected final RequestParams params; 26 | protected final Loader loader; 27 | 28 | protected ClassLoader callingClassLoader = null; 29 | protected ProgressHandler progressHandler = null; 30 | protected RequestInterceptListener requestInterceptListener = null; 31 | 32 | /*package*/ UriRequest(RequestParams params, Type loadType) throws Throwable { 33 | this.params = params; 34 | this.queryUrl = buildQueryUrl(params); 35 | this.loader = LoaderFactory.getLoader(loadType, params); 36 | } 37 | 38 | // build query 39 | protected String buildQueryUrl(RequestParams params) { 40 | return params.getUri(); 41 | } 42 | 43 | public void setProgressHandler(ProgressHandler progressHandler) { 44 | this.progressHandler = progressHandler; 45 | this.loader.setProgressHandler(progressHandler); 46 | } 47 | 48 | public void setCallingClassLoader(ClassLoader callingClassLoader) { 49 | this.callingClassLoader = callingClassLoader; 50 | } 51 | 52 | public void setRequestInterceptListener(RequestInterceptListener requestInterceptListener) { 53 | this.requestInterceptListener = requestInterceptListener; 54 | } 55 | 56 | public RequestParams getParams() { 57 | return params; 58 | } 59 | 60 | public String getRequestUri() { 61 | return queryUrl; 62 | } 63 | 64 | /** 65 | * invoke via Loader 66 | * 67 | * @throws IOException 68 | */ 69 | public abstract void sendRequest() throws Throwable; 70 | 71 | public abstract boolean isLoading(); 72 | 73 | public abstract String getCacheKey(); 74 | 75 | /** 76 | * 由loader发起请求, 拿到结果. 77 | * 78 | * @return 79 | * @throws Throwable 80 | */ 81 | public Object loadResult() throws Throwable { 82 | return this.loader.load(this); 83 | } 84 | 85 | /** 86 | * 尝试从缓存获取结果, 并为请求头加入缓存控制参数. 87 | * 88 | * @return 89 | * @throws Throwable 90 | */ 91 | public abstract Object loadResultFromCache() throws Throwable; 92 | 93 | public abstract void clearCacheHeader(); 94 | 95 | public void save2Cache() { 96 | x.task().run(new Runnable() { 97 | @Override 98 | public void run() { 99 | try { 100 | loader.save2Cache(UriRequest.this); 101 | } catch (Throwable ex) { 102 | LogUtil.e(ex.getMessage(), ex); 103 | } 104 | } 105 | }); 106 | } 107 | 108 | public abstract InputStream getInputStream() throws IOException; 109 | 110 | @Override 111 | public abstract void close() throws IOException; 112 | 113 | public abstract long getContentLength(); 114 | 115 | public abstract int getResponseCode() throws IOException; 116 | 117 | public abstract String getResponseMessage() throws IOException; 118 | 119 | public abstract long getExpiration(); 120 | 121 | public abstract long getLastModified(); 122 | 123 | public abstract String getETag(); 124 | 125 | public abstract String getResponseHeader(String name); 126 | 127 | public abstract Map> getResponseHeaders(); 128 | 129 | public abstract long getHeaderFieldDate(String name, long defaultValue); 130 | 131 | @Override 132 | public String toString() { 133 | return getRequestUri(); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/http/request/UriRequestFactory.java: -------------------------------------------------------------------------------- 1 | package org.xutils.http.request; 2 | 3 | import android.text.TextUtils; 4 | 5 | import org.xutils.common.util.LogUtil; 6 | import org.xutils.http.RequestParams; 7 | import org.xutils.http.app.RequestTracker; 8 | 9 | import java.lang.reflect.Constructor; 10 | import java.lang.reflect.Type; 11 | import java.util.HashMap; 12 | 13 | /** 14 | * Created by wyouflf on 15/11/4. 15 | * Uri请求创建工厂 16 | */ 17 | public final class UriRequestFactory { 18 | 19 | private static Class defaultTrackerCls; 20 | 21 | private static final HashMap> 22 | SCHEME_CLS_MAP = new HashMap>(); 23 | 24 | private UriRequestFactory() { 25 | } 26 | 27 | public static UriRequest getUriRequest(RequestParams params, Type loadType) throws Throwable { 28 | 29 | // get scheme 30 | String scheme = null; 31 | String uri = params.getUri(); 32 | int index = uri.indexOf(":"); 33 | if (index > 0) { 34 | scheme = uri.substring(0, index); 35 | } else if (uri.startsWith("/")) { 36 | scheme = "file"; 37 | } 38 | 39 | // get UriRequest 40 | if (!TextUtils.isEmpty(scheme)) { 41 | Class cls = SCHEME_CLS_MAP.get(scheme); 42 | if (cls != null) { 43 | Constructor constructor 44 | = cls.getConstructor(RequestParams.class, Class.class); 45 | return constructor.newInstance(params, loadType); 46 | } else { 47 | if (scheme.startsWith("http")) { 48 | return new HttpRequest(params, loadType); 49 | } else if (scheme.equals("assets")) { 50 | return new AssetsRequest(params, loadType); 51 | } else if (scheme.equals("file")) { 52 | return new LocalFileRequest(params, loadType); 53 | } else { 54 | throw new IllegalArgumentException("The url not be support: " + uri); 55 | } 56 | } 57 | } else { 58 | throw new IllegalArgumentException("The url not be support: " + uri); 59 | } 60 | } 61 | 62 | public static void registerDefaultTrackerClass(Class trackerCls) { 63 | UriRequestFactory.defaultTrackerCls = trackerCls; 64 | } 65 | 66 | public static RequestTracker getDefaultTracker() { 67 | try { 68 | return defaultTrackerCls == null ? null : defaultTrackerCls.newInstance(); 69 | } catch (Throwable ex) { 70 | LogUtil.e(ex.getMessage(), ex); 71 | } 72 | return null; 73 | } 74 | 75 | public static void registerRequestClass(String scheme, Class uriRequestCls) { 76 | SCHEME_CLS_MAP.put(scheme, uriRequestCls); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/image/GifDrawable.java: -------------------------------------------------------------------------------- 1 | package org.xutils.image; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.ColorFilter; 5 | import android.graphics.Movie; 6 | import android.graphics.PixelFormat; 7 | import android.graphics.drawable.Animatable; 8 | import android.graphics.drawable.Drawable; 9 | import android.os.SystemClock; 10 | 11 | import org.xutils.common.util.LogUtil; 12 | 13 | public class GifDrawable extends Drawable implements Runnable, Animatable { 14 | 15 | private int byteCount; 16 | private int rate = 300; 17 | private volatile boolean running; 18 | 19 | private final Movie movie; 20 | private final int duration; 21 | private final long begin = SystemClock.uptimeMillis(); 22 | 23 | public GifDrawable(Movie movie, int byteCount) { 24 | this.movie = movie; 25 | this.byteCount = byteCount; 26 | this.duration = movie.duration(); 27 | } 28 | 29 | public int getDuration() { 30 | return duration; 31 | } 32 | 33 | public Movie getMovie() { 34 | return movie; 35 | } 36 | 37 | public int getByteCount() { 38 | if (byteCount == 0) { 39 | byteCount = (movie.width() * movie.height() * 3) * (5/*fake frame count*/); 40 | } 41 | return byteCount; 42 | } 43 | 44 | public int getRate() { 45 | return rate; 46 | } 47 | 48 | public void setRate(int rate) { 49 | this.rate = rate; 50 | } 51 | 52 | @Override 53 | public void draw(Canvas canvas) { 54 | try { 55 | int time = duration > 0 ? (int) (SystemClock.uptimeMillis() - begin) % duration : 0; 56 | movie.setTime(time); 57 | movie.draw(canvas, 0, 0); 58 | start(); 59 | } catch (Throwable ex) { 60 | LogUtil.e(ex.getMessage(), ex); 61 | } 62 | } 63 | 64 | @Override 65 | public void start() { 66 | if (!isRunning()) { 67 | running = true; 68 | run(); 69 | } 70 | } 71 | 72 | @Override 73 | public void stop() { 74 | if (isRunning()) { 75 | this.unscheduleSelf(this); 76 | } 77 | } 78 | 79 | @Override 80 | public boolean isRunning() { 81 | return running && duration > 0; 82 | } 83 | 84 | @Override 85 | public void run() { 86 | if (duration > 0) { 87 | this.invalidateSelf(); 88 | this.scheduleSelf(this, SystemClock.uptimeMillis() + rate); 89 | } 90 | } 91 | 92 | @Override 93 | public void setAlpha(int alpha) { 94 | 95 | } 96 | 97 | @Override 98 | public int getIntrinsicWidth() { 99 | return movie.width(); 100 | } 101 | 102 | @Override 103 | public int getIntrinsicHeight() { 104 | return movie.height(); 105 | } 106 | 107 | @Override 108 | public void setColorFilter(ColorFilter cf) { 109 | } 110 | 111 | @Override 112 | public int getOpacity() { 113 | return movie.isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/image/ImageAnimationHelper.java: -------------------------------------------------------------------------------- 1 | package org.xutils.image; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.view.animation.AlphaAnimation; 5 | import android.view.animation.Animation; 6 | import android.view.animation.DecelerateInterpolator; 7 | import android.widget.ImageView; 8 | 9 | import org.xutils.common.util.LogUtil; 10 | 11 | import java.lang.reflect.Method; 12 | 13 | /** 14 | * Created by wyouflf on 15/10/13. 15 | * ImageView Animation Helper 16 | */ 17 | public final class ImageAnimationHelper { 18 | 19 | private final static Method cloneMethod; 20 | 21 | static { 22 | Method method = null; 23 | try { 24 | method = Animation.class.getDeclaredMethod("clone"); 25 | method.setAccessible(true); 26 | } catch (Throwable ex) { 27 | method = null; 28 | LogUtil.w(ex.getMessage(), ex); 29 | } 30 | cloneMethod = method; 31 | } 32 | 33 | private ImageAnimationHelper() { 34 | } 35 | 36 | public static void fadeInDisplay(final ImageView imageView, Drawable drawable) { 37 | AlphaAnimation fadeAnimation = new AlphaAnimation(0F, 1F); 38 | fadeAnimation.setDuration(300); 39 | fadeAnimation.setInterpolator(new DecelerateInterpolator()); 40 | imageView.setImageDrawable(drawable); 41 | imageView.startAnimation(fadeAnimation); 42 | } 43 | 44 | public static void animationDisplay(ImageView imageView, Drawable drawable, Animation animation) { 45 | imageView.setImageDrawable(drawable); 46 | if (cloneMethod != null && animation != null) { 47 | try { 48 | imageView.startAnimation((Animation) cloneMethod.invoke(animation)); 49 | } catch (Throwable ex) { 50 | imageView.startAnimation(animation); 51 | } 52 | } else { 53 | imageView.startAnimation(animation); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/image/ImageManagerImpl.java: -------------------------------------------------------------------------------- 1 | package org.xutils.image; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.widget.ImageView; 5 | 6 | import org.xutils.ImageManager; 7 | import org.xutils.common.Callback; 8 | import org.xutils.x; 9 | 10 | import java.io.File; 11 | 12 | /** 13 | * Created by wyouflf on 15/10/9. 14 | */ 15 | public final class ImageManagerImpl implements ImageManager { 16 | 17 | private static final Object lock = new Object(); 18 | private static volatile ImageManagerImpl instance; 19 | 20 | private ImageManagerImpl() { 21 | } 22 | 23 | public static void registerInstance() { 24 | if (instance == null) { 25 | synchronized (lock) { 26 | if (instance == null) { 27 | instance = new ImageManagerImpl(); 28 | } 29 | } 30 | } 31 | x.Ext.setImageManager(instance); 32 | } 33 | 34 | 35 | @Override 36 | public void bind(final ImageView view, final String url) { 37 | x.task().autoPost(new Runnable() { 38 | @Override 39 | public void run() { 40 | ImageLoader.doBind(view, url, null, null); 41 | } 42 | }); 43 | } 44 | 45 | @Override 46 | public void bind(final ImageView view, final String url, final ImageOptions options) { 47 | x.task().autoPost(new Runnable() { 48 | @Override 49 | public void run() { 50 | ImageLoader.doBind(view, url, options, null); 51 | } 52 | }); 53 | } 54 | 55 | @Override 56 | public void bind(final ImageView view, final String url, final Callback.CommonCallback callback) { 57 | x.task().autoPost(new Runnable() { 58 | @Override 59 | public void run() { 60 | ImageLoader.doBind(view, url, null, callback); 61 | } 62 | }); 63 | } 64 | 65 | @Override 66 | public void bind(final ImageView view, final String url, final ImageOptions options, final Callback.CommonCallback callback) { 67 | x.task().autoPost(new Runnable() { 68 | @Override 69 | public void run() { 70 | ImageLoader.doBind(view, url, options, callback); 71 | } 72 | }); 73 | } 74 | 75 | @Override 76 | public Callback.Cancelable loadDrawable(String url, ImageOptions options, Callback.CommonCallback callback) { 77 | return ImageLoader.doLoadDrawable(url, options, callback); 78 | } 79 | 80 | @Override 81 | public Callback.Cancelable loadFile(String url, ImageOptions options, Callback.CacheCallback callback) { 82 | return ImageLoader.doLoadFile(url, options, callback); 83 | } 84 | 85 | @Override 86 | public void clearMemCache() { 87 | ImageLoader.clearMemCache(); 88 | } 89 | 90 | @Override 91 | public void clearCacheFiles() { 92 | ImageLoader.clearCacheFiles(); 93 | ImageDecoder.clearCacheFiles(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/image/MemCacheKey.java: -------------------------------------------------------------------------------- 1 | package org.xutils.image; 2 | 3 | /** 4 | * Created by wyouflf on 15/10/20. 5 | */ 6 | /*package*/ final class MemCacheKey { 7 | public final String url; 8 | public final ImageOptions options; 9 | 10 | public MemCacheKey(String url, ImageOptions options) { 11 | this.url = url; 12 | this.options = options; 13 | } 14 | 15 | @Override 16 | public boolean equals(Object o) { 17 | if (this == o) return true; 18 | if (o == null || getClass() != o.getClass()) return false; 19 | 20 | MemCacheKey that = (MemCacheKey) o; 21 | 22 | if (!url.equals(that.url)) return false; 23 | return options.equals(that.options); 24 | 25 | } 26 | 27 | @Override 28 | public int hashCode() { 29 | int result = url.hashCode(); 30 | result = 31 * result + options.hashCode(); 31 | return result; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return url + options.toString(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/image/ReusableBitmapDrawable.java: -------------------------------------------------------------------------------- 1 | package org.xutils.image; 2 | 3 | import android.content.res.Resources; 4 | import android.graphics.Bitmap; 5 | import android.graphics.drawable.BitmapDrawable; 6 | 7 | /*package*/ final class ReusableBitmapDrawable extends BitmapDrawable implements ReusableDrawable { 8 | 9 | private MemCacheKey key; 10 | 11 | public ReusableBitmapDrawable(Resources res, Bitmap bitmap) { 12 | super(res, bitmap); 13 | } 14 | 15 | @Override 16 | public MemCacheKey getMemCacheKey() { 17 | return key; 18 | } 19 | 20 | @Override 21 | public void setMemCacheKey(MemCacheKey key) { 22 | this.key = key; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/image/ReusableDrawable.java: -------------------------------------------------------------------------------- 1 | package org.xutils.image; 2 | 3 | /** 4 | * Created by wyouflf on 15/10/20. 5 | * 使已被LruCache移除, 但还在被ImageView使用的Drawable可以再次被回收使用. 6 | */ 7 | /*package*/ interface ReusableDrawable { 8 | 9 | MemCacheKey getMemCacheKey(); 10 | 11 | void setMemCacheKey(MemCacheKey key); 12 | } 13 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/view/ViewFinder.java: -------------------------------------------------------------------------------- 1 | package org.xutils.view; 2 | 3 | import android.app.Activity; 4 | import android.view.View; 5 | 6 | /** 7 | * Author: wyouflf 8 | * Date: 13-9-9 9 | * Time: 下午12:29 10 | */ 11 | /*package*/ final class ViewFinder { 12 | 13 | private View view; 14 | private Activity activity; 15 | 16 | public ViewFinder(View view) { 17 | this.view = view; 18 | } 19 | 20 | public ViewFinder(Activity activity) { 21 | this.activity = activity; 22 | } 23 | 24 | public View findViewById(int id) { 25 | if (view != null) return view.findViewById(id); 26 | if (activity != null) return activity.findViewById(id); 27 | return null; 28 | } 29 | 30 | public View findViewByInfo(ViewInfo info) { 31 | return findViewById(info.value, info.parentId); 32 | } 33 | 34 | public View findViewById(int id, int pid) { 35 | View pView = null; 36 | if (pid > 0) { 37 | pView = this.findViewById(pid); 38 | } 39 | 40 | View view = null; 41 | if (pView != null) { 42 | view = pView.findViewById(id); 43 | } else { 44 | view = this.findViewById(id); 45 | } 46 | return view; 47 | } 48 | 49 | /*public Context getContext() { 50 | if (view != null) return view.getContext(); 51 | if (activity != null) return activity; 52 | return null; 53 | }*/ 54 | } 55 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/view/ViewInfo.java: -------------------------------------------------------------------------------- 1 | package org.xutils.view; 2 | 3 | /** 4 | * Author: wyouflf 5 | * Date: 13-12-5 6 | * Time: 下午11:25 7 | */ 8 | /*package*/ final class ViewInfo { 9 | public int value; 10 | public int parentId; 11 | 12 | @Override 13 | public boolean equals(Object o) { 14 | if (this == o) return true; 15 | if (o == null || getClass() != o.getClass()) return false; 16 | 17 | ViewInfo viewInfo = (ViewInfo) o; 18 | 19 | if (value != viewInfo.value) return false; 20 | return parentId == viewInfo.parentId; 21 | 22 | } 23 | 24 | @Override 25 | public int hashCode() { 26 | int result = value; 27 | result = 31 * result + parentId; 28 | return result; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/view/annotation/ContentView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.view.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.TYPE) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface ContentView { 26 | int value(); 27 | } 28 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/view/annotation/Event.java: -------------------------------------------------------------------------------- 1 | package org.xutils.view.annotation; 2 | 3 | import android.view.View; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * 事件注解. 12 | * 被注解的方法必须具备以下形式: 13 | * 1. private 修饰 14 | * 2. 返回值类型没有要求 15 | * 3. 参数签名和type的接口要求的参数签名一致. 16 | * Author: wyouflf 17 | * Date: 13-9-9 18 | * Time: 下午12:43 19 | */ 20 | @Target(ElementType.METHOD) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | public @interface Event { 23 | 24 | /** 25 | * 控件的id集合, id小于1时不执行ui事件绑定. 26 | * 27 | * @return 28 | */ 29 | int[] value(); 30 | 31 | /** 32 | * 控件的parent控件的id集合, 组合为(value[i], parentId[i] or 0). 33 | * 34 | * @return 35 | */ 36 | int[] parentId() default 0; 37 | 38 | /** 39 | * 事件的listener, 默认为点击事件. 40 | * 41 | * @return 42 | */ 43 | Class type() default View.OnClickListener.class; 44 | 45 | /** 46 | * 事件的setter方法名, 默认为set+type#simpleName. 47 | * 48 | * @return 49 | */ 50 | String setter() default ""; 51 | 52 | /** 53 | * 如果type的接口类型提供多个方法, 需要使用此参数指定方法名. 54 | * 55 | * @return 56 | */ 57 | String method() default ""; 58 | } 59 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/view/annotation/ViewInject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.xutils.view.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.FIELD) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface ViewInject { 26 | 27 | int value(); 28 | 29 | /* parent view id */ 30 | int parentId() default 0; 31 | } 32 | -------------------------------------------------------------------------------- /xutils/src/main/java/org/xutils/x.java: -------------------------------------------------------------------------------- 1 | package org.xutils; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | 6 | import org.xutils.common.TaskController; 7 | import org.xutils.common.task.TaskControllerImpl; 8 | import org.xutils.db.DbManagerImpl; 9 | import org.xutils.http.HttpManagerImpl; 10 | import org.xutils.image.ImageManagerImpl; 11 | import org.xutils.view.ViewInjectorImpl; 12 | 13 | import java.lang.reflect.Method; 14 | 15 | import javax.net.ssl.HostnameVerifier; 16 | import javax.net.ssl.HttpsURLConnection; 17 | 18 | 19 | /** 20 | * Created by wyouflf on 15/6/10. 21 | * 任务控制中心, http, image, db, view注入等接口的入口. 22 | * 需要在在application的onCreate中初始化: x.Ext.init(this); 23 | */ 24 | public final class x { 25 | 26 | private x() { 27 | } 28 | 29 | public static boolean isDebug() { 30 | return Ext.debug; 31 | } 32 | 33 | public static Application app() { 34 | if (Ext.app == null) { 35 | try { 36 | // 在IDE进行布局预览时使用 37 | Class renderActionClass = Class.forName("com.android.layoutlib.bridge.impl.RenderAction"); 38 | Method method = renderActionClass.getDeclaredMethod("getCurrentContext"); 39 | Context context = (Context) method.invoke(null); 40 | Ext.app = new MockApplication(context); 41 | } catch (Throwable ignored) { 42 | throw new RuntimeException("please invoke x.Ext.init(app) on Application#onCreate()" 43 | + " and register your Application in manifest."); 44 | } 45 | } 46 | return Ext.app; 47 | } 48 | 49 | public static TaskController task() { 50 | return Ext.taskController; 51 | } 52 | 53 | public static HttpManager http() { 54 | if (Ext.httpManager == null) { 55 | HttpManagerImpl.registerInstance(); 56 | } 57 | return Ext.httpManager; 58 | } 59 | 60 | public static ImageManager image() { 61 | if (Ext.imageManager == null) { 62 | ImageManagerImpl.registerInstance(); 63 | } 64 | return Ext.imageManager; 65 | } 66 | 67 | public static ViewInjector view() { 68 | if (Ext.viewInjector == null) { 69 | ViewInjectorImpl.registerInstance(); 70 | } 71 | return Ext.viewInjector; 72 | } 73 | 74 | public static DbManager getDb(DbManager.DaoConfig daoConfig) { 75 | return DbManagerImpl.getInstance(daoConfig); 76 | } 77 | 78 | public static class Ext { 79 | private static boolean debug; 80 | private static Application app; 81 | private static TaskController taskController; 82 | private static HttpManager httpManager; 83 | private static ImageManager imageManager; 84 | private static ViewInjector viewInjector; 85 | 86 | private Ext() { 87 | } 88 | 89 | public static void init(Application app) { 90 | TaskControllerImpl.registerInstance(); 91 | if (Ext.app == null) { 92 | Ext.app = app; 93 | } 94 | } 95 | 96 | public static void setDebug(boolean debug) { 97 | Ext.debug = debug; 98 | } 99 | 100 | public static void setTaskController(TaskController taskController) { 101 | if (Ext.taskController == null) { 102 | Ext.taskController = taskController; 103 | } 104 | } 105 | 106 | public static void setHttpManager(HttpManager httpManager) { 107 | Ext.httpManager = httpManager; 108 | } 109 | 110 | public static void setImageManager(ImageManager imageManager) { 111 | Ext.imageManager = imageManager; 112 | } 113 | 114 | public static void setViewInjector(ViewInjector viewInjector) { 115 | Ext.viewInjector = viewInjector; 116 | } 117 | 118 | public static void setDefaultHostnameVerifier(HostnameVerifier hostnameVerifier) { 119 | HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); 120 | } 121 | } 122 | 123 | private static class MockApplication extends Application { 124 | public MockApplication(Context baseContext) { 125 | this.attachBaseContext(baseContext); 126 | } 127 | } 128 | } 129 | --------------------------------------------------------------------------------