├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── kymjs │ │ └── kjframe │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── org │ │ │ └── kymjs │ │ │ └── kjframe │ │ │ ├── KJActivity.java │ │ │ ├── KJBitmap.java │ │ │ ├── KJDB.java │ │ │ ├── KJHttp.java │ │ │ ├── bitmap │ │ │ ├── BitmapCallBack.java │ │ │ ├── BitmapConfig.java │ │ │ ├── BitmapCreate.java │ │ │ ├── BitmapMemoryCache.java │ │ │ ├── DiskImageRequest.java │ │ │ ├── ImageDisplayer.java │ │ │ ├── ImageRequest.java │ │ │ └── MemoryLruCache.java │ │ │ ├── database │ │ │ ├── CursorHelper.java │ │ │ ├── DaoConfig.java │ │ │ ├── DbModel.java │ │ │ ├── ManyToOneLazyLoader.java │ │ │ ├── OneToManyLazyLoader.java │ │ │ ├── SqlBuilder.java │ │ │ ├── SqlInfo.java │ │ │ ├── annotate │ │ │ │ ├── Id.java │ │ │ │ ├── ManyToOne.java │ │ │ │ ├── OneToMany.java │ │ │ │ ├── Property.java │ │ │ │ ├── Table.java │ │ │ │ └── Transient.java │ │ │ └── utils │ │ │ │ ├── ClassUtils.java │ │ │ │ ├── FieldUtils.java │ │ │ │ ├── Id.java │ │ │ │ ├── KeyValue.java │ │ │ │ ├── ManyToOne.java │ │ │ │ ├── OneToMany.java │ │ │ │ ├── Property.java │ │ │ │ └── TableInfo.java │ │ │ ├── http │ │ │ ├── ByteArrayPool.java │ │ │ ├── Cache.java │ │ │ ├── CacheDispatcher.java │ │ │ ├── Delivery.java │ │ │ ├── DeliveryExecutor.java │ │ │ ├── DeliveryResponse.java │ │ │ ├── DiskCache.java │ │ │ ├── DownloadController.java │ │ │ ├── DownloadTaskQueue.java │ │ │ ├── FileRequest.java │ │ │ ├── FormRequest.java │ │ │ ├── HTTPSTrustManager.java │ │ │ ├── HttpCallBack.java │ │ │ ├── HttpClientStack.java │ │ │ ├── HttpConfig.java │ │ │ ├── HttpConnectStack.java │ │ │ ├── HttpHeaderParser.java │ │ │ ├── HttpParams.java │ │ │ ├── HttpStack.java │ │ │ ├── HttpUtils.java │ │ │ ├── JsonRequest.java │ │ │ ├── KJAsyncTask.java │ │ │ ├── KJHTTP.java │ │ │ ├── KJHttpException.java │ │ │ ├── KJHttpResponse.java │ │ │ ├── KJHttpStatus.java │ │ │ ├── Network.java │ │ │ ├── NetworkDispatcher.java │ │ │ ├── NetworkResponse.java │ │ │ ├── OKHttpStack.java │ │ │ ├── PoolingByteArrayOutputStream.java │ │ │ ├── Request.java │ │ │ └── Response.java │ │ │ ├── ui │ │ │ ├── AnnotateUtil.java │ │ │ ├── BindView.java │ │ │ ├── FrameActivity.java │ │ │ ├── FrameFragment.java │ │ │ ├── I_BroadcastReg.java │ │ │ ├── I_KJActivity.java │ │ │ ├── I_SkipActivity.java │ │ │ ├── KJActivityStack.java │ │ │ ├── KJFragment.java │ │ │ ├── SupportFragment.java │ │ │ └── ViewInject.java │ │ │ ├── utils │ │ │ ├── CipherUtils.java │ │ │ ├── DensityUtils.java │ │ │ ├── FileUtils.java │ │ │ ├── ImageUtils.java │ │ │ ├── KJConfig.java │ │ │ ├── KJLoger.java │ │ │ ├── PreferenceHelper.java │ │ │ ├── StringUtils.java │ │ │ ├── SystemTool.java │ │ │ └── ViewUtils.java │ │ │ └── widget │ │ │ ├── AdapterHolder.java │ │ │ ├── AnimatorProxy.java │ │ │ ├── KJAdapter.java │ │ │ ├── KJScrollView.java │ │ │ ├── KJSlidingMenu.java │ │ │ ├── KJViewPager.java │ │ │ ├── RoundImageView.java │ │ │ └── ViewHelper.java │ └── res │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── org │ └── kymjs │ └── kjframe │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kjframe.iml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | kjframe -------------------------------------------------------------------------------- /.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/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.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 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | applicationId "org.kymjs.kjframe" 9 | minSdkVersion 8 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 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(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.0.1' 26 | } 27 | -------------------------------------------------------------------------------- /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 D:\Android\SDK\android-sdk-windows/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 | -------------------------------------------------------------------------------- /app/src/androidTest/java/org/kymjs/kjframe/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.kymjs.kjframe; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/KJActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 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 org.kymjs.kjframe; 17 | 18 | import org.kymjs.kjframe.ui.FrameActivity; 19 | import org.kymjs.kjframe.ui.KJActivityStack; 20 | import org.kymjs.kjframe.utils.KJLoger; 21 | 22 | import android.app.Activity; 23 | import android.content.Intent; 24 | import android.os.Bundle; 25 | 26 | /** 27 | * @author kymjs (https://github.com/kymjs) 28 | */ 29 | public abstract class KJActivity extends FrameActivity { 30 | 31 | /** 32 | * 当前Activity状态 33 | */ 34 | public static enum ActivityState { 35 | RESUME, PAUSE, STOP, DESTROY 36 | } 37 | 38 | public Activity aty; 39 | /** Activity状态 */ 40 | public ActivityState activityState = ActivityState.DESTROY; 41 | 42 | /*************************************************************************** 43 | * 44 | * print Activity callback methods 45 | * 46 | ***************************************************************************/ 47 | @Override 48 | protected void onCreate(Bundle savedInstanceState) { 49 | aty = this; 50 | KJActivityStack.create().addActivity(this); 51 | KJLoger.state(this.getClass().getName(), "---------onCreat "); 52 | super.onCreate(savedInstanceState); 53 | } 54 | 55 | @Override 56 | protected void onStart() { 57 | super.onStart(); 58 | KJLoger.state(this.getClass().getName(), "---------onStart "); 59 | } 60 | 61 | @Override 62 | protected void onResume() { 63 | super.onResume(); 64 | activityState = ActivityState.RESUME; 65 | KJLoger.state(this.getClass().getName(), "---------onResume "); 66 | } 67 | 68 | @Override 69 | protected void onPause() { 70 | super.onPause(); 71 | activityState = ActivityState.PAUSE; 72 | KJLoger.state(this.getClass().getName(), "---------onPause "); 73 | } 74 | 75 | @Override 76 | protected void onStop() { 77 | super.onStop(); 78 | activityState = ActivityState.STOP; 79 | KJLoger.state(this.getClass().getName(), "---------onStop "); 80 | } 81 | 82 | @Override 83 | protected void onRestart() { 84 | super.onRestart(); 85 | KJLoger.state(this.getClass().getName(), "---------onRestart "); 86 | } 87 | 88 | @Override 89 | protected void onDestroy() { 90 | activityState = ActivityState.DESTROY; 91 | KJLoger.state(this.getClass().getName(), "---------onDestroy "); 92 | super.onDestroy(); 93 | KJActivityStack.create().finishActivity(this); 94 | } 95 | 96 | /** 97 | * skip to @param(cls),and call @param(aty's) finish() method 98 | */ 99 | @Override 100 | public void skipActivity(Activity aty, Class cls) { 101 | showActivity(aty, cls); 102 | aty.finish(); 103 | } 104 | 105 | /** 106 | * skip to @param(cls),and call @param(aty's) finish() method 107 | */ 108 | @Override 109 | public void skipActivity(Activity aty, Intent it) { 110 | showActivity(aty, it); 111 | aty.finish(); 112 | } 113 | 114 | /** 115 | * skip to @param(cls),and call @param(aty's) finish() method 116 | */ 117 | @Override 118 | public void skipActivity(Activity aty, Class cls, Bundle extras) { 119 | showActivity(aty, cls, extras); 120 | aty.finish(); 121 | } 122 | 123 | /** 124 | * show to @param(cls),but can't finish activity 125 | */ 126 | @Override 127 | public void showActivity(Activity aty, Class cls) { 128 | Intent intent = new Intent(); 129 | intent.setClass(aty, cls); 130 | aty.startActivity(intent); 131 | } 132 | 133 | /** 134 | * show to @param(cls),but can't finish activity 135 | */ 136 | @Override 137 | public void showActivity(Activity aty, Intent it) { 138 | aty.startActivity(it); 139 | } 140 | 141 | /** 142 | * show to @param(cls),but can't finish activity 143 | */ 144 | @Override 145 | public void showActivity(Activity aty, Class cls, Bundle extras) { 146 | Intent intent = new Intent(); 147 | intent.putExtras(extras); 148 | intent.setClass(aty, cls); 149 | aty.startActivity(intent); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/bitmap/BitmapCallBack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.bitmap; 17 | 18 | import android.graphics.Bitmap; 19 | 20 | /** 21 | * BitmapLibrary中的回调方法 22 | * 23 | * @author kymjs (https://github.com/kymjs) 24 | * 25 | */ 26 | public abstract class BitmapCallBack { 27 | /** 载入前回调 */ 28 | public void onPreLoad() {} 29 | 30 | /** bitmap载入完成将回调 */ 31 | public void onSuccess(final Bitmap bitmap) {} 32 | 33 | /** bitmap载入失败将回调 */ 34 | public void onFailure(final Exception e) {} 35 | 36 | /** bitmap载入完成不管成功失败 */ 37 | public void onFinish() {} 38 | 39 | /** bitmap开始加载网络图片 */ 40 | public void onDoHttp() {} 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/bitmap/BitmapConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.bitmap; 17 | 18 | import org.kymjs.kjframe.bitmap.ImageDisplayer.ImageCache; 19 | import org.kymjs.kjframe.http.HttpConfig; 20 | import org.kymjs.kjframe.utils.KJLoger; 21 | 22 | /** 23 | * Bitmap配置器 24 | * 25 | * @author kymjs (https://github.com/kymjs) 26 | * 27 | */ 28 | public class BitmapConfig { 29 | 30 | public boolean isDEBUG = KJLoger.DEBUG_LOG; 31 | 32 | /** 新版本图片缓存与http缓存处于同一目录 */ 33 | @Deprecated 34 | public static String CACHEPATH = HttpConfig.CACHEPATH; 35 | 36 | /** 磁盘缓存大小 */ 37 | public static int DISK_CACHE_SIZE = 10 * 1024 * 1024; 38 | /** 磁盘缓存器 **/ 39 | public static ImageCache mMemoryCache; 40 | 41 | public int cacheTime = 1440000; 42 | // 为了防止网速很快的时候速度过快而造成先显示加载中图片,然后瞬间显示网络图片的闪烁问题 43 | public long delayTime = 100; 44 | 45 | public BitmapConfig() { 46 | if (mMemoryCache == null) { 47 | mMemoryCache = new BitmapMemoryCache(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/bitmap/BitmapMemoryCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.bitmap; 17 | 18 | import org.kymjs.kjframe.bitmap.ImageDisplayer.ImageCache; 19 | import org.kymjs.kjframe.utils.SystemTool; 20 | 21 | import android.annotation.SuppressLint; 22 | import android.graphics.Bitmap; 23 | 24 | /** 25 | * 使用lru算法的Bitmap内存缓存池
26 | * 27 | * 创建时间 2014-7-11 28 | * 29 | * @author kymjs (https://github.com/kymjs) 30 | * @version 1.0 31 | */ 32 | public final class BitmapMemoryCache implements ImageCache { 33 | 34 | private MemoryLruCache cache; 35 | 36 | public BitmapMemoryCache() { 37 | int maxMemory = (int) (Runtime.getRuntime().maxMemory()); 38 | init(maxMemory / 8); 39 | } 40 | 41 | /** 42 | * @param maxSize 43 | * 使用内存缓存的内存大小,单位:kb 44 | */ 45 | public BitmapMemoryCache(int maxSize) { 46 | init(maxSize); 47 | } 48 | 49 | /** 50 | * @param maxSize 51 | * 使用内存缓存的内存大小,单位:kb 52 | */ 53 | @SuppressLint("NewApi") 54 | private void init(int maxSize) { 55 | cache = new MemoryLruCache(maxSize) { 56 | @Override 57 | protected int sizeOf(String key, Bitmap value) { 58 | super.sizeOf(key, value); 59 | if (SystemTool.getSDKVersion() >= 12) { 60 | return value.getByteCount(); 61 | } else { 62 | return value.getRowBytes() * value.getHeight(); 63 | } 64 | } 65 | }; 66 | } 67 | 68 | @Override 69 | public void remove(String key) { 70 | cache.remove(key); 71 | } 72 | 73 | @Override 74 | public void clean() { 75 | cache.clean(); 76 | } 77 | 78 | /** 79 | * @param url 80 | * 图片的地址 81 | * @return 82 | */ 83 | @Override 84 | public Bitmap getBitmap(String url) { 85 | return cache.get(url); 86 | } 87 | 88 | /** 89 | * @param url 90 | * 图片的地址 91 | * @param bitmap 92 | * 要缓存的bitmap 93 | */ 94 | @Override 95 | public void putBitmap(String url, Bitmap bitmap) { 96 | if (this.getBitmap(url) == null) { 97 | cache.put(url, bitmap); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/bitmap/DiskImageRequest.java: -------------------------------------------------------------------------------- 1 | package org.kymjs.kjframe.bitmap; import java.io.FileInputStream; import java.io.FileNotFoundException; import org.kymjs.kjframe.http.KJAsyncTask; import org.kymjs.kjframe.utils.FileUtils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.os.Looper; /** * 本地图片加载 * * @author kymjs (https://www.kymjs.com/) */ public class DiskImageRequest { private final Handler handle = new Handler(Looper.getMainLooper()); private String mPath; class DiskImageRequestTask extends KJAsyncTask { private final int mMaxWidth; private final int mMaxHeight; private final BitmapCallBack mCallback; public DiskImageRequestTask(int maxWidth, int maxHeight, BitmapCallBack callback) { mMaxHeight = maxHeight; mMaxWidth = maxWidth; mCallback = callback; } @Override protected void onPreExecute() { super.onPreExecute(); if (mCallback != null) { mCallback.onPreLoad(); } } @Override protected byte[] doInBackground(Void... params) { return loadFromFile(mPath, mMaxWidth, mMaxHeight, mCallback); } } public void load(String path, int maxWidth, int maxHeight, BitmapCallBack callback) { mPath = path; DiskImageRequestTask task = new DiskImageRequestTask(maxWidth, maxHeight, callback); task.execute(); } /** * 从本地载入一张图片 * * @param imagePath * 图片的地址 * @throws FileNotFoundException */ private byte[] loadFromFile(String path, int maxWidth, int maxHeight, BitmapCallBack callback) { byte[] data = null; FileInputStream fis = null; try { fis = new FileInputStream(path); if (fis != null) { data = FileUtils.input2byte(fis); } handleBitmap(data, maxWidth, maxHeight, callback); } catch (Exception e) { doFailure(callback, e); } finally { FileUtils.closeIO(fis); } return data; } private Bitmap handleBitmap(byte[] data, int maxWidth, int maxHeight, BitmapCallBack callback) { BitmapFactory.Options option = new BitmapFactory.Options(); Bitmap bitmap = null; if (maxWidth <= 0 && maxHeight <= 0) { bitmap = BitmapFactory .decodeByteArray(data, 0, data.length, option); } else { option.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(data, 0, data.length, option); int actualWidth = option.outWidth; int actualHeight = option.outHeight; // 计算出图片应该显示的宽高 int desiredWidth = getResizedDimension(maxWidth, maxHeight, actualWidth, actualHeight); int desiredHeight = getResizedDimension(maxHeight, maxWidth, actualHeight, actualWidth); option.inJustDecodeBounds = false; option.inSampleSize = findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight); Bitmap tempBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, option); // 做缩放 if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth || tempBitmap .getHeight() > desiredHeight)) { bitmap = Bitmap.createScaledBitmap(tempBitmap, desiredWidth, desiredHeight, true); tempBitmap.recycle(); } else { bitmap = tempBitmap; } } if (bitmap == null) { doFailure(callback, new RuntimeException("bitmap create error")); } else { BitmapConfig.mMemoryCache.putBitmap(mPath, bitmap); doSuccess(callback, bitmap); } return bitmap; } /** * 框架会自动将大于设定值的bitmap转换成设定值,所以需要这个方法来判断应该显示默认大小或者是设定值大小。
* 本方法会根据maxPrimary与actualPrimary比较来判断,如果无法判断则会根据辅助值判断,辅助值一般是主要值对应的。 * 比如宽为主值则高为辅值 * * @param maxPrimary * 需要判断的值,用作主要判断 * @param maxSecondary * 需要判断的值,用作辅助判断 * @param actualPrimary * 真实宽度 * @param actualSecondary * 真实高度 * @return 获取图片需要显示的大小 */ private int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary, int actualSecondary) { if (maxPrimary == 0 && maxSecondary == 0) { return actualPrimary; } if (maxPrimary == 0) { double ratio = (double) maxSecondary / (double) actualSecondary; return (int) (actualPrimary * ratio); } if (maxSecondary == 0) { return maxPrimary; } double ratio = (double) actualSecondary / (double) actualPrimary; int resized = maxPrimary; if (resized * ratio > maxSecondary) { resized = (int) (maxSecondary / ratio); } return resized; } /** * 关于本方法的判断,可以查看我的博客:http://blog.kymjs.com/kjframeforandroid/2014/12/05/02/ * * @param actualWidth * @param actualHeight * @param desiredWidth * @param desiredHeight * @return */ static int findBestSampleSize(int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) { double wr = (double) actualWidth / desiredWidth; double hr = (double) actualHeight / desiredHeight; double ratio = Math.min(wr, hr); float n = 1.0f; while ((n * 2) <= ratio) { n *= 2; } return (int) n; } private void doSuccess(final BitmapCallBack callback, final Bitmap bitmap) { if (callback != null) { handle.post(new Runnable() { @Override public void run() { callback.onSuccess(bitmap); callback.onFinish(); } }); } } private void doFailure(final BitmapCallBack callback, final Exception e) { if (callback != null) { handle.post(new Runnable() { @Override public void run() { callback.onFailure(e); callback.onFinish(); } }); } } } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/DaoConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database; 17 | 18 | import org.kymjs.kjframe.KJDB.DbUpdateListener; 19 | import org.kymjs.kjframe.utils.KJLoger; 20 | 21 | import android.content.Context; 22 | 23 | /** 24 | * 数据库配置器
25 | * 26 | * 创建时间 2014-8-15 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.0 30 | */ 31 | final public class DaoConfig { 32 | private Context mContext = null; // android上下文 33 | private String mDbName = "KJLibrary.db"; // 数据库名字 34 | private int dbVersion = 1; // 数据库版本 35 | private boolean debug = KJLoger.DEBUG_LOG; // 是否是调试模式(调试模式 增删改查的时候显示SQL语句) 36 | private DbUpdateListener dbUpdateListener; 37 | // private boolean saveOnSDCard = false;//是否保存到SD卡 38 | private String targetDirectory;// 数据库文件在sd卡中的目录 39 | 40 | public Context getContext() { 41 | return mContext; 42 | } 43 | 44 | public void setContext(Context context) { 45 | this.mContext = context; 46 | } 47 | 48 | /** 49 | * 数据库名 50 | */ 51 | public String getDbName() { 52 | return mDbName; 53 | } 54 | 55 | /** 56 | * 数据库名 57 | */ 58 | public void setDbName(String dbName) { 59 | this.mDbName = dbName; 60 | } 61 | 62 | /** 63 | * 数据库版本 64 | */ 65 | public int getDbVersion() { 66 | return dbVersion; 67 | } 68 | 69 | /** 70 | * 数据库版本 71 | */ 72 | public void setDbVersion(int dbVersion) { 73 | this.dbVersion = dbVersion; 74 | } 75 | 76 | /** 77 | * 是否调试模式 78 | */ 79 | public boolean isDebug() { 80 | return debug; 81 | } 82 | 83 | /** 84 | * 是否调试模式 85 | */ 86 | public void setDebug(boolean debug) { 87 | this.debug = debug; 88 | } 89 | 90 | /** 91 | * 数据库升级时监听器 92 | * 93 | * @return 94 | */ 95 | public DbUpdateListener getDbUpdateListener() { 96 | return dbUpdateListener; 97 | } 98 | 99 | /** 100 | * 数据库升级时监听器 101 | */ 102 | public void setDbUpdateListener(DbUpdateListener dbUpdateListener) { 103 | this.dbUpdateListener = dbUpdateListener; 104 | } 105 | 106 | // public boolean isSaveOnSDCard() { 107 | // return saveOnSDCard; 108 | // } 109 | // 110 | // public void setSaveOnSDCard(boolean saveOnSDCard) { 111 | // this.saveOnSDCard = saveOnSDCard; 112 | // } 113 | 114 | /** 115 | * 数据库文件在sd卡中的目录 116 | */ 117 | public String getTargetDirectory() { 118 | return targetDirectory; 119 | } 120 | 121 | /** 122 | * 数据库文件在sd卡中的目录 123 | */ 124 | public void setTargetDirectory(String targetDirectory) { 125 | this.targetDirectory = targetDirectory; 126 | } 127 | } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/DbModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database; 17 | 18 | import java.util.HashMap; 19 | 20 | /** 21 | * 数据库的模型
22 | * 23 | * 创建时间 2014-8-15 24 | * 25 | * @author kymjs (https://github.com/kymjs) 26 | * @version 1.0 27 | */ 28 | public class DbModel { 29 | 30 | private final HashMap dataMap = new HashMap(); 31 | 32 | public Object get(String column) { 33 | return dataMap.get(column); 34 | } 35 | 36 | public String getString(String column) { 37 | return String.valueOf(get(column)); 38 | } 39 | 40 | public int getInt(String column) { 41 | return Integer.valueOf(getString(column)); 42 | } 43 | 44 | public boolean getBoolean(String column) { 45 | return Boolean.valueOf(getString(column)); 46 | } 47 | 48 | public double getDouble(String column) { 49 | return Double.valueOf(getString(column)); 50 | } 51 | 52 | public float getFloat(String column) { 53 | return Float.valueOf(getString(column)); 54 | } 55 | 56 | public long getLong(String column) { 57 | return Long.valueOf(getString(column)); 58 | } 59 | 60 | public void set(String key, Object value) { 61 | dataMap.put(key, value); 62 | } 63 | 64 | public HashMap getDataMap() { 65 | return dataMap; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/ManyToOneLazyLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database; 17 | 18 | import org.kymjs.kjframe.KJDB; 19 | 20 | /** 21 | * 多对一延迟加载类
22 | * 创建时间 2014-8-15 23 | * 24 | * @param 25 | * 宿主实体的class 26 | * @param 27 | * 多放实体class 28 | * 29 | * @author kymjs (https://github.com/kymjs) 30 | * @version 1.0 31 | */ 32 | public class ManyToOneLazyLoader { 33 | M manyEntity; 34 | Class manyClazz; 35 | Class oneClazz; 36 | KJDB db; 37 | 38 | public ManyToOneLazyLoader(M manyEntity, Class manyClazz, 39 | Class oneClazz, KJDB db) { 40 | this.manyEntity = manyEntity; 41 | this.manyClazz = manyClazz; 42 | this.oneClazz = oneClazz; 43 | this.db = db; 44 | } 45 | 46 | O oneEntity; 47 | boolean hasLoaded = false; 48 | 49 | /** 50 | * 如果数据未加载,则调用loadManyToOne填充数据 51 | * 52 | * @return 53 | */ 54 | public O get() { 55 | if (oneEntity == null && !hasLoaded) { 56 | this.db.loadManyToOne(this.manyEntity, this.manyClazz, 57 | this.oneClazz); 58 | hasLoaded = true; 59 | } 60 | return oneEntity; 61 | } 62 | 63 | public void set(O value) { 64 | oneEntity = value; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/OneToManyLazyLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | import org.kymjs.kjframe.KJDB; 22 | 23 | /** 24 | * 一对多延迟加载类
25 | * 创建时间 2014-8-15 26 | * 27 | * @param 28 | * 宿主实体的class 29 | * @param 30 | * 多放实体class 31 | * @author kymjs (https://github.com/kymjs) 32 | * @version 1.0 33 | */ 34 | public class OneToManyLazyLoader { 35 | O ownerEntity; 36 | Class ownerClazz; 37 | Class listItemClazz; 38 | KJDB db; 39 | 40 | public OneToManyLazyLoader(O ownerEntity, Class ownerClazz, 41 | Class listItemclazz, KJDB db) { 42 | this.ownerEntity = ownerEntity; 43 | this.ownerClazz = ownerClazz; 44 | this.listItemClazz = listItemclazz; 45 | this.db = db; 46 | } 47 | 48 | List entities; 49 | 50 | /** 51 | * 如果数据未加载,则调用loadOneToMany填充数据 52 | * 53 | * @return 54 | */ 55 | public List getList() { 56 | if (entities == null) { 57 | this.db.loadOneToMany(this.ownerEntity, this.ownerClazz, 58 | this.listItemClazz); 59 | } 60 | if (entities == null) { 61 | entities = new ArrayList(); 62 | } 63 | return entities; 64 | } 65 | 66 | public void setList(List value) { 67 | entities = value; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/SqlInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database; 17 | 18 | import java.util.LinkedList; 19 | 20 | /** 21 | * sql语句的全部信息
22 | * 23 | * 创建时间 2014-8-15 24 | * 25 | * @author kymjs (https://github.com/kymjs) 26 | * @version 1.0 27 | */ 28 | public class SqlInfo { 29 | 30 | private String sql; 31 | private LinkedList bindArgs; 32 | 33 | public String getSql() { 34 | return sql; 35 | } 36 | 37 | public void setSql(String sql) { 38 | this.sql = sql; 39 | } 40 | 41 | public LinkedList getBindArgs() { 42 | return bindArgs; 43 | } 44 | 45 | public void setBindArgs(LinkedList bindArgs) { 46 | this.bindArgs = bindArgs; 47 | } 48 | 49 | public Object[] getBindArgsAsArray() { 50 | if (bindArgs != null) 51 | return bindArgs.toArray(); 52 | return null; 53 | } 54 | 55 | public String[] getBindArgsAsStringArray() { 56 | if (bindArgs != null) { 57 | String[] strings = new String[bindArgs.size()]; 58 | for (int i = 0; i < bindArgs.size(); i++) { 59 | strings[i] = bindArgs.get(i).toString(); 60 | } 61 | return strings; 62 | } 63 | return null; 64 | } 65 | 66 | public void addValue(Object obj) { 67 | if (bindArgs == null) 68 | bindArgs = new LinkedList(); 69 | 70 | bindArgs.add(obj); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/annotate/Id.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.annotate; 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 | /** 24 | * Id主键配置,不配置的时候默认找类的id或_id字段作为主键,column不配置的是默认为字段名
25 | * 26 | * 创建时间 2014-8-15 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.0 30 | */ 31 | @Target(ElementType.FIELD) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | public @interface Id { 34 | /** 35 | * 设置为主键 36 | * 37 | * @return 38 | */ 39 | public String column() default ""; 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/annotate/ManyToOne.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.annotate; 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 | /** 24 | * 标识多对一的属性列
25 | * 26 | * 创建时间 2014-8-15 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.0 30 | */ 31 | @Target(ElementType.FIELD) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | public @interface ManyToOne { 34 | public String column() default ""; 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/annotate/OneToMany.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.annotate; 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 | /** 24 | * 标识一对多的属性列
25 | * 26 | * 创建时间 2014-8-15 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.0 30 | */ 31 | @Target(ElementType.FIELD) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | public @interface OneToMany { 34 | 35 | public String manyColumn(); 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/annotate/Property.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.annotate; 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 | /** 24 | * 可以设置默认值的属性列
25 | * 26 | * 创建时间 2014-8-15 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.0 30 | */ 31 | @Target(ElementType.FIELD) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | public @interface Property { 34 | public String column() default ""; 35 | 36 | public String defaultValue() default ""; 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/annotate/Table.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.annotate; 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 | /** 24 | * 表名注解
25 | * 26 | * 创建时间 2014-8-15 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.0 30 | */ 31 | @Target(ElementType.TYPE) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | public @interface Table { 34 | /** 35 | * 表名 36 | */ 37 | public String name(); 38 | } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/annotate/Transient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.annotate; 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 | /** 24 | * 检测 字段是否已经被标注为 非数据库字段
25 | * 26 | * 创建时间 2014-8-15 27 | * 28 | * 29 | * @author kymjs (https://github.com/kymjs) 30 | * @version 1.0 31 | */ 32 | @Target(ElementType.FIELD) 33 | @Retention(RetentionPolicy.RUNTIME) 34 | public @interface Transient { 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/utils/Id.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.utils; 17 | 18 | /** 19 | * 主键,一个特殊的属性
20 | * 21 | * 创建时间 2014-8-15 22 | * 23 | * @author kymjs (https://github.com/kymjs) 24 | * @version 1.0 25 | */ 26 | public class Id extends Property { 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/utils/KeyValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.utils; 17 | 18 | import java.text.SimpleDateFormat; 19 | 20 | /** 21 | * 键值对封装
22 | * 23 | * 创建时间 2014-8-15 24 | * 25 | * @author kymjs (https://github.com/kymjs) 26 | * @version 1.0 27 | */ 28 | public class KeyValue { 29 | private String key; 30 | private Object value; 31 | 32 | public KeyValue(String key, Object value) { 33 | this.key = key; 34 | this.value = value; 35 | } 36 | 37 | public KeyValue() {} 38 | 39 | public String getKey() { 40 | return key; 41 | } 42 | 43 | public void setKey(String key) { 44 | this.key = key; 45 | } 46 | 47 | private static SimpleDateFormat sdf = new SimpleDateFormat( 48 | "yyyy-MM-dd HH:mm:ss"); 49 | 50 | public Object getValue() { 51 | if (value instanceof java.util.Date || value instanceof java.sql.Date) { 52 | return sdf.format(value); 53 | } 54 | return value; 55 | } 56 | 57 | public void setValue(Object value) { 58 | this.value = value; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/utils/ManyToOne.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.utils; 17 | 18 | /** 19 | * 多对一的字段
20 | * 21 | * 创建时间 2014-8-15 22 | * 23 | * @author kymjs (https://github.com/kymjs) 24 | * @version 1.0 25 | */ 26 | public class ManyToOne extends Property { 27 | 28 | private Class manyClass; 29 | 30 | public Class getManyClass() { 31 | return manyClass; 32 | } 33 | 34 | public void setManyClass(Class manyClass) { 35 | this.manyClass = manyClass; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/utils/OneToMany.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.utils; 17 | 18 | /** 19 | * 一对多的字段
20 | * 21 | * 创建时间 2014-8-15 22 | * 23 | * @author kymjs (https://github.com/kymjs) 24 | * @version 1.0 25 | */ 26 | public class OneToMany extends Property { 27 | 28 | private Class oneClass; 29 | 30 | public Class getOneClass() { 31 | return oneClass; 32 | } 33 | 34 | public void setOneClass(Class oneClass) { 35 | this.oneClass = oneClass; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/utils/Property.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.utils; 17 | 18 | import android.annotation.SuppressLint; 19 | 20 | import java.lang.reflect.Field; 21 | import java.lang.reflect.InvocationTargetException; 22 | import java.lang.reflect.Method; 23 | import java.text.ParseException; 24 | import java.text.SimpleDateFormat; 25 | import java.util.Date; 26 | 27 | /** 28 | * 属性 ,【非主键】的【基本数据类型】 都是属性
29 | * 30 | * 创建时间 2014-8-15 31 | * 32 | * @author kymjs (https://github.com/kymjs) 33 | * @version 1.0 34 | */ 35 | public class Property { 36 | 37 | private String fieldName; 38 | private String column; 39 | private String defaultValue; 40 | private Class dataType; 41 | private Field field; 42 | 43 | private Method get; 44 | private Method set; 45 | 46 | public void setValue(Object receiver, Object value) { 47 | if (set != null && value != null) { 48 | try { 49 | if (dataType == String.class) { 50 | set.invoke(receiver, value.toString()); 51 | } else if (dataType == int.class || dataType == Integer.class) { 52 | set.invoke(receiver, value == null ? (Integer) null 53 | : Integer.parseInt(value.toString())); 54 | } else if (dataType == float.class || dataType == Float.class) { 55 | set.invoke( 56 | receiver, 57 | value == null ? (Float) null : Float 58 | .parseFloat(value.toString())); 59 | } else if (dataType == double.class || dataType == Double.class) { 60 | set.invoke( 61 | receiver, 62 | value == null ? (Double) null : Double 63 | .parseDouble(value.toString())); 64 | } else if (dataType == long.class || dataType == Long.class) { 65 | set.invoke( 66 | receiver, 67 | value == null ? (Long) null : Long.parseLong(value 68 | .toString())); 69 | } else if (dataType == java.util.Date.class 70 | || dataType == java.sql.Date.class) { 71 | set.invoke(receiver, value == null ? (Date) null 72 | : stringToDateTime(value.toString())); 73 | } else if (dataType == boolean.class 74 | || dataType == Boolean.class) { 75 | set.invoke( 76 | receiver, 77 | value == null ? (Boolean) null : "1".equals(value 78 | .toString())); 79 | } else { 80 | set.invoke(receiver, value); 81 | } 82 | } catch (Exception e) { 83 | } 84 | } else { 85 | try { 86 | field.setAccessible(true); 87 | field.set(receiver, value); 88 | } catch (Exception e) { 89 | } 90 | } 91 | } 92 | 93 | /** 94 | * 获取某个实体执行某个方法的结果 95 | * 96 | * @param obj 97 | * @return 98 | */ 99 | @SuppressWarnings("unchecked") 100 | public T getValue(Object obj) { 101 | if (obj != null && get != null) { 102 | try { 103 | return (T) get.invoke(obj); 104 | } catch (IllegalArgumentException e) { 105 | } catch (IllegalAccessException e) { 106 | } catch (InvocationTargetException e) { 107 | } 108 | } 109 | return null; 110 | } 111 | 112 | @SuppressLint("SimpleDateFormat") 113 | private static SimpleDateFormat sdf = new SimpleDateFormat( 114 | "yyyy-MM-dd HH:mm:ss"); 115 | 116 | private static Date stringToDateTime(String strDate) { 117 | if (strDate != null) { 118 | try { 119 | return sdf.parse(strDate); 120 | } catch (ParseException e) { 121 | } 122 | } 123 | return null; 124 | } 125 | 126 | public String getFieldName() { 127 | return fieldName; 128 | } 129 | 130 | public void setFieldName(String fieldName) { 131 | this.fieldName = fieldName; 132 | } 133 | 134 | public String getColumn() { 135 | return column; 136 | } 137 | 138 | public void setColumn(String column) { 139 | this.column = column; 140 | } 141 | 142 | public String getDefaultValue() { 143 | return defaultValue; 144 | } 145 | 146 | public void setDefaultValue(String defaultValue) { 147 | this.defaultValue = defaultValue; 148 | } 149 | 150 | public Class getDataType() { 151 | return dataType; 152 | } 153 | 154 | public void setDataType(Class dataType) { 155 | this.dataType = dataType; 156 | } 157 | 158 | public Method getGet() { 159 | return get; 160 | } 161 | 162 | public void setGet(Method get) { 163 | this.get = get; 164 | } 165 | 166 | public Method getSet() { 167 | return set; 168 | } 169 | 170 | public void setSet(Method set) { 171 | this.set = set; 172 | } 173 | 174 | public Field getField() { 175 | return field; 176 | } 177 | 178 | public void setField(Field field) { 179 | this.field = field; 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/database/utils/TableInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.database.utils; 17 | 18 | import java.lang.reflect.Field; 19 | import java.util.HashMap; 20 | import java.util.List; 21 | 22 | /** 23 | * 表完整信息
24 | * 25 | * 创建时间 2014-8-15 26 | * 27 | * @author kymjs (https://github.com/kymjs) 28 | * @version 1.0 29 | */ 30 | public class TableInfo { 31 | 32 | private String className; 33 | private String tableName; 34 | 35 | private Id id; 36 | 37 | public final HashMap propertyMap = new HashMap(); 38 | public final HashMap oneToManyMap = new HashMap(); 39 | public final HashMap manyToOneMap = new HashMap(); 40 | 41 | private boolean checkDatabese;// 在对实体进行数据库操作的时候查询是否已经有表了,只需查询一遍,用此标示 42 | 43 | private static final HashMap tableInfoMap = new HashMap(); 44 | 45 | private TableInfo() {} 46 | 47 | @SuppressWarnings("unused") 48 | public static TableInfo get(Class clazz) { 49 | if (clazz == null) 50 | throw new RuntimeException( 51 | "table info get error,because the clazz is null"); 52 | 53 | TableInfo tableInfo = tableInfoMap.get(clazz.getName()); 54 | if (tableInfo == null) { 55 | tableInfo = new TableInfo(); 56 | 57 | tableInfo.setTableName(ClassUtils.getTableName(clazz)); 58 | tableInfo.setClassName(clazz.getName()); 59 | 60 | Field idField = ClassUtils.getPrimaryKeyField(clazz); 61 | if (idField != null) { 62 | Id id = new Id(); 63 | id.setColumn(FieldUtils.getColumnByField(idField)); 64 | id.setFieldName(idField.getName()); 65 | id.setSet(FieldUtils.getFieldSetMethod(clazz, idField)); 66 | id.setGet(FieldUtils.getFieldGetMethod(clazz, idField)); 67 | id.setDataType(idField.getType()); 68 | 69 | tableInfo.setId(id); 70 | } else { 71 | throw new RuntimeException( 72 | "the class[" 73 | + clazz 74 | + "]'s idField is null , \n you can define _id,id property or use annotation @id to solution this exception"); 75 | } 76 | 77 | List pList = ClassUtils.getPropertyList(clazz); 78 | if (pList != null) { 79 | for (Property p : pList) { 80 | if (p != null) 81 | tableInfo.propertyMap.put(p.getColumn(), p); 82 | } 83 | } 84 | 85 | List mList = ClassUtils.getManyToOneList(clazz); 86 | if (mList != null) { 87 | for (ManyToOne m : mList) { 88 | if (m != null) 89 | tableInfo.manyToOneMap.put(m.getColumn(), m); 90 | } 91 | } 92 | 93 | List oList = ClassUtils.getOneToManyList(clazz); 94 | if (oList != null) { 95 | for (OneToMany o : oList) { 96 | if (o != null) 97 | tableInfo.oneToManyMap.put(o.getColumn(), o); 98 | } 99 | } 100 | tableInfoMap.put(clazz.getName(), tableInfo); 101 | } 102 | 103 | if (tableInfo == null) { 104 | throw new RuntimeException("the class[" + clazz 105 | + "]'s table is null"); 106 | } 107 | return tableInfo; 108 | } 109 | 110 | public static TableInfo get(String className) { 111 | try { 112 | return get(Class.forName(className)); 113 | } catch (ClassNotFoundException e) { 114 | e.printStackTrace(); 115 | } 116 | return null; 117 | } 118 | 119 | public String getClassName() { 120 | return className; 121 | } 122 | 123 | public void setClassName(String className) { 124 | this.className = className; 125 | } 126 | 127 | public String getTableName() { 128 | return tableName; 129 | } 130 | 131 | public void setTableName(String tableName) { 132 | this.tableName = tableName; 133 | } 134 | 135 | public Id getId() { 136 | return id; 137 | } 138 | 139 | public void setId(Id id) { 140 | this.id = id; 141 | } 142 | 143 | public boolean isCheckDatabese() { 144 | return checkDatabese; 145 | } 146 | 147 | public void setCheckDatabese(boolean checkDatabese) { 148 | this.checkDatabese = checkDatabese; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/Cache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Android Open Source Project,张涛. 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 org.kymjs.kjframe.http; 17 | 18 | import java.util.Collections; 19 | import java.util.Map; 20 | 21 | /** 22 | * 一个缓存接口协议,其中包含了缓存的bean原型 23 | */ 24 | public interface Cache { 25 | 26 | public Entry get(String key); 27 | 28 | public void put(String key, Entry entry); 29 | 30 | public void remove(String key); 31 | 32 | public void clean(); 33 | 34 | /** 35 | * 执行在线程中 36 | */ 37 | public void initialize(); 38 | 39 | /** 40 | * 让一个缓存过期 41 | * 42 | * @param key 43 | * Cache key 44 | * @param fullExpire 45 | * True to fully expire the entry, false to soft expire 46 | */ 47 | public void invalidate(String key, boolean fullExpire); 48 | 49 | /** 50 | * cache真正缓存的数据bean,这个是会被保存的缓存对象 51 | */ 52 | public static class Entry { 53 | public byte[] data; 54 | public String etag; // 为cache标记一个tag 55 | 56 | public long serverDate; // 本次请求成功时的服务器时间 57 | public long ttl; // 有效期,System.currentTimeMillis() 58 | 59 | public Map responseHeaders = Collections.emptyMap(); 60 | 61 | /** 62 | * 是否已过期 63 | */ 64 | public boolean isExpired() { 65 | return this.ttl < System.currentTimeMillis(); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/CacheDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Android Open Source Project,张涛. 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 org.kymjs.kjframe.http; 17 | 18 | import android.os.Process; 19 | 20 | import org.kymjs.kjframe.KJHttp; 21 | import org.kymjs.kjframe.bitmap.ImageRequest; 22 | import org.kymjs.kjframe.utils.KJLoger; 23 | 24 | import java.util.concurrent.BlockingQueue; 25 | 26 | /** 27 | * 缓存调度器
28 | * 29 | * Note:
30 | * 工作描述: 缓存逻辑同样也采用责任链模式,参考注释{@link KJHttp }, 31 | * 由缓存任务队列CacheQueue,缓存调度器CacheDispatcher,缓存器Cache组成
32 | * 33 | * 调度器不停的从CacheQueue中取request,并把这个request尝试从缓存器中获取缓存响应。
34 | * 如果缓存器有有效且及时的缓存则直接返回缓存;
35 | * 如果缓存器有有效但待刷新的有效缓存,则交给分发器去分发一次中介相应,并再去添加到工作队列中执行网络请求获取最新的数据;
36 | * 如果缓存器中没有有效缓存,则把请求添加到mNetworkQueue工作队列中去执行网络请求;
37 | * 38 | * Note:
39 | * 关于中介相应查看 Response.intermediate() 40 | */ 41 | public class CacheDispatcher extends Thread { 42 | 43 | private final BlockingQueue> mCacheQueue; // 缓存队列 44 | private final BlockingQueue> mNetworkQueue; // 用于执行网络请求的工作队列 45 | private final Cache mCache; // 缓存器 46 | private final Delivery mDelivery; // 分发器 47 | private final HttpConfig mConfig; // 配置器 48 | 49 | private volatile boolean mQuit = false; 50 | 51 | /** 52 | * 创建分发器(必须手动调用star()方法启动分发任务) 53 | * 54 | * @param cacheQueue 缓存队列 55 | * @param networkQueue 正在执行的队列 56 | * @param config 配置器 57 | */ 58 | public CacheDispatcher(BlockingQueue> cacheQueue, 59 | BlockingQueue> networkQueue, HttpConfig config) { 60 | mCacheQueue = cacheQueue; 61 | mNetworkQueue = networkQueue; 62 | mCache = HttpConfig.mCache; 63 | mDelivery = config.mDelivery; 64 | mConfig = config; 65 | } 66 | 67 | /** 68 | * 强制退出 69 | */ 70 | public void quit() { 71 | mQuit = true; 72 | interrupt(); 73 | } 74 | 75 | /** 76 | * 工作在阻塞态 77 | */ 78 | @Override 79 | public void run() { 80 | Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 81 | mCache.initialize(); 82 | 83 | while (true) { 84 | try { 85 | final Request request = mCacheQueue.take(); 86 | if (request.isCanceled()) { 87 | request.finish("cache-discard-canceled"); 88 | continue; 89 | } 90 | 91 | Cache.Entry entry = mCache.get(request.getCacheKey()); 92 | if (entry == null) { // 如果没有缓存,去网络请求 93 | mNetworkQueue.put(request); 94 | continue; 95 | } 96 | 97 | // 如果缓存过期,去网络请求,图片缓存永久有效 98 | if (entry.isExpired() && !(request instanceof ImageRequest)) { 99 | request.setCacheEntry(entry); 100 | mNetworkQueue.put(request); 101 | continue; 102 | } 103 | 104 | // 从缓存返回数据 105 | Response response = request 106 | .parseNetworkResponse(new NetworkResponse(entry.data, 107 | entry.responseHeaders)); 108 | KJLoger.debugLog("CacheDispatcher:", "http resopnd from cache"); 109 | if (mConfig.useDelayCache) { 110 | sleep(mConfig.delayTime); 111 | } 112 | mDelivery.postResponse(request, response); 113 | } catch (InterruptedException e) { 114 | if (mQuit) { 115 | return; 116 | } else { 117 | continue; 118 | } 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/Delivery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Android Open Source Project,张涛. 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 org.kymjs.kjframe.http; 17 | 18 | /** 19 | * 分发器,将异步线程中的结果响应到UI线程中 20 | * 21 | * @author kymjs 22 | * 23 | */ 24 | public interface Delivery { 25 | /** 26 | * 分发响应结果 27 | * 28 | * @param request 29 | * @param response 30 | */ 31 | public void postResponse(Request request, Response response); 32 | 33 | /** 34 | * 分发Failure事件 35 | * 36 | * @param request 37 | * 请求 38 | * @param error 39 | * 异常原因 40 | */ 41 | public void postError(Request request, KJHttpException error); 42 | 43 | /** 44 | * 当有中介响应的时候,会被调用,首先返回中介响应,并执行runnable(实际就是再去请求网络)
45 | * Note:所谓中介响应:当本地有一个未过期缓存的时候会优先返回一个缓存,但如果这个缓存又是需要刷新的时候,会再次去请求网络, 46 | * 那么之前返回的那个有效但需要刷新的就是中介响应 47 | */ 48 | public void postResponse(Request request, Response response, 49 | Runnable runnable); 50 | 51 | /** 52 | * 分发下载进度事件 53 | * 54 | * @param request 55 | * @param fileSize 56 | * @param downloadedSize 57 | */ 58 | public void postDownloadProgress(Request request, long fileSize, 59 | long downloadedSize); 60 | 61 | public void postCancel(Request request); 62 | 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/DeliveryExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Android Open Source Project,张涛. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.util.concurrent.Executor; 20 | 21 | import android.os.Handler; 22 | 23 | /** 24 | * Http响应的分发器,这里用于把异步线程中的响应分发到UI线程中执行 25 | */ 26 | public class DeliveryExecutor implements Delivery { 27 | 28 | private final Executor mResponsePoster; 29 | 30 | public DeliveryExecutor(final Handler handler) { 31 | mResponsePoster = new Executor() { 32 | @Override 33 | public void execute(Runnable command) { 34 | handler.post(command); 35 | } 36 | }; 37 | } 38 | 39 | public DeliveryExecutor(Executor executor) { 40 | mResponsePoster = executor; 41 | } 42 | 43 | @Override 44 | public void postResponse(Request request, Response response) { 45 | postResponse(request, response, null); 46 | } 47 | 48 | /** 49 | * 当有中介响应的时候,会被调用,首先返回中介响应,并执行runnable(实际就是再去请求网络)
50 | * Note:所谓中介响应:当本地有一个未过期缓存的时候会优先返回一个缓存,但如果这个缓存又是需要刷新的时候,会再次去请求网络, 51 | * 那么之前返回的那个有效但需要刷新的就是中介响应 52 | */ 53 | @Override 54 | public void postResponse(Request request, Response response, 55 | Runnable runnable) { 56 | request.markDelivered(); 57 | mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, 58 | runnable)); 59 | } 60 | 61 | @Override 62 | public void postError(Request request, KJHttpException error) { 63 | Response response = Response.error(error); 64 | mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, 65 | null)); 66 | } 67 | 68 | /** 69 | * 一个Runnable,将网络请求响应分发到UI线程中 70 | */ 71 | @SuppressWarnings("rawtypes") 72 | private class ResponseDeliveryRunnable implements Runnable { 73 | private final Request mRequest; 74 | private final Response mResponse; 75 | private final Runnable mRunnable; 76 | 77 | public ResponseDeliveryRunnable(Request request, Response response, 78 | Runnable runnable) { 79 | mRequest = request; 80 | mResponse = response; 81 | mRunnable = runnable; 82 | } 83 | 84 | @SuppressWarnings("unchecked") 85 | @Override 86 | public void run() { 87 | if (mRequest.isCanceled()) { 88 | mRequest.finish("request已经取消,在分发时finish"); 89 | return; 90 | } 91 | 92 | if (mResponse.isSuccess()) { 93 | mRequest.deliverResponse(mResponse.headers, mResponse.result); 94 | } else { 95 | mRequest.deliverError(mResponse.error); 96 | } 97 | mRequest.requestFinish(); 98 | mRequest.finish("done"); 99 | if (mRunnable != null) { // 执行参数runnable 100 | mRunnable.run(); 101 | } 102 | } 103 | } 104 | 105 | @Override 106 | public void postDownloadProgress(Request request, long fileSize, 107 | long downloadedSize) { 108 | request.mCallback.onLoading(fileSize, downloadedSize); 109 | } 110 | 111 | @Override 112 | public void postCancel(Request request) {} 113 | } 114 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/DeliveryResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Android Open Source Project,张涛. 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 org.kymjs.kjframe.http; 17 | 18 | /** 19 | * 分发器,将异步线程中的结果响应到UI线程中 20 | * 21 | * @author kymjs (http://blog.kymjs.com) 22 | * 23 | */ 24 | public interface DeliveryResponse { 25 | /** 26 | * 分发响应结果 27 | * 28 | * @param request 29 | * @param response 30 | */ 31 | public void postResponse(Request request, Response response); 32 | 33 | /** 34 | * 分发Failure事件 35 | * 36 | * @param request 37 | * 请求 38 | * @param error 39 | * 异常原因 40 | */ 41 | public void postError(Request request, KJHttpException error); 42 | 43 | /** 44 | * 当有中介响应的时候,会被调用,首先返回中介响应,并执行runnable(实际就是再去请求网络)
45 | * Note:所谓中介响应:当本地有一个未过期缓存的时候会优先返回一个缓存,但如果这个缓存又是需要刷新的时候,会再次去请求网络, 46 | * 那么之前返回的那个有效但需要刷新的就是中介响应 47 | */ 48 | public void postResponse(Request request, Response response, 49 | Runnable runnable); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/DownloadController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 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 org.kymjs.kjframe.http; 17 | 18 | import android.util.Log; 19 | 20 | public class DownloadController { 21 | 22 | private final FileRequest mRequest; 23 | private final DownloadTaskQueue mQueue; 24 | 25 | private int mStatus; 26 | public static final int STATUS_WAITING = 0; 27 | public static final int STATUS_DOWNLOADING = 1; 28 | public static final int STATUS_PAUSE = 2; 29 | public static final int STATUS_SUCCESS = 3; 30 | public static final int STATUS_DISCARD = 4; 31 | 32 | DownloadController(DownloadTaskQueue queue, FileRequest request) { 33 | mRequest = request; 34 | mQueue = queue; 35 | } 36 | 37 | /* package */boolean equalsRequest(String storeFilePath, String url) { 38 | return (storeFilePath.equals(mRequest.getStoreFile().getAbsolutePath()) && url 39 | .equals(mRequest.getUrl())); 40 | } 41 | 42 | /* apckage */boolean equalsUrl(String url) { 43 | return url.equals(mRequest.getUrl()); 44 | } 45 | 46 | /** 47 | * 如果当前任务是等待态,让他转入运行态 48 | * 49 | * @return 50 | */ 51 | /* package */boolean doLoadOnWait() { 52 | if (mStatus == STATUS_WAITING) { 53 | mStatus = STATUS_DOWNLOADING; 54 | if (mQueue.getRequestQueue() != null) { 55 | mRequest.resume(); 56 | mQueue.getRequestQueue().add(mRequest); 57 | } else { 58 | Log.e("KJLibrary", 59 | "must call be DownloadTaskQueue.setRequestQueue()"); 60 | } 61 | return true; 62 | } else { 63 | return false; 64 | } 65 | } 66 | 67 | /** 68 | * 这个控制器负责的Request 69 | * 70 | * @return 71 | */ 72 | public FileRequest getRequest() { 73 | return mRequest; 74 | } 75 | 76 | /** 77 | * 获取文件的下载状态(待下载,正在下载,已暂停,已完成,已移除)
78 | * Controller.STATUS_WAITING = 0;
79 | * Controller.STATUS_DOWNLOADING = 1;
80 | * Controller.STATUS_PAUSE = 2;
81 | * Controller.STATUS_SUCCESS = 3;
82 | * Controller.STATUS_DISCARD = 4;
83 | */ 84 | public int getStatus() { 85 | return mStatus; 86 | } 87 | 88 | public boolean isDownloading() { 89 | return mStatus == STATUS_DOWNLOADING; 90 | } 91 | 92 | /** 93 | * 暂停任务 94 | * 95 | * @return 96 | */ 97 | public boolean pause() { 98 | if ((mStatus == STATUS_DOWNLOADING || mStatus == STATUS_WAITING) && mRequest != null && mQueue != null) { 99 | mStatus = STATUS_PAUSE; 100 | mRequest.cancel(); 101 | mQueue.wake(); 102 | return true; 103 | } 104 | return false; 105 | } 106 | 107 | /** 108 | * 恢复处于暂停态的任务 109 | * 110 | * @return 如果mQueue为null或当前状态不是STATUS_PAUSE,返回false 111 | * @deprecated 不推荐直接调用本方法,建议直接再次调用{@link DownloadTaskQueue#add(FileRequest)} 112 | */ 113 | @Deprecated 114 | public boolean resume() { 115 | if (mStatus == STATUS_PAUSE && mQueue != null) { 116 | mStatus = STATUS_WAITING; 117 | mQueue.wake(); 118 | return true; 119 | } else { 120 | return false; 121 | } 122 | } 123 | 124 | /** 125 | * 废弃当前下载任务 126 | * 127 | * @return 128 | */ 129 | public boolean removeTask() { 130 | if (mStatus == STATUS_DISCARD || mStatus == STATUS_SUCCESS) { 131 | return false; 132 | } 133 | if ((mStatus == STATUS_DOWNLOADING || mStatus == STATUS_WAITING) && mRequest != null) { 134 | mRequest.cancel(); 135 | mStatus = STATUS_DISCARD; 136 | } 137 | if (mRequest != null && mQueue != null) { 138 | mQueue.remove(mRequest.getUrl()); 139 | return true; 140 | } else { 141 | return false; 142 | } 143 | } 144 | } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/DownloadTaskQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 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 org.kymjs.kjframe.http; 17 | 18 | import android.os.Looper; 19 | 20 | import org.kymjs.kjframe.KJHttp; 21 | 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | 25 | /** 26 | * 负责维护当前正在下载状态
27 | * 对每个下载请求提供一个控制器,来控制下载的各种状态改变 28 | * 29 | * @author kymjs 30 | */ 31 | public class DownloadTaskQueue { 32 | private final int mParallelTaskCount; // 最大同时下载量 33 | private final List mTaskQueue; // 以链表的形式储存下载控制器 34 | private KJHttp mRequestQueue; // 关联一个请求队列,目的是在恢复下载的时候可以再次将下载请求加入到请求队列中 35 | 36 | public DownloadTaskQueue(int parallelTaskCount) { 37 | if (parallelTaskCount >= HttpConfig.NETWORK_POOL_SIZE) { 38 | parallelTaskCount = HttpConfig.NETWORK_POOL_SIZE - 1; 39 | } 40 | mParallelTaskCount = parallelTaskCount; 41 | mTaskQueue = new LinkedList<>(); 42 | } 43 | 44 | public List getTaskQueue() { 45 | return mTaskQueue; 46 | } 47 | 48 | /** 49 | * 清空全部下载任务 50 | */ 51 | public void clearAll() { 52 | synchronized (mTaskQueue) { 53 | while (mTaskQueue.size() > 0) { 54 | mTaskQueue.get(0).removeTask(); 55 | } 56 | } 57 | } 58 | 59 | /** 60 | * 添加一个下载请求,如果这个请求已经存在,则尝试唤醒这个请求 61 | * 62 | * @param request 要添加的下载请求 63 | */ 64 | public void add(FileRequest request) { 65 | throwIfNotOnMainThread(); 66 | DownloadController requestTask = requestExist(request); 67 | if (requestTask != null) { 68 | requestTask.removeTask(); 69 | } 70 | synchronized (mTaskQueue) { 71 | mTaskQueue.add(new DownloadController(this, request)); 72 | } 73 | wake(); 74 | } 75 | 76 | /** 77 | * 移除一个下载任务 78 | * 79 | * @param url 要移除的url 80 | */ 81 | public void remove(String url) { 82 | for (DownloadController controller : mTaskQueue) { 83 | if (controller.equalsUrl(url)) { 84 | synchronized (mTaskQueue) { 85 | mTaskQueue.remove(controller); 86 | wake(); 87 | return; 88 | } 89 | } 90 | } 91 | } 92 | 93 | /** 94 | * @param storeFilePath 下载后文件在本地的地址 95 | * @param url 下载的url 96 | * @return DownloadController下载控制器 97 | */ 98 | public DownloadController get(String storeFilePath, String url) { 99 | synchronized (mTaskQueue) { 100 | for (DownloadController controller : mTaskQueue) { 101 | if (controller.equalsRequest(storeFilePath, url)) 102 | return controller; 103 | } 104 | } 105 | return null; 106 | } 107 | 108 | public void setRequestQueue(KJHttp requestQueue) { 109 | this.mRequestQueue = requestQueue; 110 | } 111 | 112 | /* package */KJHttp getRequestQueue() { 113 | return mRequestQueue; 114 | } 115 | 116 | /* package */void wake() { 117 | synchronized (mTaskQueue) { 118 | int parallelTaskCount = 0; // 同时下载的数量 119 | 120 | for (DownloadController controller : mTaskQueue) { 121 | if (controller.isDownloading()) { 122 | parallelTaskCount++; 123 | } 124 | } 125 | 126 | // 判断同时下载数量是否超过最大值 127 | for (DownloadController controller : mTaskQueue) { 128 | if (parallelTaskCount < mParallelTaskCount) { 129 | if (controller.doLoadOnWait()) { 130 | parallelTaskCount++; 131 | } 132 | } else { 133 | break; 134 | } 135 | } 136 | } 137 | } 138 | 139 | /** 140 | * 必须在主线程执行 141 | */ 142 | private void throwIfNotOnMainThread() { 143 | if (Looper.myLooper() != Looper.getMainLooper()) { 144 | throw new IllegalStateException( 145 | "FileDownloader must be invoked from the main thread."); 146 | } 147 | } 148 | 149 | /** 150 | * 如果这个请求本身就存在,则直接返回这个请求 151 | * 152 | * @param request 要被判断的request 153 | * @return 如果这个请求本身就存在,则直接返回这个请求 154 | */ 155 | private DownloadController requestExist(FileRequest request) { 156 | for (DownloadController task : mTaskQueue) { 157 | FileRequest req = task.getRequest(); 158 | if (request.getUrl().equals(req.getUrl()) 159 | && request.getStoreFile().getAbsolutePath() 160 | .equals(req.getStoreFile().getAbsolutePath())) { 161 | return task; 162 | } 163 | } 164 | return null; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/FormRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 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 org.kymjs.kjframe.http; 17 | 18 | import org.kymjs.kjframe.utils.KJLoger; 19 | 20 | import java.io.ByteArrayOutputStream; 21 | import java.io.IOException; 22 | import java.util.Map; 23 | 24 | /** 25 | * Form表单形式的Http请求 26 | * 27 | * @author kymjs 28 | */ 29 | public class FormRequest extends Request { 30 | 31 | private final HttpParams mParams; 32 | 33 | public FormRequest(String url, HttpCallBack callback) { 34 | this(HttpMethod.GET, url, null, callback); 35 | } 36 | 37 | public FormRequest(int httpMethod, String url, HttpParams params, 38 | HttpCallBack callback) { 39 | super(httpMethod, url, callback); 40 | if (params == null) { 41 | params = new HttpParams(); 42 | } 43 | this.mParams = params; 44 | } 45 | 46 | @Override 47 | public String getCacheKey() { 48 | if (getMethod() == HttpMethod.POST) { 49 | return getUrl() + mParams.getUrlParams(); 50 | } else { 51 | return getUrl(); 52 | } 53 | } 54 | 55 | @Override 56 | public String getBodyContentType() { 57 | if (mParams.getContentType() != null) { 58 | return mParams.getContentType().get(KJHTTP.CONTENT_TYPE); 59 | } else { 60 | return super.getBodyContentType(); 61 | } 62 | } 63 | 64 | @Override 65 | public Map getHeaders() { 66 | return mParams.getHeaders(); 67 | } 68 | 69 | @Override 70 | public byte[] getBody() { 71 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 72 | try { 73 | mParams.writeTo(bos); 74 | } catch (IOException e) { 75 | KJLoger.debug("FormRequest75--->IOException writing to ByteArrayOutputStream"); 76 | } 77 | return bos.toByteArray(); 78 | } 79 | 80 | @Override 81 | public Response parseNetworkResponse(NetworkResponse response) { 82 | return Response.success(response.data, response.headers, 83 | HttpHeaderParser.parseCacheHeaders(mConfig, response)); 84 | } 85 | 86 | @Override 87 | protected void deliverResponse(Map headers, byte[] response) { 88 | if (mCallback != null) { 89 | mCallback.onSuccess(headers, response); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/HTTPSTrustManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, 张涛. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.security.KeyManagementException; 20 | import java.security.NoSuchAlgorithmException; 21 | import java.security.SecureRandom; 22 | import java.security.cert.X509Certificate; 23 | 24 | import javax.net.ssl.HostnameVerifier; 25 | import javax.net.ssl.HttpsURLConnection; 26 | import javax.net.ssl.SSLContext; 27 | import javax.net.ssl.SSLSession; 28 | import javax.net.ssl.TrustManager; 29 | import javax.net.ssl.X509TrustManager; 30 | 31 | /** 32 | * @author kymjs (http://www.kymjs.com/) on 9/23/15. 33 | */ 34 | public class HTTPSTrustManager implements X509TrustManager { 35 | 36 | private static TrustManager[] trustManagers; 37 | private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{}; 38 | 39 | @Override 40 | public void checkClientTrusted( 41 | java.security.cert.X509Certificate[] x509Certificates, String s) 42 | throws java.security.cert.CertificateException { 43 | // To change body of implemented methods use File | Settings | File 44 | // Templates. 45 | } 46 | 47 | @Override 48 | public void checkServerTrusted( 49 | java.security.cert.X509Certificate[] x509Certificates, String s) 50 | throws java.security.cert.CertificateException { 51 | // To change body of implemented methods use File | Settings | File 52 | // Templates. 53 | } 54 | 55 | public boolean isClientTrusted(X509Certificate[] chain) { 56 | return true; 57 | } 58 | 59 | public boolean isServerTrusted(X509Certificate[] chain) { 60 | return true; 61 | } 62 | 63 | @Override 64 | public X509Certificate[] getAcceptedIssuers() { 65 | return _AcceptedIssuers; 66 | } 67 | 68 | public static void allowAllSSL() { 69 | HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { 70 | @Override 71 | public boolean verify(String arg0, SSLSession arg1) { 72 | return true; 73 | } 74 | }); 75 | 76 | SSLContext context = null; 77 | if (trustManagers == null) { 78 | trustManagers = new TrustManager[]{new HTTPSTrustManager()}; 79 | } 80 | 81 | try { 82 | context = SSLContext.getInstance("TLS"); 83 | context.init(null, trustManagers, new SecureRandom()); 84 | } catch (NoSuchAlgorithmException e) { 85 | e.printStackTrace(); 86 | } catch (KeyManagementException e) { 87 | e.printStackTrace(); 88 | } 89 | HttpsURLConnection.setDefaultSSLSocketFactory(context 90 | .getSocketFactory()); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/HttpCallBack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.http; 17 | 18 | import android.graphics.Bitmap; 19 | 20 | import java.util.Map; 21 | 22 | /** 23 | * Http请求回调类
24 | * 25 | * 创建时间 2014-8-7 26 | * 27 | * @author kymjs (https://github.com/kymjs) 28 | * @version 1.4 29 | */ 30 | public abstract class HttpCallBack { 31 | 32 | /** 33 | * 请求开始之前回调 34 | */ 35 | public void onPreStart() { 36 | onPreStar(); 37 | } 38 | 39 | /** 40 | * 拼写错误,请使用onPreStart() 41 | */ 42 | @Deprecated 43 | public void onPreStar() {} 44 | 45 | /** 46 | * Http请求成功时回调 47 | * 48 | * @param t 49 | * HttpRequest返回信息 50 | */ 51 | public void onSuccess(String t) {} 52 | 53 | /** 54 | * Http请求成功时回调 55 | * 56 | * @param t 57 | * HttpRequest返回信息 58 | */ 59 | public void onSuccess(byte[] t) { 60 | if (t != null) { 61 | onSuccess(new String(t)); 62 | } 63 | } 64 | 65 | /** 66 | * Http请求成功时回调 67 | * 68 | * @param headers 69 | * HttpRespond头 70 | * @param t 71 | * HttpRequest返回信息 72 | */ 73 | public void onSuccess(Map headers, byte[] t) { 74 | onSuccess(t); 75 | } 76 | 77 | /** 78 | * 仅在KJBitmap中可用,图片加载完成时回调 79 | * 80 | * @param t 81 | */ 82 | public void onSuccess(Bitmap t) {} 83 | 84 | /** 85 | * Http请求失败时回调 86 | * 87 | * @param errorNo 88 | * 错误码 89 | * @param strMsg 90 | * 错误原因 91 | */ 92 | public void onFailure(int errorNo, String strMsg) {} 93 | 94 | /** 95 | * Http请求结束后回调 96 | */ 97 | public void onFinish() {} 98 | 99 | /** 100 | * 进度回调,仅支持Download时使用 101 | * 102 | * @param count 103 | * 总数 104 | * @param current 105 | * 当前进度 106 | */ 107 | public void onLoading(long count, long current) {} 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/HttpConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 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 org.kymjs.kjframe.http; 17 | 18 | import android.net.http.AndroidHttpClient; 19 | import android.os.Build; 20 | import android.os.Handler; 21 | import android.os.Looper; 22 | 23 | import org.kymjs.kjframe.utils.FileUtils; 24 | 25 | import java.io.File; 26 | 27 | import javax.net.ssl.SSLSocketFactory; 28 | 29 | /** 30 | * Http配置器 31 | * 32 | * @author kymjs 33 | */ 34 | public class HttpConfig { 35 | 36 | public static boolean DEBUG = true; 37 | 38 | /** 39 | * 缓存文件夹 40 | **/ 41 | public static String CACHEPATH = "KJLibrary/cache"; 42 | /** 43 | * 线程池大小 44 | **/ 45 | public static int NETWORK_POOL_SIZE = 4; 46 | /** 47 | * Http请求超时时间 48 | **/ 49 | public static int TIMEOUT = 5000; 50 | 51 | /** 52 | * 磁盘缓存大小 53 | */ 54 | public static int DISK_CACHE_SIZE = 5 * 1024 * 1024; 55 | /** 56 | * 缓存有效时间: 默认5分钟 57 | */ 58 | public int cacheTime = 5; 59 | 60 | /** 61 | * 在Http请求中,如果服务器也声明了对缓存时间的控制,那么是否优先使用服务器设置: 默认false 62 | */ 63 | public static boolean useServerControl = false; 64 | 65 | /** 66 | * 为了更真实的模拟网络请求。如果启用,在读取完成以后,并不立即返回而是延迟500毫秒再返回 67 | */ 68 | public boolean useDelayCache = false; 69 | /** 70 | * 如果启用了useDelayCache,本属性才有效。单位:ms 71 | */ 72 | public long delayTime = 500; 73 | 74 | /** 75 | * 同时允许多少个下载任务,建议不要太大(注意:本任务最大值不能超过NETWORK_POOL_SIZE) 76 | */ 77 | public static int MAX_DOWNLOAD_TASK_SIZE = 2; 78 | 79 | /** 80 | * 缓存器 81 | **/ 82 | public static Cache mCache; 83 | /** 84 | * 网络请求执行器 85 | **/ 86 | public Network mNetwork; 87 | /** 88 | * Http响应的分发器 89 | **/ 90 | public Delivery mDelivery; 91 | /** 92 | * 下载控制器队列,对每个下载任务都有一个控制器负责控制下载 93 | */ 94 | public DownloadTaskQueue mController; 95 | /** 96 | * 全局的cookie,如果每次Http请求都需要传递固定的cookie,可以设置本项 97 | */ 98 | public static String sCookie; 99 | 100 | public HttpConfig() { 101 | if (mCache == null) { 102 | File folder = FileUtils.getSaveFolder(CACHEPATH); 103 | mCache = new DiskCache(folder, DISK_CACHE_SIZE); 104 | } 105 | mNetwork = new Network(httpStackFactory()); 106 | mDelivery = new DeliveryExecutor(new Handler(Looper.getMainLooper())); 107 | mController = new DownloadTaskQueue(HttpConfig.MAX_DOWNLOAD_TASK_SIZE); 108 | } 109 | 110 | /** 111 | * 创建HTTP请求端的生产器(将抽象工厂缩减为方法) 112 | * 113 | * @return 114 | */ 115 | public HttpStack httpStackFactory() { 116 | if (Build.VERSION.SDK_INT >= 11) { 117 | return new HttpConnectStack(); 118 | } else { 119 | return new HttpClientStack( 120 | AndroidHttpClient.newInstance("kjframe/0")); 121 | } 122 | } 123 | 124 | public HttpStack httpStackFactory(SSLSocketFactory ssl) { 125 | return new HttpConnectStack(null, ssl); 126 | } 127 | 128 | public void setCookieString(String cookie) { 129 | sCookie = cookie; 130 | } 131 | 132 | public String getCookieString() { 133 | return sCookie; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/HttpHeaderParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project, 张涛 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.text.ParseException; 20 | import java.text.SimpleDateFormat; 21 | import java.util.Date; 22 | import java.util.Map; 23 | 24 | /** 25 | * 用于解析HttpHeader的工具类 26 | */ 27 | public class HttpHeaderParser { 28 | 29 | public static Cache.Entry parseCacheHeaders(HttpConfig httpconfig, 30 | NetworkResponse response) { 31 | long now = System.currentTimeMillis(); 32 | 33 | Map headers = response.headers; 34 | long serverDate = 0; // 服务器返回本次响应时的时间 35 | long maxAge = 0; // 本次缓存的有效时间 36 | boolean hasCacheControl = false; // 服务器是否有声明缓存控制 37 | String serverEtag = null; 38 | String tempStr; 39 | 40 | tempStr = headers.get("Date"); 41 | if (tempStr != null) { 42 | serverDate = parseDateAsEpoch(tempStr); 43 | } 44 | 45 | // 如果服务器有声明缓存控制器,则使用服务器的控制逻辑 46 | tempStr = headers.get("Cache-Control"); 47 | if (tempStr != null) { 48 | hasCacheControl = true; 49 | String[] tokens = tempStr.split(","); 50 | for (int i = 0; i < tokens.length; i++) { 51 | String token = tokens[i].trim(); 52 | // 如果服务器说不缓存这次数据,那么就不缓存了。。。。 53 | if (token.equals("no-cache") || token.equals("no-store")) { 54 | return null; 55 | } else if (token.startsWith("max-age=")) { 56 | try { 57 | // 如果服务器声明了缓存时间长度,则使用服务器缓存时间长度 58 | maxAge = Long.parseLong(token.substring(8)); 59 | } catch (Exception e) { 60 | } 61 | } else if (token.equals("must-revalidate") 62 | || token.equals("proxy-revalidate")) { 63 | // 如果服务器声明必须重新验证,或必须使用代理验证,则相当于本次数据是一次性的 64 | maxAge = 0; 65 | } 66 | } 67 | } 68 | 69 | long serverExpires = 0; // 如果有到期时限,则也使用服务器的到期时限 70 | tempStr = headers.get("Expires"); 71 | if (tempStr != null) { 72 | serverExpires = parseDateAsEpoch(tempStr); 73 | } 74 | 75 | long softExpire = 0; // 定义多久以后需要刷新 76 | serverEtag = headers.get("ETag"); 77 | if (hasCacheControl) { 78 | softExpire = now + maxAge * 1000; 79 | } else if (serverDate > 0 && serverExpires >= serverDate) { 80 | softExpire = now + (serverExpires - serverDate); 81 | } 82 | 83 | Cache.Entry entry = new Cache.Entry(); 84 | entry.data = response.data; 85 | 86 | if (HttpConfig.useServerControl) { 87 | entry.ttl = softExpire; 88 | } else { 89 | entry.ttl = now + httpconfig.cacheTime * 60000; // 分钟转毫秒 90 | } 91 | entry.etag = serverEtag; 92 | entry.serverDate = serverDate; 93 | entry.responseHeaders = headers; 94 | return entry; 95 | } 96 | 97 | /** 98 | * 使用RFC1123格式解析服务器返回的时间 99 | * 100 | * @return 如果解析异常,返回null 101 | */ 102 | public static long parseDateAsEpoch(String dateStr) { 103 | try { 104 | SimpleDateFormat sdf = new SimpleDateFormat(); 105 | Date date = sdf.parse(dateStr); 106 | return date.getTime(); 107 | } catch (ParseException e) { 108 | return 0; 109 | } 110 | } 111 | 112 | /** 113 | * 返回这个内容头的编码,如果没有则使用HTTP默认(ISO-8859-1)指定的字符集 114 | */ 115 | public static String parseCharset(Map headers) { 116 | String contentType = headers.get(KJHTTP.CONTENT_TYPE); 117 | if (contentType != null) { 118 | String[] params = contentType.split(";"); 119 | for (int i = 1; i < params.length; i++) { 120 | String[] pair = params[i].trim().split("="); 121 | if (pair.length == 2) { 122 | if (pair[0].equals("charset")) { 123 | return pair[1]; 124 | } 125 | } 126 | } 127 | } 128 | return KJHTTP.DEFAULT_CONTENT_CHARSET; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/HttpStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.io.IOException; 20 | import java.util.Map; 21 | 22 | /** 23 | * Http请求端,已知实现类: 24 | * 25 | * @see HttpConnectStack 26 | * @see HttpClientStack 27 | * 28 | * @author kymjs 29 | * 30 | */ 31 | public interface HttpStack { 32 | /** 33 | * 让Http请求端去发起一个Request 34 | * 用自定义的KJHttpResponse替代原有的HttpReponse,从而达到底层联网接口与HttpClient彻底解耦的目标(by 我是无名氏) 35 | * 36 | * @param request 37 | * 一次实际请求集合 38 | * @param additionalHeaders 39 | * Http请求头 40 | * @return 一个Http响应 41 | */ 42 | public KJHttpResponse performRequest(Request request, 43 | Map additionalHeaders) throws IOException; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/HttpUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 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 org.kymjs.kjframe.http; 17 | 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | import java.util.Map; 21 | import java.util.zip.GZIPInputStream; 22 | 23 | import org.kymjs.kjframe.utils.KJLoger; 24 | 25 | import android.text.TextUtils; 26 | 27 | /** 28 | * HTTP工具类 29 | * 将HttpUtils中的所有HttpResponse替换成自定义的KJHttpResponse(by 我是无名氏) 30 | * @author 张涛 31 | * 32 | */ 33 | public class HttpUtils { 34 | 35 | public static byte[] responseToBytes(KJHttpResponse response) 36 | throws IOException, KJHttpException { 37 | PoolingByteArrayOutputStream bytes = new PoolingByteArrayOutputStream( 38 | ByteArrayPool.get(), (int) response.getContentLength()); 39 | byte[] buffer = null; 40 | InputStream in = null; 41 | try { 42 | in = response.getContent(); 43 | if (isGzipContent(response) && !(in instanceof GZIPInputStream)) { 44 | in = new GZIPInputStream(in); 45 | } 46 | 47 | if (in == null) { 48 | throw new KJHttpException("服务器连接异常"); 49 | } 50 | 51 | buffer = ByteArrayPool.get().getBuf(1024); 52 | int count; 53 | while ((count = in.read(buffer)) != -1) { 54 | bytes.write(buffer, 0, count); 55 | } 56 | return bytes.toByteArray(); 57 | } finally { 58 | try { 59 | // Close the InputStream and release the resources by 60 | // "consuming the content". 61 | if(in != null) { 62 | in.close(); 63 | } 64 | } catch (IOException e) { 65 | // This can happen if there was an exception above that left the 66 | // entity in 67 | // an invalid state. 68 | KJLoger.debug("Error occured when calling consumingContent"); 69 | } 70 | ByteArrayPool.get().returnBuf(buffer); 71 | bytes.close(); 72 | } 73 | } 74 | 75 | /** Returns the charset specified in the Content-Type of this header. */ 76 | public static String getCharset(KJHttpResponse response) { 77 | Map header = response.getHeaders(); 78 | if (header != null) { 79 | String contentType = header.get(KJHTTP.CONTENT_TYPE); 80 | if (!TextUtils.isEmpty(contentType)) { 81 | String[] params = contentType.split(";"); 82 | for (int i = 1; i < params.length; i++) { 83 | String[] pair = params[i].trim().split("="); 84 | if (pair.length == 2) { 85 | if (pair[0].equals("charset")) { 86 | return pair[1]; 87 | } 88 | } 89 | } 90 | } 91 | } 92 | return null; 93 | } 94 | 95 | public static String getHeader(KJHttpResponse response, String key) { 96 | String headerValue = response.getHeaders().get(key); 97 | return headerValue == null ? null : headerValue; 98 | } 99 | 100 | public static boolean isSupportRange(KJHttpResponse response) { 101 | if (TextUtils.equals(getHeader(response, "Accept-Ranges"), "bytes")) { 102 | return true; 103 | } 104 | String value = getHeader(response, "Content-Range"); 105 | return value != null && value.startsWith("bytes"); 106 | } 107 | 108 | public static boolean isGzipContent(KJHttpResponse response) { 109 | return TextUtils 110 | .equals(getHeader(response, "Content-Encoding"), "gzip"); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/JsonRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.io.UnsupportedEncodingException; 20 | import java.util.Map; 21 | 22 | import org.kymjs.kjframe.utils.KJLoger; 23 | 24 | /** 25 | * 用来发起application/json格式的请求的,我们平时所使用的是form表单提交的参数,而使用JsonRequest提交的是json参数。 26 | */ 27 | public class JsonRequest extends Request { 28 | private static final String PROTOCOL_CHARSET = "utf-8"; 29 | private static final String PROTOCOL_CONTENT_TYPE = String.format( 30 | "application/json; charset=%s", PROTOCOL_CHARSET); 31 | 32 | private final String mRequestBody; 33 | private final HttpParams mParams; 34 | 35 | public JsonRequest(int method, String url, HttpParams params, 36 | HttpCallBack callback) { 37 | super(method, url, callback); 38 | mRequestBody = params.getJsonParams(); 39 | mParams = params; 40 | } 41 | 42 | @Override 43 | public Map getHeaders() { 44 | return mParams.getHeaders(); 45 | } 46 | 47 | @Override 48 | protected void deliverResponse(Map headers, byte[] response) { 49 | if (mCallback != null) { 50 | mCallback.onSuccess(headers, response); 51 | } 52 | } 53 | 54 | @Override 55 | public Response parseNetworkResponse(NetworkResponse response) { 56 | return Response.success(response.data, response.headers, 57 | HttpHeaderParser.parseCacheHeaders(mConfig, response)); 58 | } 59 | 60 | @Override 61 | public String getBodyContentType() { 62 | return PROTOCOL_CONTENT_TYPE; 63 | } 64 | 65 | @Override 66 | public String getCacheKey() { 67 | if (getMethod() == HttpMethod.POST) { 68 | return getUrl() + mParams.getUrlParams(); 69 | } else { 70 | return getUrl(); 71 | } 72 | } 73 | 74 | @Override 75 | public byte[] getBody() { 76 | try { 77 | return mRequestBody == null ? null : mRequestBody 78 | .getBytes(PROTOCOL_CHARSET); 79 | } catch (UnsupportedEncodingException uee) { 80 | KJLoger.debug( 81 | "Unsupported Encoding while trying to get the bytes of %s using %s", 82 | mRequestBody, PROTOCOL_CHARSET); 83 | return null; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/KJHTTP.java: -------------------------------------------------------------------------------- 1 | package org.kymjs.kjframe.http; 2 | 3 | /** 4 | * 用于替换HttpClient中的HTTP(by 我是无名氏) 5 | */ 6 | public class KJHTTP { 7 | 8 | public static final String ASCII = "ASCII"; 9 | 10 | public static final String CHARSET_PARAM = "; charset="; 11 | 12 | public static final String CHUNK_CODING = "chunked"; 13 | 14 | public static final String CONN_CLOSE = "Close"; 15 | 16 | public static final String CONN_DIRECTIVE = "Connection"; 17 | 18 | public static final String CONN_KEEP_ALIVE = "Keep-Alive"; 19 | 20 | public static final String CONTENT_ENCODING = "Content-Encoding"; 21 | 22 | public static final String CONTENT_LEN = "Content-Length"; 23 | 24 | public static final String CONTENT_TYPE = "Content-Type"; 25 | 26 | public static final int CR = 13; 27 | 28 | public static final String DATE_HEADER = "Date"; 29 | 30 | public static final String DEFAULT_CONTENT_CHARSET = "ISO-8859-1"; 31 | 32 | public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream"; 33 | 34 | public static final String DEFAULT_PROTOCOL_CHARSET = "US-ASCII"; 35 | 36 | public static final String EXPECT_CONTINUE = "100-continue"; 37 | 38 | public static final String EXPECT_DIRECTIVE = "Expect"; 39 | 40 | public static final int HT = 9; 41 | 42 | public static final String IDENTITY_CODING = "identity"; 43 | 44 | public static final String ISO_8859_1 = "ISO-8859-1"; 45 | 46 | public static final int LF = 10; 47 | 48 | public static final String OCTET_STREAM_TYPE = "application/octet-stream"; 49 | 50 | public static final String PLAIN_TEXT_TYPE = "text/plain"; 51 | 52 | public static final String SERVER_HEADER = "Server"; 53 | 54 | public static final int SP = 32; 55 | 56 | public static final String TARGET_HOST = "Host"; 57 | 58 | public static final String TRANSFER_ENCODING = "Transfer-Encoding"; 59 | 60 | public static final String USER_AGENT = "User-Agent"; 61 | 62 | public static final String US_ASCII = "US-ASCII"; 63 | 64 | public static final String UTF_16 = "UTF-16"; 65 | 66 | public static final String UTF_8 = "UTF-8"; 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/KJHttpException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | /** 20 | * 整个框架异常的基类 21 | */ 22 | @SuppressWarnings("serial") 23 | public class KJHttpException extends Exception { 24 | public final NetworkResponse networkResponse; 25 | 26 | public KJHttpException() { 27 | networkResponse = null; 28 | } 29 | 30 | public KJHttpException(NetworkResponse response) { 31 | networkResponse = response; 32 | } 33 | 34 | public KJHttpException(String exceptionMessage) { 35 | super(exceptionMessage); 36 | networkResponse = null; 37 | } 38 | 39 | public KJHttpException(String exceptionMessage, NetworkResponse response) { 40 | super(exceptionMessage); 41 | networkResponse = response; 42 | } 43 | 44 | public KJHttpException(String exceptionMessage, Throwable reason) { 45 | super(exceptionMessage, reason); 46 | networkResponse = null; 47 | } 48 | 49 | public KJHttpException(Throwable cause) { 50 | super(cause); 51 | networkResponse = null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/KJHttpResponse.java: -------------------------------------------------------------------------------- 1 | package org.kymjs.kjframe.http; 2 | 3 | import java.io.InputStream; 4 | import java.util.Map; 5 | 6 | /** 7 | * 此类用于替换HttpClient中的HttpResponse,最大程度减少HTTP框架与HttpClient的黏连程度,从而达到适配Android6.0的目的 8 | * @author 我是无名氏 9 | */ 10 | public class KJHttpResponse { 11 | 12 | /** 13 | * 消息头 14 | */ 15 | private Map headers; 16 | 17 | /** 18 | * 状态码 19 | */ 20 | private int statusCode; 21 | 22 | /** 23 | * 响应消息 24 | */ 25 | private String responseMessage; 26 | 27 | /** 28 | * 报文流 29 | */ 30 | private InputStream content; 31 | 32 | /** 33 | * 报文编码 34 | */ 35 | private String contentEncoding; 36 | 37 | /** 38 | * 报文类型 39 | */ 40 | private String contentType; 41 | 42 | /** 43 | * 报文长度 44 | */ 45 | private long contentLength; 46 | 47 | public Map getHeaders() { 48 | return headers; 49 | } 50 | 51 | public void setHeaders(Map headers) { 52 | this.headers = headers; 53 | } 54 | 55 | public int getStatusCode() { 56 | return statusCode; 57 | } 58 | 59 | public void setStatusCode(int statusCode) { 60 | this.statusCode = statusCode; 61 | } 62 | 63 | public String getResponseMessage() { 64 | return responseMessage; 65 | } 66 | 67 | public void setResponseMessage(String responseMessage) { 68 | this.responseMessage = responseMessage; 69 | } 70 | 71 | public InputStream getContent() { 72 | return content; 73 | } 74 | 75 | public void setContent(InputStream content) { 76 | this.content = content; 77 | } 78 | 79 | public String getContentEncoding() { 80 | return contentEncoding; 81 | } 82 | 83 | public void setContentEncoding(String contentEncoding) { 84 | this.contentEncoding = contentEncoding; 85 | } 86 | 87 | public String getContentType() { 88 | return contentType; 89 | } 90 | 91 | public void setContentType(String contentType) { 92 | this.contentType = contentType; 93 | } 94 | 95 | public long getContentLength() { 96 | return contentLength; 97 | } 98 | 99 | public void setContentLength(long contentLength) { 100 | this.contentLength = contentLength; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/KJHttpStatus.java: -------------------------------------------------------------------------------- 1 | package org.kymjs.kjframe.http; 2 | 3 | /** 4 | * 此类用于替换HttpClient中的HttpStatus 5 | * @author 我是无名氏 6 | * 7 | */ 8 | public class KJHttpStatus { 9 | 10 | public static final int SC_ACCEPTED = 202; 11 | 12 | public static final int SC_BAD_GATEWAY = 502; 13 | 14 | public static final int SC_BAD_REQUEST = 400; 15 | 16 | public static final int SC_CONFLICT = 409; 17 | 18 | public static final int SC_CONTINUE = 100; 19 | 20 | public static final int SC_CREATED = 201; 21 | 22 | public static final int SC_EXPECTATION_FAILED = 417; 23 | 24 | public static final int SC_FAILED_DEPENDENCY = 424; 25 | 26 | public static final int SC_FORBIDDEN = 403; 27 | 28 | public static final int SC_GATEWAY_TIMEOUT = 504; 29 | 30 | public static final int SC_GONE = 410; 31 | 32 | public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505; 33 | 34 | public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419; 35 | 36 | public static final int SC_INSUFFICIENT_STORAGE = 507; 37 | 38 | public static final int SC_INTERNAL_SERVER_ERROR = 500; 39 | 40 | public static final int SC_LENGTH_REQUIRED = 411; 41 | 42 | public static final int SC_LOCKED = 423; 43 | 44 | public static final int SC_METHOD_FAILURE = 420; 45 | 46 | public static final int SC_METHOD_NOT_ALLOWED = 405; 47 | 48 | public static final int SC_MOVED_PERMANENTLY = 301; 49 | 50 | public static final int SC_MOVED_TEMPORARILY = 302; 51 | 52 | public static final int SC_MULTIPLE_CHOICES = 300; 53 | 54 | public static final int SC_MULTI_STATUS = 207; 55 | 56 | public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203; 57 | 58 | public static final int SC_NOT_ACCEPTABLE = 406; 59 | 60 | public static final int SC_NOT_FOUND = 404; 61 | 62 | public static final int SC_NOT_IMPLEMENTED = 501; 63 | 64 | public static final int SC_NOT_MODIFIED = 304; 65 | 66 | public static final int SC_NO_CONTENT = 204; 67 | 68 | public static final int SC_OK = 200; 69 | 70 | public static final int SC_PARTIAL_CONTENT = 206; 71 | 72 | public static final int SC_PAYMENT_REQUIRED = 402; 73 | 74 | public static final int SC_PRECONDITION_FAILED = 412; 75 | 76 | public static final int SC_PROCESSING = 102; 77 | 78 | public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407; 79 | 80 | public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; 81 | 82 | public static final int SC_REQUEST_TIMEOUT = 408; 83 | 84 | public static final int SC_REQUEST_TOO_LONG = 413; 85 | 86 | public static final int SC_REQUEST_URI_TOO_LONG = 414; 87 | 88 | public static final int SC_RESET_CONTENT = 205; 89 | 90 | public static final int SC_SEE_OTHER = 303; 91 | 92 | public static final int SC_SERVICE_UNAVAILABLE = 503; 93 | 94 | public static final int SC_SWITCHING_PROTOCOLS = 101; 95 | 96 | public static final int SC_TEMPORARY_REDIRECT = 307; 97 | 98 | public static final int SC_UNAUTHORIZED = 401; 99 | 100 | public static final int SC_UNPROCESSABLE_ENTITY = 422; 101 | 102 | public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415; 103 | 104 | public static final int SC_USE_PROXY = 305; 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/NetworkDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project, 张涛 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.util.concurrent.BlockingQueue; 20 | 21 | import org.kymjs.kjframe.utils.KJLoger; 22 | 23 | import android.annotation.TargetApi; 24 | import android.net.TrafficStats; 25 | import android.os.Build; 26 | import android.os.Process; 27 | 28 | /** 29 | * 网络请求任务的调度器,负责不停的从RequestQueue中取Request并交给NetWork执行, 30 | * 执行完成后分发执行结果到UI线程的回调并缓存结果到缓存器 31 | */ 32 | public class NetworkDispatcher extends Thread { 33 | private final BlockingQueue> mQueue; // 正在发生请求的队列 34 | private final Network mNetwork; // 网络请求执行器 35 | private final Cache mCache; // 缓存器 36 | private final Delivery mDelivery; 37 | private volatile boolean mQuit = false; // 标记是否退出本线程 38 | 39 | public NetworkDispatcher(BlockingQueue> queue, Network network, 40 | Cache cache, Delivery delivery) { 41 | mQueue = queue; 42 | mNetwork = network; 43 | mCache = cache; 44 | mDelivery = delivery; 45 | } 46 | 47 | /** 48 | * 强制退出本线程 49 | */ 50 | public void quit() { 51 | mQuit = true; 52 | interrupt(); 53 | } 54 | 55 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 56 | private void addTrafficStatsTag(Request request) { 57 | // Tag the request (if API >= 14) 58 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 59 | TrafficStats.setThreadStatsTag(request.getTrafficStatsTag()); 60 | } 61 | } 62 | 63 | /** 64 | * 阻塞态工作,不停的从队列中获取任务,直到退出。并把取出的request使用Network执行请求,然后NetWork返回一个NetWork响应 65 | */ 66 | @Override 67 | public void run() { 68 | Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 69 | while (true) { 70 | Request request; 71 | try { 72 | request = mQueue.take(); 73 | } catch (InterruptedException e) { 74 | if (mQuit) { 75 | return; 76 | } else { 77 | continue; 78 | } 79 | } 80 | try { 81 | if (request.isCanceled()) { 82 | request.finish("任务已经取消"); 83 | continue; 84 | } 85 | addTrafficStatsTag(request); 86 | 87 | NetworkResponse networkResponse = mNetwork 88 | .performRequest(request); 89 | // 如果这个响应已经被分发,则不会再次分发 90 | if (networkResponse.notModified 91 | && request.hasHadResponseDelivered()) { 92 | request.finish("已经分发过本响应"); 93 | continue; 94 | } 95 | Response response = request 96 | .parseNetworkResponse(networkResponse); 97 | 98 | if (request.shouldCache() && response.cacheEntry != null) { 99 | mCache.put(request.getCacheKey(), response.cacheEntry); 100 | } 101 | 102 | request.markDelivered(); 103 | mDelivery.postResponse(request, response); 104 | } catch (KJHttpException volleyError) { 105 | parseAndDeliverNetworkError(request, volleyError); 106 | } catch (Exception e) { 107 | KJLoger.debug("Unhandled exception %s", e.getMessage()); 108 | mDelivery.postError(request, new KJHttpException(e)); 109 | } 110 | } 111 | } 112 | 113 | private void parseAndDeliverNetworkError(Request request, 114 | KJHttpException error) { 115 | error = request.parseNetworkError(error); 116 | mDelivery.postError(request, error); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/NetworkResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project, 张涛 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.util.Collections; 20 | import java.util.Map; 21 | 22 | /** 23 | * 从NetWork执行器返回的Http响应,包含了本次响应是成功还是失败,请求头,响应内容,HTTP状态码 24 | */ 25 | public class NetworkResponse { 26 | 27 | public NetworkResponse(int statusCode, byte[] data, 28 | Map headers, boolean notModified) { 29 | this.statusCode = statusCode; 30 | this.data = data; 31 | this.headers = headers; 32 | this.notModified = notModified; 33 | } 34 | 35 | public NetworkResponse(byte[] data) { 36 | this(KJHttpStatus.SC_OK, data, Collections. emptyMap(), 37 | false); 38 | } 39 | 40 | public NetworkResponse(byte[] data, Map headers) { 41 | this(KJHttpStatus.SC_OK, data, headers, false); 42 | } 43 | 44 | public final int statusCode; 45 | 46 | public final byte[] data; 47 | 48 | public final Map headers; 49 | 50 | public final boolean notModified; // 如果服务器返回304(Not Modified),则为true 51 | } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/OKHttpStack.java: -------------------------------------------------------------------------------- 1 | package org.kymjs.kjframe.http; 2 | 3 | import java.io.IOException; 4 | import java.net.HttpURLConnection; 5 | import java.net.URL; 6 | 7 | /** 8 | * 如果想要集成OKHttp,这里提供一个入口,集成的代码自己写,不会写到网上搜,一搜一大推 9 | * 然后找到HttpConfig中的httpStackFactory()方法,将new HttpConnectStack()替换成new OKHttpStack() 10 | * @author 我是无名氏 11 | * 12 | */ 13 | public class OKHttpStack extends HttpConnectStack { 14 | 15 | public OKHttpStack() { 16 | 17 | } 18 | 19 | @Override 20 | public HttpURLConnection openConnection(URL url, Request request) 21 | throws IOException { 22 | 23 | return super.openConnection(url, request); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/PoolingByteArrayOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project, 张涛 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.IOException; 21 | 22 | /** 23 | * 缓存的写入流 24 | */ 25 | public class PoolingByteArrayOutputStream extends ByteArrayOutputStream { 26 | /** 27 | * If the {@link #PoolingByteArrayOutputStream(ByteArrayPool)} constructor 28 | * is called, this is the default size to which the underlying byte array is 29 | * initialized. 30 | */ 31 | private static final int DEFAULT_SIZE = 256; 32 | 33 | private final ByteArrayPool mPool; 34 | 35 | /** 36 | * Constructs a new PoolingByteArrayOutputStream with a default size. If 37 | * more bytes are written to this instance, the underlying byte array will 38 | * expand. 39 | */ 40 | public PoolingByteArrayOutputStream(ByteArrayPool pool) { 41 | this(pool, DEFAULT_SIZE); 42 | } 43 | 44 | /** 45 | * Constructs a new {@code ByteArrayOutputStream} with a default size of 46 | * {@code size} bytes. If more than {@code size} bytes are written to this 47 | * instance, the underlying byte array will expand. 48 | * 49 | * @param size 50 | * initial size for the underlying byte array. The value will be 51 | * pinned to a default minimum size. 52 | */ 53 | public PoolingByteArrayOutputStream(ByteArrayPool pool, int size) { 54 | mPool = pool; 55 | buf = mPool.getBuf(Math.max(size, DEFAULT_SIZE)); 56 | } 57 | 58 | @Override 59 | public void close() throws IOException { 60 | mPool.returnBuf(buf); 61 | buf = null; 62 | super.close(); 63 | } 64 | 65 | @Override 66 | public void finalize() { 67 | mPool.returnBuf(buf); 68 | } 69 | 70 | /** 71 | * Ensures there is enough space in the buffer for the given number of 72 | * additional bytes. 73 | */ 74 | private void expand(int i) { 75 | /* Can the buffer handle @i more bytes, if not expand it */ 76 | if (count + i <= buf.length) { 77 | return; 78 | } 79 | byte[] newbuf = mPool.getBuf((count + i) * 2); 80 | System.arraycopy(buf, 0, newbuf, 0, count); 81 | mPool.returnBuf(buf); 82 | buf = newbuf; 83 | } 84 | 85 | @Override 86 | public synchronized void write(byte[] buffer, int offset, int len) { 87 | expand(len); 88 | super.write(buffer, offset, len); 89 | } 90 | 91 | @Override 92 | public synchronized void write(int oneByte) { 93 | expand(1); 94 | super.write(oneByte); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/http/Response.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project, 张涛 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.kymjs.kjframe.http; 18 | 19 | import java.util.Map; 20 | 21 | /** 22 | * Http响应封装类,包含了本次响应的全部信息 23 | */ 24 | public class Response { 25 | /** 26 | * Http响应的类型 27 | */ 28 | public final T result; 29 | 30 | /** 31 | * 本次响应的缓存对象,如果失败则为null 32 | */ 33 | public final Cache.Entry cacheEntry; 34 | 35 | public final KJHttpException error; 36 | 37 | public final Map headers; 38 | 39 | public boolean isSuccess() { 40 | return error == null; 41 | } 42 | 43 | private Response(T result, Map headers, 44 | Cache.Entry cacheEntry) { 45 | this.result = result; 46 | this.cacheEntry = cacheEntry; 47 | this.error = null; 48 | this.headers = headers; 49 | } 50 | 51 | private Response(KJHttpException error) { 52 | this.result = null; 53 | this.cacheEntry = null; 54 | this.headers = null; 55 | this.error = error; 56 | } 57 | 58 | /** 59 | * 返回一个成功的HttpRespond 60 | * 61 | * @param result 62 | * Http响应的类型 63 | * @param cacheEntry 64 | * 缓存对象 65 | */ 66 | public static Response success(T result, 67 | Map headers, Cache.Entry cacheEntry) { 68 | return new Response(result, headers, cacheEntry); 69 | } 70 | 71 | /** 72 | * 返回一个失败的HttpRespond 73 | * 74 | * @param error 75 | * 失败原因 76 | */ 77 | public static Response error(KJHttpException error) { 78 | return new Response(error); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/AnnotateUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | import android.app.Activity; 19 | import android.app.Fragment; 20 | import android.content.Context; 21 | import android.view.View; 22 | import android.view.View.OnClickListener; 23 | 24 | import java.lang.reflect.Field; 25 | 26 | /** 27 | * 注解工具类
28 | * 29 | * 创建时间 2014-6-5 30 | * 31 | * @author kymjs (https://github.com/kymjs) 32 | * @version 1.1 33 | */ 34 | public class AnnotateUtil { 35 | /** 36 | * @param currentClass 37 | * 当前类,一般为Activity或Fragment 38 | * @param sourceView 39 | * 待绑定控件的直接或间接父控件 40 | */ 41 | public static void initBindView(Object currentClass, View sourceView) { 42 | // 通过反射获取到全部属性,反射的字段可能是一个类(静态)字段或实例字段 43 | Field[] fields = currentClass.getClass().getDeclaredFields(); 44 | if (fields != null && fields.length > 0) { 45 | for (Field field : fields) { 46 | // 返回BindView类型的注解内容 47 | BindView bindView = field.getAnnotation(BindView.class); 48 | if (bindView != null) { 49 | int viewId = bindView.id(); 50 | boolean clickLis = bindView.click(); 51 | try { 52 | field.setAccessible(true); 53 | if (clickLis) { 54 | sourceView.findViewById(viewId).setOnClickListener( 55 | (OnClickListener) currentClass); 56 | } 57 | // 将currentClass的field赋值为sourceView.findViewById(viewId) 58 | field.set(currentClass, sourceView.findViewById(viewId)); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | 67 | /** 68 | * 必须在setContentView之后调用 69 | * 70 | * @param aty Activity对象 71 | */ 72 | public static void initBindView(Activity aty) { 73 | initBindView(aty, aty.getWindow().getDecorView()); 74 | } 75 | 76 | /** 77 | * 必须在setContentView之后调用 78 | * 79 | * @param view 80 | * 侵入式的view,例如使用inflater载入的view 81 | */ 82 | public static void initBindView(View view) { 83 | Context cxt = view.getContext(); 84 | if (cxt instanceof Activity) { 85 | initBindView((Activity) cxt); 86 | } else { 87 | throw new RuntimeException("view must into Activity"); 88 | } 89 | } 90 | 91 | /** 92 | * 必须在setContentView之后调用 93 | * 94 | * @param frag 要初始化的Fragment 95 | */ 96 | public static void initBindView(Fragment frag) { 97 | initBindView(frag, frag.getActivity().getWindow().getDecorView()); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/BindView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 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 | /** 24 | * 注解式绑定控件
25 | * 26 | * 创建时间 2014-7-11 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.0 30 | */ 31 | @Target(ElementType.FIELD) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | public @interface BindView { 34 | public int id(); 35 | 36 | public boolean click() default false; 37 | } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/FrameActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | import android.app.FragmentTransaction; 19 | import android.os.Bundle; 20 | import android.os.Handler; 21 | import android.view.View; 22 | import android.view.View.OnClickListener; 23 | import android.support.v4.app.FragmentActivity; 24 | 25 | /** 26 | * Activity's framework,the developer shouldn't extends it
27 | * 28 | * 创建时间 2014-3-1
29 | * 最后修改时间 2014-10-17
30 | * 31 | * @author kymjs (https://github.com/kymjs) 32 | * @version 1.8 33 | */ 34 | public abstract class FrameActivity extends FragmentActivity implements 35 | OnClickListener, I_BroadcastReg, I_KJActivity, I_SkipActivity { 36 | 37 | public static final int WHICH_MSG = 0X37210; 38 | 39 | protected KJFragment currentKJFragment; 40 | protected SupportFragment currentSupportFragment; 41 | 42 | /** 43 | * 一个私有回调类,线程中初始化数据完成后的回调 44 | */ 45 | private interface ThreadDataCallBack { 46 | void onSuccess(); 47 | } 48 | 49 | private static ThreadDataCallBack callback; 50 | 51 | // 当线程中初始化的数据初始化完成后,调用回调方法 52 | private static Handler threadHandle = new Handler() { 53 | @Override 54 | public void handleMessage(android.os.Message msg) { 55 | if (msg.what == WHICH_MSG) { 56 | callback.onSuccess(); 57 | } 58 | }; 59 | }; 60 | 61 | /** 62 | * 如果调用了initDataFromThread(),则当数据初始化完成后将回调该方法。 63 | */ 64 | protected void threadDataInited() {} 65 | 66 | /** 67 | * 在线程中初始化数据,注意不能在这里执行UI操作 68 | */ 69 | @Override 70 | public void initDataFromThread() { 71 | callback = new ThreadDataCallBack() { 72 | @Override 73 | public void onSuccess() { 74 | threadDataInited(); 75 | } 76 | }; 77 | } 78 | 79 | @Override 80 | public void initData() {} 81 | 82 | @Override 83 | public void initWidget() {} 84 | 85 | // 仅仅是为了代码整洁点 86 | private void initializer() { 87 | new Thread(new Runnable() { 88 | @Override 89 | public void run() { 90 | initDataFromThread(); 91 | threadHandle.sendEmptyMessage(WHICH_MSG); 92 | } 93 | }).start(); 94 | initData(); 95 | initWidget(); 96 | } 97 | 98 | /** listened widget's click method */ 99 | @Override 100 | public void widgetClick(View v) {} 101 | 102 | @Override 103 | public void onClick(View v) { 104 | widgetClick(v); 105 | } 106 | 107 | protected T bindView(int id) { 108 | return (T) findViewById(id); 109 | } 110 | 111 | protected T bindView(int id, boolean click) { 112 | T view = (T) findViewById(id); 113 | if (click) { 114 | view.setOnClickListener(this); 115 | } 116 | return view; 117 | } 118 | 119 | @Override 120 | public void registerBroadcast() {} 121 | 122 | @Override 123 | public void unRegisterBroadcast() {} 124 | 125 | @Override 126 | protected void onCreate(Bundle savedInstanceState) { 127 | super.onCreate(savedInstanceState); 128 | setRootView(); // 必须放在annotate之前调用 129 | AnnotateUtil.initBindView(this); 130 | initializer(); 131 | registerBroadcast(); 132 | } 133 | 134 | @Override 135 | protected void onDestroy() { 136 | unRegisterBroadcast(); 137 | super.onDestroy(); 138 | } 139 | 140 | /** 141 | * 用Fragment替换视图 142 | * 143 | * @param resView 144 | * 将要被替换掉的视图 145 | * @param targetFragment 146 | * 用来替换的Fragment 147 | */ 148 | public void changeFragment(int resView, KJFragment targetFragment) { 149 | if (targetFragment.equals(currentKJFragment)) { 150 | return; 151 | } 152 | FragmentTransaction transaction = getFragmentManager() 153 | .beginTransaction(); 154 | if (!targetFragment.isAdded()) { 155 | transaction.add(resView, targetFragment, targetFragment.getClass() 156 | .getName()); 157 | } 158 | if (targetFragment.isHidden()) { 159 | transaction.show(targetFragment); 160 | targetFragment.onChange(); 161 | } 162 | if (currentKJFragment != null && currentKJFragment.isVisible()) { 163 | transaction.hide(currentKJFragment); 164 | } 165 | currentKJFragment = targetFragment; 166 | transaction.commit(); 167 | } 168 | 169 | /** 170 | * 用Fragment替换视图 171 | * 172 | * @param resView 173 | * 将要被替换掉的视图 174 | * @param targetFragment 175 | * 用来替换的Fragment 176 | */ 177 | public void changeFragment(int resView, SupportFragment targetFragment) { 178 | if (targetFragment.equals(currentSupportFragment)) { 179 | return; 180 | } 181 | android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager() 182 | .beginTransaction(); 183 | if (!targetFragment.isAdded()) { 184 | transaction.add(resView, targetFragment, targetFragment.getClass() 185 | .getName()); 186 | } 187 | if (targetFragment.isHidden()) { 188 | transaction.show(targetFragment); 189 | targetFragment.onChange(); 190 | } 191 | if (currentSupportFragment != null 192 | && currentSupportFragment.isVisible()) { 193 | transaction.hide(currentSupportFragment); 194 | } 195 | currentSupportFragment = targetFragment; 196 | transaction.commit(); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/FrameFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | import android.app.Fragment; 19 | import android.os.Bundle; 20 | import android.os.Handler; 21 | import android.view.LayoutInflater; 22 | import android.view.View; 23 | import android.view.View.OnClickListener; 24 | import android.view.ViewGroup; 25 | 26 | /** 27 | * Fragment's framework,the developer shouldn't extends it
28 | * 29 | * 创建时间 2014-3-1
30 | * 最后修改时间 2014-5-30
31 | * 32 | * @author kymjs (https://github.com/kymjs) 33 | * @version 1.6 34 | */ 35 | public abstract class FrameFragment extends Fragment implements OnClickListener { 36 | 37 | public static final int WHICH_MSG = 0X37211; 38 | 39 | protected View fragmentRootView; 40 | 41 | /** 42 | * 一个私有回调类,线程中初始化数据完成后的回调 43 | */ 44 | private interface ThreadDataCallBack { 45 | void onSuccess(); 46 | } 47 | 48 | private static ThreadDataCallBack callback; 49 | 50 | // 当线程中初始化的数据初始化完成后,调用回调方法 51 | private static Handler threadHandle = new Handler() { 52 | @Override 53 | public void handleMessage(android.os.Message msg) { 54 | if (msg.what == WHICH_MSG) { 55 | callback.onSuccess(); 56 | } 57 | }; 58 | }; 59 | 60 | protected abstract View inflaterView(LayoutInflater inflater, 61 | ViewGroup container, Bundle bundle); 62 | 63 | /** 64 | * initialization widget, you should look like parentView.findviewbyid(id); 65 | * call method 66 | * 67 | * @param parentView 68 | */ 69 | protected void initWidget(View parentView) {} 70 | 71 | /** initialization data */ 72 | protected void initData() {} 73 | 74 | /** 75 | * 当通过changeFragment()显示时会被调用(类似于onResume) 76 | */ 77 | protected void onChange() {} 78 | 79 | /** 80 | * initialization data. And this method run in background thread, so you 81 | * shouldn't change ui
82 | * on initializated, will call threadDataInited(); 83 | */ 84 | protected void initDataFromThread() { 85 | callback = new ThreadDataCallBack() { 86 | @Override 87 | public void onSuccess() { 88 | threadDataInited(); 89 | } 90 | }; 91 | } 92 | 93 | /** 94 | * 如果调用了initDataFromThread(),则当数据初始化完成后将回调该方法。 95 | */ 96 | protected void threadDataInited() {} 97 | 98 | /** widget click method */ 99 | protected void widgetClick(View v) {} 100 | 101 | @Override 102 | public void onClick(View v) { 103 | widgetClick(v); 104 | } 105 | 106 | @Override 107 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 108 | Bundle savedInstanceState) { 109 | fragmentRootView = inflaterView(inflater, container, savedInstanceState); 110 | AnnotateUtil.initBindView(this, fragmentRootView); 111 | initData(); 112 | initWidget(fragmentRootView); 113 | new Thread(new Runnable() { 114 | @Override 115 | public void run() { 116 | initDataFromThread(); 117 | threadHandle.sendEmptyMessage(WHICH_MSG); 118 | } 119 | }).start(); 120 | return fragmentRootView; 121 | } 122 | 123 | protected T bindView(int id) { 124 | return (T) fragmentRootView.findViewById(id); 125 | } 126 | 127 | protected T bindView(int id, boolean click) { 128 | T view = (T) fragmentRootView.findViewById(id); 129 | if (click) { 130 | view.setOnClickListener(this); 131 | } 132 | return view; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/I_BroadcastReg.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | /** 19 | * 规范Activity中广播接受者注册的接口协议
20 | * 21 | * 创建时间 2014-7-11 22 | * 23 | * @author kymjs (https://github.com/kymjs) 24 | * @version 1.0 25 | */ 26 | public interface I_BroadcastReg { 27 | /** 28 | * 注册广播 29 | */ 30 | void registerBroadcast(); 31 | 32 | /** 33 | * 解除注册广播 34 | */ 35 | void unRegisterBroadcast(); 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/I_KJActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | import android.view.View; 19 | 20 | /** 21 | * KJFrameActivity接口协议,实现此接口可使用KJActivityManager堆栈
22 | * 23 | * 创建时间 2014-3-1
24 | * 最后修改时间 2014-5-30 25 | * 26 | * @author kymjs (https://github.com/kymjs) 27 | * @version 1.0 28 | */ 29 | public interface I_KJActivity { 30 | /** 设置root界面 */ 31 | void setRootView(); 32 | 33 | /** 初始化数据 */ 34 | void initData(); 35 | 36 | /** 在线程中初始化数据 */ 37 | void initDataFromThread(); 38 | 39 | /** 初始化控件 */ 40 | void initWidget(); 41 | 42 | /** 点击事件回调方法 */ 43 | void widgetClick(View v); 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/I_SkipActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | import android.os.Bundle; 21 | 22 | /** 23 | * 规范Activity跳转的接口协议 24 | * 25 | * @author kymjs (https://github.com/kymjs) 26 | */ 27 | public interface I_SkipActivity { 28 | /** 29 | * skip to @param(cls),and call @param(aty's) finish() method 30 | */ 31 | public void skipActivity(Activity aty, Class cls); 32 | 33 | /** 34 | * skip to @param(cls),and call @param(aty's) finish() method 35 | */ 36 | public void skipActivity(Activity aty, Intent it); 37 | 38 | /** 39 | * skip to @param(cls),and call @param(aty's) finish() method 40 | */ 41 | public void skipActivity(Activity aty, Class cls, Bundle extras); 42 | 43 | /** 44 | * show a @param(cls),but can't finish activity 45 | */ 46 | public void showActivity(Activity aty, Class cls); 47 | 48 | /** 49 | * show a @param(cls),but can't finish activity 50 | */ 51 | public void showActivity(Activity aty, Intent it); 52 | 53 | /** 54 | * show a @param(cls),but can't finish activity 55 | */ 56 | public void showActivity(Activity aty, Class cls, Bundle extras); 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/KJActivityStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | import java.util.Stack; 19 | 20 | import android.app.Activity; 21 | import android.content.Context; 22 | 23 | /** 24 | * 应用程序Activity管理类:用于Activity管理和应用程序退出
25 | * 26 | * 创建时间 2014-2-28 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.1 30 | */ 31 | final public class KJActivityStack { 32 | private static Stack activityStack; 33 | private static final KJActivityStack instance = new KJActivityStack(); 34 | 35 | private KJActivityStack() {} 36 | 37 | public static KJActivityStack create() { 38 | return instance; 39 | } 40 | 41 | /** 42 | * 获取当前Activity栈中元素个数 43 | */ 44 | public int getCount() { 45 | return activityStack.size(); 46 | } 47 | 48 | /** 49 | * 添加Activity到栈 50 | */ 51 | public void addActivity(I_KJActivity activity) { 52 | if (activityStack == null) { 53 | activityStack = new Stack(); 54 | } 55 | activityStack.add(activity); 56 | } 57 | 58 | /** 59 | * 获取当前Activity(栈顶Activity) 60 | */ 61 | public Activity topActivity() { 62 | if (activityStack == null) { 63 | throw new NullPointerException( 64 | "Activity stack is Null,your Activity must extend KJActivity"); 65 | } 66 | if (activityStack.isEmpty()) { 67 | return null; 68 | } 69 | I_KJActivity activity = activityStack.lastElement(); 70 | return (Activity) activity; 71 | } 72 | 73 | /** 74 | * 获取当前Activity(栈顶Activity) 没有找到则返回null 75 | */ 76 | public Activity findActivity(Class cls) { 77 | I_KJActivity activity = null; 78 | for (I_KJActivity aty : activityStack) { 79 | if (aty.getClass().equals(cls)) { 80 | activity = aty; 81 | break; 82 | } 83 | } 84 | return (Activity) activity; 85 | } 86 | 87 | /** 88 | * 结束当前Activity(栈顶Activity) 89 | */ 90 | public void finishActivity() { 91 | I_KJActivity activity = activityStack.lastElement(); 92 | finishActivity((Activity) activity); 93 | } 94 | 95 | /** 96 | * 结束指定的Activity(重载) 97 | */ 98 | public void finishActivity(Activity activity) { 99 | if (activity != null) { 100 | activityStack.remove(activity); 101 | // activity.finish();//此处不用finish 102 | activity = null; 103 | } 104 | } 105 | 106 | /** 107 | * 结束指定的Activity(重载) 108 | */ 109 | public void finishActivity(Class cls) { 110 | for (I_KJActivity activity : activityStack) { 111 | if (activity.getClass().equals(cls)) { 112 | finishActivity((Activity) activity); 113 | } 114 | } 115 | } 116 | 117 | /** 118 | * 关闭除了指定activity以外的全部activity 如果cls不存在于栈中,则栈全部清空 119 | * 120 | * @param cls 121 | */ 122 | public void finishOthersActivity(Class cls) { 123 | for (I_KJActivity activity : activityStack) { 124 | if (!(activity.getClass().equals(cls))) { 125 | finishActivity((Activity) activity); 126 | } 127 | } 128 | } 129 | 130 | /** 131 | * 结束所有Activity 132 | */ 133 | public void finishAllActivity() { 134 | for (int i = 0, size = activityStack.size(); i < size; i++) { 135 | if (null != activityStack.get(i)) { 136 | ((Activity) activityStack.get(i)).finish(); 137 | } 138 | } 139 | activityStack.clear(); 140 | } 141 | 142 | /** 143 | * 应用程序退出 144 | * 145 | */ 146 | public void AppExit(Context context) { 147 | try { 148 | finishAllActivity(); 149 | Runtime.getRuntime().exit(0); 150 | } catch (Exception e) { 151 | Runtime.getRuntime().exit(-1); 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/KJFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | import org.kymjs.kjframe.utils.KJLoger; 19 | 20 | import android.os.Bundle; 21 | 22 | /** 23 | * Application's base Fragment,you should inherit it for your Fragment
24 | * 25 | * 创建时间 2014-5-28 26 | * 27 | * @author kymjs (https://github.com/kymjs) 28 | * @version 1.0 29 | */ 30 | public abstract class KJFragment extends FrameFragment { 31 | 32 | /*************************************************************************** 33 | * 34 | * print Fragment callback methods 35 | * 36 | ***************************************************************************/ 37 | @Override 38 | public void onCreate(Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | KJLoger.state(this.getClass().getName(), "---------onCreateView "); 41 | } 42 | 43 | @Override 44 | public void onResume() { 45 | KJLoger.state(this.getClass().getName(), "---------onResume "); 46 | super.onResume(); 47 | } 48 | 49 | @Override 50 | public void onPause() { 51 | KJLoger.state(this.getClass().getName(), "---------onPause "); 52 | super.onPause(); 53 | } 54 | 55 | @Override 56 | public void onStop() { 57 | KJLoger.state(this.getClass().getName(), "---------onStop "); 58 | super.onStop(); 59 | } 60 | 61 | @Override 62 | public void onDestroyView() { 63 | KJLoger.state(this.getClass().getName(), "---------onDestroy "); 64 | super.onDestroyView(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/SupportFragment.java: -------------------------------------------------------------------------------- 1 | package org.kymjs.kjframe.ui; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import org.kymjs.kjframe.utils.KJLoger; public abstract class SupportFragment extends Fragment implements OnClickListener { public static final int WHICH_MSG = 0X37211; protected View fragmentRootView; /** * 一个私有回调类,线程中初始化数据完成后的回调 */ private interface ThreadDataCallBack { void onSuccess(); } private static ThreadDataCallBack callback; // 当线程中初始化的数据初始化完成后,调用回调方法 private static Handler threadHandle = new Handler() { @Override public void handleMessage(android.os.Message msg) { if (msg.what == WHICH_MSG) { callback.onSuccess(); } }; }; protected abstract View inflaterView(LayoutInflater inflater, ViewGroup container, Bundle bundle); /** * initialization widget, you should look like parentView.findviewbyid(id); * call method * * @param parentView */ protected void initWidget(View parentView) {} /** initialization data */ protected void initData() {} /** * initialization data. And this method run in background thread, so you * shouldn't change ui
* on initializated, will call threadDataInited(); */ protected void initDataFromThread() { callback = new ThreadDataCallBack() { @Override public void onSuccess() { threadDataInited(); } }; } /** * 如果调用了initDataFromThread(),则当数据初始化完成后将回调该方法。 */ protected void threadDataInited() {} /** * 当通过changeFragment()显示时会被调用(类似于onResume) */ protected void onChange() {} /** widget click method */ protected void widgetClick(View v) {} @Override public void onClick(View v) { widgetClick(v); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { fragmentRootView = inflaterView(inflater, container, savedInstanceState); AnnotateUtil.initBindView(this, fragmentRootView); initData(); initWidget(fragmentRootView); new Thread(new Runnable() { @Override public void run() { initDataFromThread(); threadHandle.sendEmptyMessage(WHICH_MSG); } }).start(); return fragmentRootView; } protected T bindView(int id) { return (T) fragmentRootView.findViewById(id); } protected T bindView(int id, boolean click) { T view = (T) fragmentRootView.findViewById(id); if (click) { view.setOnClickListener(this); } return view; } /*************************************************************************** * * print Fragment callback methods * ***************************************************************************/ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); KJLoger.state(this.getClass().getName(), "---------onCreateView "); } @Override public void onResume() { KJLoger.state(this.getClass().getName(), "---------onResume "); super.onResume(); } @Override public void onPause() { KJLoger.state(this.getClass().getName(), "---------onPause "); super.onPause(); } @Override public void onStop() { KJLoger.state(this.getClass().getName(), "---------onStop "); super.onStop(); } @Override public void onDestroyView() { KJLoger.state(this.getClass().getName(), "---------onDestroy "); super.onDestroyView(); } } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/ui/ViewInject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.ui; 17 | 18 | import org.kymjs.kjframe.utils.DensityUtils; 19 | import org.kymjs.kjframe.utils.StringUtils; 20 | import org.kymjs.kjframe.utils.SystemTool; 21 | 22 | import android.app.Activity; 23 | import android.app.AlertDialog; 24 | import android.app.DatePickerDialog; 25 | import android.app.DatePickerDialog.OnDateSetListener; 26 | import android.app.ProgressDialog; 27 | import android.content.Context; 28 | import android.content.DialogInterface; 29 | import android.content.DialogInterface.OnClickListener; 30 | import android.view.View; 31 | import android.widget.DatePicker; 32 | import android.widget.TextView; 33 | import android.widget.Toast; 34 | 35 | /** 36 | * 侵入式View的调用工具类 37 | * 38 | * @author kymjs (https://github.com/kymjs) 39 | */ 40 | public class ViewInject { 41 | 42 | private ViewInject() {} 43 | 44 | private static class ClassHolder { 45 | private static final ViewInject instance = new ViewInject(); 46 | } 47 | 48 | /** 49 | * 类对象创建方法 50 | * 51 | * @return 本类的对象 52 | */ 53 | public static ViewInject create() { 54 | return ClassHolder.instance; 55 | } 56 | 57 | /** 58 | * 显示一个toast 59 | * 60 | * @param msg 61 | */ 62 | public static void toast(String msg) { 63 | try { 64 | toast(KJActivityStack.create().topActivity(), msg); 65 | } catch (Exception e) { 66 | } 67 | } 68 | 69 | /** 70 | * 长时间显示一个toast 71 | * 72 | * @param msg 73 | */ 74 | public static void longToast(String msg) { 75 | try { 76 | longToast(KJActivityStack.create().topActivity(), msg); 77 | } catch (Exception e) { 78 | } 79 | } 80 | 81 | /** 82 | * 长时间显示一个toast 83 | * 84 | * @param msg 85 | */ 86 | public static void longToast(Context context, String msg) { 87 | Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); 88 | } 89 | 90 | /** 91 | * 显示一个toast 92 | * 93 | * @param msg 94 | */ 95 | public static void toast(Context context, String msg) { 96 | Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); 97 | } 98 | 99 | /** 100 | * 返回一个退出确认对话框 101 | */ 102 | public void getExitDialog(final Context context, String title, 103 | OnClickListener l) { 104 | AlertDialog.Builder builder = new AlertDialog.Builder(context); 105 | builder.setMessage(title); 106 | builder.setCancelable(false); 107 | builder.setNegativeButton("取消", new OnClickListener() { 108 | @Override 109 | public void onClick(DialogInterface dialog, int which) { 110 | dialog.dismiss(); 111 | } 112 | }); 113 | builder.setPositiveButton("确定", l); 114 | builder.create(); 115 | builder.show(); 116 | builder = null; 117 | } 118 | 119 | /** 120 | * 返回一个自定义View对话框 121 | */ 122 | public AlertDialog getDialogView(Context cxt, String title, View view) { 123 | AlertDialog dialog = new AlertDialog.Builder(cxt).create(); 124 | dialog.setMessage(title); 125 | dialog.setView(view); 126 | dialog.show(); 127 | return dialog; 128 | } 129 | 130 | /** 131 | * 用于创建PopupWindow封装一些公用属性 132 | */ 133 | // private PopupWindow createWindow(View view, int w, int h, int argb) { 134 | // PopupWindow popupView = new PopupWindow(view, w, h); 135 | // popupView.setFocusable(true); 136 | // popupView.setBackgroundDrawable(new ColorDrawable(argb)); 137 | // popupView.setOutsideTouchable(true); 138 | // return popupView; 139 | // } 140 | 141 | /** 142 | * 返回一个日期对话框 143 | */ 144 | public void getDateDialog(String title, final TextView textView) { 145 | final String[] time = SystemTool.getDataTime("yyyy-MM-dd").split("-"); 146 | final int year = StringUtils.toInt(time[0], 0); 147 | final int month = StringUtils.toInt(time[1], 1); 148 | final int day = StringUtils.toInt(time[2], 0); 149 | DatePickerDialog dialog = new DatePickerDialog(textView.getContext(), 150 | new OnDateSetListener() { 151 | @Override 152 | public void onDateSet(DatePicker view, int year, 153 | int monthOfYear, int dayOfMonth) { 154 | textView.setText(year + "-" + (monthOfYear + 1) + "-" 155 | + dayOfMonth); 156 | } 157 | }, year, month - 1, day); 158 | dialog.setTitle(title); 159 | dialog.show(); 160 | } 161 | 162 | /** 163 | * 返回一个等待信息弹窗 164 | * 165 | * @param aty 166 | * 要显示弹出窗的Activity 167 | * @param msg 168 | * 弹出窗上要显示的文字 169 | * @param cancel 170 | * dialog是否可以被取消 171 | */ 172 | public static ProgressDialog getprogress(Activity aty, String msg, 173 | boolean cancel) { 174 | // 实例化一个ProgressBarDialog 175 | ProgressDialog progressDialog = new ProgressDialog(aty); 176 | progressDialog.setMessage(msg); 177 | progressDialog.getWindow().setLayout(DensityUtils.getScreenW(aty), 178 | DensityUtils.getScreenH(aty)); 179 | progressDialog.setCancelable(cancel); 180 | // 设置ProgressBarDialog的显示样式 181 | progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 182 | progressDialog.show(); 183 | return progressDialog; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/utils/CipherUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.utils; 17 | 18 | import java.io.UnsupportedEncodingException; 19 | import java.security.Key; 20 | import java.security.MessageDigest; 21 | import java.security.NoSuchAlgorithmException; 22 | 23 | import javax.crypto.Cipher; 24 | import javax.crypto.SecretKeyFactory; 25 | import javax.crypto.spec.DESKeySpec; 26 | 27 | /** 28 | * 加密与解密的工具类
29 | * 30 | * 创建时间 2014-8-14 31 | * 32 | * @author kymjs (https://github.com/kymjs) 33 | * @version 1.1 34 | */ 35 | public final class CipherUtils { 36 | /** 37 | * MD5加密 38 | */ 39 | public static String md5(String string) { 40 | byte[] hash; 41 | try { 42 | hash = MessageDigest.getInstance("MD5").digest( 43 | string.getBytes("UTF-8")); 44 | } catch (NoSuchAlgorithmException e) { 45 | throw new RuntimeException("Huh, MD5 should be supported?", e); 46 | } catch (UnsupportedEncodingException e) { 47 | throw new RuntimeException("Huh, UTF-8 should be supported?", e); 48 | } 49 | 50 | StringBuilder hex = new StringBuilder(hash.length * 2); 51 | for (byte b : hash) { 52 | if ((b & 0xFF) < 0x10) 53 | hex.append("0"); 54 | hex.append(Integer.toHexString(b & 0xFF)); 55 | } 56 | return hex.toString(); 57 | } 58 | 59 | /** 60 | * 返回可逆算法DES的密钥 61 | * 62 | * @param key 63 | * 前8字节将被用来生成密钥。 64 | * @return 生成的密钥 65 | * @throws Exception 66 | */ 67 | public static Key getDESKey(byte[] key) throws Exception { 68 | DESKeySpec des = new DESKeySpec(key); 69 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 70 | return keyFactory.generateSecret(des); 71 | } 72 | 73 | /** 74 | * 根据指定的密钥及算法,将字符串进行解密。 75 | * 76 | * @param data 77 | * 要进行解密的数据,它是由原来的byte[]数组转化为字符串的结果。 78 | * @param key 79 | * 密钥。 80 | * @param algorithm 81 | * 算法。 82 | * @return 解密后的结果。它由解密后的byte[]重新创建为String对象。如果解密失败,将返回null。 83 | * @throws Exception 84 | */ 85 | public static String decrypt(String data, Key key, String algorithm) 86 | throws Exception { 87 | Cipher cipher = Cipher.getInstance(algorithm); 88 | cipher.init(Cipher.DECRYPT_MODE, key); 89 | String result = new String(cipher.doFinal(StringUtils 90 | .hexStringToByteArray(data)), "utf8"); 91 | return result; 92 | } 93 | 94 | /** 95 | * 根据指定的密钥及算法对指定字符串进行可逆加密。 96 | * 97 | * @param data 98 | * 要进行加密的字符串。 99 | * @param key 100 | * 密钥。 101 | * @param algorithm 102 | * 算法。 103 | * @return 加密后的结果将由byte[]数组转换为16进制表示的数组。如果加密过程失败,将返回null。 104 | */ 105 | public static String encrypt(String data, Key key, String algorithm) 106 | throws Exception { 107 | Cipher cipher = Cipher.getInstance(algorithm); 108 | cipher.init(Cipher.ENCRYPT_MODE, key); 109 | return StringUtils.byteArrayToHexString(cipher.doFinal(data 110 | .getBytes("utf8"))); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/utils/DensityUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.utils; 17 | 18 | import android.content.Context; 19 | import android.content.res.Resources; 20 | import android.util.DisplayMetrics; 21 | import android.util.TypedValue; 22 | 23 | /** 24 | * 系统屏幕的一些操作
25 | * 26 | * 创建时间 2014-8-14 27 | * 28 | * @author kymjs (https://github.com/kymjs) 29 | * @version 1.1 30 | */ 31 | public final class DensityUtils { 32 | 33 | /** 34 | * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 35 | */ 36 | public static int dip2px(Context context, float dpValue) { 37 | Resources r = context.getResources(); 38 | float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 39 | dpValue, r.getDisplayMetrics()); 40 | return (int) px; 41 | } 42 | 43 | /** 44 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 45 | */ 46 | public static int px2dip(Context context, float pxValue) { 47 | final float scale = context.getResources().getDisplayMetrics().density; 48 | return (int) (pxValue / scale + 0.5f); 49 | } 50 | 51 | /** 52 | * 根据手机的分辨率从 px(像素) 的单位 转成为 sp 53 | */ 54 | public static int px2sp(Context context, float pxValue) { 55 | float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 56 | return (int) (pxValue / fontScale + 0.5f); 57 | } 58 | 59 | /** 60 | * 根据手机的分辨率从 sp 的单位 转成为 px 61 | */ 62 | public static int sp2px(Context context, float spValue) { 63 | float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 64 | return (int) (spValue * fontScale + 0.5f); 65 | } 66 | 67 | /** 68 | * 获取dialog宽度 69 | */ 70 | public static int getDialogW(Context aty) { 71 | DisplayMetrics dm = new DisplayMetrics(); 72 | dm = aty.getResources().getDisplayMetrics(); 73 | int w = dm.widthPixels - 100; 74 | // int w = aty.getWindowManager().getDefaultDisplay().getWidth() - 100; 75 | return w; 76 | } 77 | 78 | /** 79 | * 获取屏幕宽度 80 | */ 81 | public static int getScreenW(Context aty) { 82 | DisplayMetrics dm = new DisplayMetrics(); 83 | dm = aty.getResources().getDisplayMetrics(); 84 | int w = dm.widthPixels; 85 | // int w = aty.getWindowManager().getDefaultDisplay().getWidth(); 86 | return w; 87 | } 88 | 89 | /** 90 | * 获取屏幕高度 91 | */ 92 | public static int getScreenH(Context aty) { 93 | DisplayMetrics dm = new DisplayMetrics(); 94 | dm = aty.getResources().getDisplayMetrics(); 95 | int h = dm.heightPixels; 96 | // int h = aty.getWindowManager().getDefaultDisplay().getHeight(); 97 | return h; 98 | } 99 | } -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/utils/ImageUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.utils; 17 | 18 | import android.content.Context; 19 | import android.graphics.Bitmap; 20 | import android.graphics.BitmapFactory; 21 | import android.graphics.Matrix; 22 | 23 | import java.io.BufferedOutputStream; 24 | import java.io.File; 25 | import java.io.FileOutputStream; 26 | import java.io.IOException; 27 | import java.math.BigDecimal; 28 | import java.text.SimpleDateFormat; 29 | import java.util.Date; 30 | import java.util.Locale; 31 | import java.util.Random; 32 | 33 | /** 34 | * 图片工具类 35 | * Created by kymjs on 15/9/8. 36 | */ 37 | public class ImageUtils { 38 | 39 | /** 40 | * 压缩图片 41 | * 42 | * @param filePath 源图片地址 43 | * @param width 想要的宽度 44 | * @param height 想要的高度 45 | * @param isAdjust 是否自动调整尺寸, true图片就不会拉伸,false严格按照你的尺寸压缩 46 | * @return Bitmap 47 | */ 48 | public static File getSmallImageFile(Context cxt, String filePath, int width, int height, 49 | boolean isAdjust) { 50 | 51 | Bitmap bitmap = reduce(BitmapFactory.decodeFile(filePath), width, height, isAdjust); 52 | 53 | File file = new File(getRandomFileName(cxt.getCacheDir().getPath())); 54 | 55 | BufferedOutputStream outputStream = null; 56 | try { 57 | outputStream = new BufferedOutputStream(new FileOutputStream(file)); 58 | bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outputStream); 59 | outputStream.flush(); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } finally { 63 | try { 64 | if (outputStream != null) { 65 | outputStream.close(); 66 | } 67 | } catch (IOException e) { 68 | e.printStackTrace(); 69 | } 70 | } 71 | return file; 72 | } 73 | 74 | /*** 75 | * 获取一个随机图片文件名,含路径 76 | * 77 | * @param filePath 78 | * @return 79 | */ 80 | public static String getRandomFileName(String filePath) { 81 | SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", 82 | Locale.getDefault()); 83 | Date date = new Date(); 84 | String key = format.format(date); 85 | 86 | Random r = new Random(); 87 | key = key + r.nextInt(); 88 | key = key.substring(0, 15); 89 | return filePath + "/" + key + ".jpeg"; 90 | } 91 | 92 | /** 93 | * 压缩图片 94 | * 95 | * @param bitmap 源图片 96 | * @param width 想要的宽度 97 | * @param height 想要的高度 98 | * @param isAdjust 是否自动调整尺寸, true图片就不会拉伸,false严格按照你的尺寸压缩 99 | * @return Bitmap 100 | */ 101 | public static Bitmap reduce(Bitmap bitmap, int width, int height, boolean isAdjust) { 102 | // 如果想要的宽度和高度都比源图片小,就不压缩了,直接返回原图 103 | if (bitmap.getWidth() < width && bitmap.getHeight() < height) { 104 | return bitmap; 105 | } 106 | if (width == 0 && height == 0) { 107 | width = bitmap.getWidth(); 108 | height = bitmap.getHeight(); 109 | } 110 | 111 | // 根据想要的尺寸精确计算压缩比例, 方法详解:public BigDecimal divide(BigDecimal divisor, int scale, int 112 | // roundingMode); 113 | // scale表示要保留的小数位, roundingMode表示如何处理多余的小数位,BigDecimal.ROUND_DOWN表示自动舍弃 114 | float sx = new BigDecimal(width).divide(new BigDecimal(bitmap.getWidth()), 4, BigDecimal 115 | .ROUND_DOWN).floatValue(); 116 | float sy = new BigDecimal(height).divide(new BigDecimal(bitmap.getHeight()), 4, 117 | BigDecimal.ROUND_DOWN).floatValue(); 118 | if (isAdjust) {// 如果想自动调整比例,不至于图片会拉伸 119 | sx = (sx < sy ? sx : sy); 120 | sy = sx;// 哪个比例小一点,就用哪个比例 121 | } 122 | Matrix matrix = new Matrix(); 123 | matrix.postScale(sx, sy);// 调用api中的方法进行压缩,就大功告成了 124 | return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, 125 | true); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/utils/KJConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.utils; 17 | 18 | /** 19 | * 20 | * @author kymjs (https://github.com/kymjs) 21 | */ 22 | public final class KJConfig { 23 | 24 | public static final double VERSION = 2.2491; 25 | 26 | /** 错误处理广播 */ 27 | public static final String RECEIVER_ERROR = KJConfig.class.getName() 28 | + "org.kymjs.android.frame.error"; 29 | /** 无网络警告广播 */ 30 | public static final String RECEIVER_NOT_NET_WARN = KJConfig.class.getName() 31 | + "org.kymjs.android.frame.notnet"; 32 | /** preference键值对 */ 33 | public static final String SETTING_FILE = "kjframe_preference"; 34 | public static final String ONLY_WIFI = "only_wifi"; 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/utils/KJLoger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.utils; 17 | 18 | import android.util.Log; 19 | 20 | /** 21 | * 应用程序的Log管理
22 | * 创建时间 2014-2-28 23 | * 24 | * @author kymjs (https://github.com/kymjs) 25 | * @version 1.1 26 | */ 27 | public final class KJLoger { 28 | public static boolean IS_DEBUG = true; 29 | public static boolean DEBUG_LOG = true; 30 | public static boolean SHOW_ACTIVITY_STATE = true; 31 | 32 | public static final void openDebutLog(boolean enable) { 33 | IS_DEBUG = enable; 34 | DEBUG_LOG = enable; 35 | } 36 | 37 | public static final void openActivityState(boolean enable) { 38 | SHOW_ACTIVITY_STATE = enable; 39 | } 40 | 41 | public static final void debug(String msg) { 42 | if (IS_DEBUG) { 43 | Log.i("debug", msg); 44 | } 45 | } 46 | 47 | public static final void log(String packName, String state) { 48 | debugLog(packName, state); 49 | } 50 | 51 | public static final void debug(String msg, Throwable tr) { 52 | if (IS_DEBUG) { 53 | Log.i("debug", msg, tr); 54 | } 55 | } 56 | 57 | public static final void state(String packName, String state) { 58 | if (SHOW_ACTIVITY_STATE) { 59 | Log.d("activity_state", packName + state); 60 | } 61 | } 62 | 63 | public static final void debugLog(String packName, String state) { 64 | if (DEBUG_LOG) { 65 | Log.d("debug", packName + state); 66 | } 67 | } 68 | 69 | public static final void exception(Exception e) { 70 | if (DEBUG_LOG) { 71 | e.printStackTrace(); 72 | } 73 | } 74 | 75 | public static final void debug(String msg, Object... format) { 76 | debug(String.format(msg, format)); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/utils/PreferenceHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.utils; 17 | 18 | import android.content.Context; 19 | import android.content.SharedPreferences; 20 | import android.content.SharedPreferences.Editor; 21 | 22 | /** 23 | * SharedPreferences操作工具包
24 | * 25 | * 说明 本工具包只能在单进程项目下使用,多进程共享请使用如下demo的两行代码重写:
26 | * Context otherContext = c.createPackageContext( "com.android.contacts", 27 | * Context.CONTEXT_IGNORE_SECURITY);
28 | * SharedPreferences sp = otherContext.getSharedPreferences( "my_file", 29 | * Context.MODE_MULTI_PROCESS);
30 | * 31 | * 创建时间 2014-7-27 32 | * 33 | * @author kymjs (https://github.com/kymjs) 34 | */ 35 | public class PreferenceHelper { 36 | public static void write(Context context, String fileName, String k, int v) { 37 | SharedPreferences preference = context.getSharedPreferences(fileName, 38 | Context.MODE_PRIVATE); 39 | Editor editor = preference.edit(); 40 | editor.putInt(k, v); 41 | editor.commit(); 42 | } 43 | 44 | public static void write(Context context, String fileName, String k, 45 | boolean v) { 46 | SharedPreferences preference = context.getSharedPreferences(fileName, 47 | Context.MODE_PRIVATE); 48 | Editor editor = preference.edit(); 49 | editor.putBoolean(k, v); 50 | editor.commit(); 51 | } 52 | 53 | public static void write(Context context, String fileName, String k, 54 | String v) { 55 | SharedPreferences preference = context.getSharedPreferences(fileName, 56 | Context.MODE_PRIVATE); 57 | Editor editor = preference.edit(); 58 | editor.putString(k, v); 59 | editor.commit(); 60 | } 61 | 62 | public static int readInt(Context context, String fileName, String k) { 63 | SharedPreferences preference = context.getSharedPreferences(fileName, 64 | Context.MODE_PRIVATE); 65 | return preference.getInt(k, 0); 66 | } 67 | 68 | public static int readInt(Context context, String fileName, String k, 69 | int defv) { 70 | SharedPreferences preference = context.getSharedPreferences(fileName, 71 | Context.MODE_PRIVATE); 72 | return preference.getInt(k, defv); 73 | } 74 | 75 | public static boolean readBoolean(Context context, String fileName, String k) { 76 | SharedPreferences preference = context.getSharedPreferences(fileName, 77 | Context.MODE_PRIVATE); 78 | return preference.getBoolean(k, false); 79 | } 80 | 81 | public static boolean readBoolean(Context context, String fileName, 82 | String k, boolean defBool) { 83 | SharedPreferences preference = context.getSharedPreferences(fileName, 84 | Context.MODE_PRIVATE); 85 | return preference.getBoolean(k, defBool); 86 | } 87 | 88 | public static String readString(Context context, String fileName, String k) { 89 | SharedPreferences preference = context.getSharedPreferences(fileName, 90 | Context.MODE_PRIVATE); 91 | return preference.getString(k, null); 92 | } 93 | 94 | public static String readString(Context context, String fileName, String k, 95 | String defV) { 96 | SharedPreferences preference = context.getSharedPreferences(fileName, 97 | Context.MODE_PRIVATE); 98 | return preference.getString(k, defV); 99 | } 100 | 101 | public static void remove(Context context, String fileName, String k) { 102 | SharedPreferences preference = context.getSharedPreferences(fileName, 103 | Context.MODE_PRIVATE); 104 | Editor editor = preference.edit(); 105 | editor.remove(k); 106 | editor.commit(); 107 | } 108 | 109 | public static void clean(Context cxt, String fileName) { 110 | SharedPreferences preference = cxt.getSharedPreferences(fileName, 111 | Context.MODE_PRIVATE); 112 | SharedPreferences.Editor editor = preference.edit(); 113 | editor.clear(); 114 | editor.commit(); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/utils/ViewUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014,KJFrameForAndroid Open Source Project,张涛. 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 org.kymjs.kjframe.utils; 17 | 18 | import android.content.Context; 19 | import android.content.Intent; 20 | import android.graphics.Bitmap; 21 | import android.os.Parcelable; 22 | import android.view.View; 23 | 24 | /** 25 | * 系统界面工具类
26 | * 27 | * 创建时间 2014-8-14 28 | * 29 | * @author kymjs (https://github.com/kymjs) 30 | * @version 1.1 31 | */ 32 | public class ViewUtils { 33 | /** 34 | * 截图 35 | * 36 | * @param v 37 | * 需要进行截图的控件 38 | * @return 该控件截图的Bitmap对象。 39 | */ 40 | public static Bitmap captureView(View v) { 41 | v.setDrawingCacheEnabled(true); 42 | v.buildDrawingCache(); 43 | return v.getDrawingCache(); 44 | } 45 | 46 | /** 47 | * 创建快捷方式 48 | * 49 | * @param cxt 50 | * Context 51 | * @param icon 52 | * 快捷方式图标 53 | * @param title 54 | * 快捷方式标题 55 | * @param cls 56 | * 要启动的类 57 | */ 58 | public void createDeskShortCut(Context cxt, int icon, String title, 59 | Class cls) { 60 | // 创建快捷方式的Intent 61 | Intent shortcutIntent = new Intent( 62 | "com.android.launcher.action.INSTALL_SHORTCUT"); 63 | // 不允许重复创建 64 | shortcutIntent.putExtra("duplicate", false); 65 | // 需要现实的名称 66 | shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, title); 67 | // 快捷图片 68 | Parcelable ico = Intent.ShortcutIconResource.fromContext( 69 | cxt.getApplicationContext(), icon); 70 | shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, ico); 71 | Intent intent = new Intent(cxt, cls); 72 | // 下面两个属性是为了当应用程序卸载时桌面上的快捷方式会删除 73 | intent.setAction("android.intent.action.MAIN"); 74 | intent.addCategory("android.intent.category.LAUNCHER"); 75 | // 点击快捷图片,运行的程序主入口 76 | shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent); 77 | // 发送广播。OK 78 | cxt.sendBroadcast(shortcutIntent); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/widget/AdapterHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 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 org.kymjs.kjframe.widget; 17 | 18 | /** 19 | * 万能Adapter,查看KJAdapter 20 | * 21 | * @author kymjs(http://www.kymjs.com/) 22 | */ 23 | import android.graphics.Bitmap; 24 | import android.util.SparseArray; 25 | import android.view.LayoutInflater; 26 | import android.view.View; 27 | import android.view.ViewGroup; 28 | import android.widget.ImageView; 29 | import android.widget.TextView; 30 | 31 | import org.kymjs.kjframe.KJBitmap; 32 | 33 | public class AdapterHolder { 34 | private final SparseArray mViews; 35 | private final int mPosition; 36 | private final View mConvertView; 37 | 38 | private AdapterHolder(ViewGroup parent, int layoutId, int position) { 39 | this.mPosition = position; 40 | this.mViews = new SparseArray(); 41 | mConvertView = LayoutInflater.from(parent.getContext()).inflate( 42 | layoutId, parent, false); 43 | // setTag 44 | mConvertView.setTag(this); 45 | } 46 | 47 | /** 48 | * 拿到全部View 49 | * 50 | * @return 51 | */ 52 | public SparseArray getAllView() { 53 | return mViews; 54 | } 55 | 56 | /** 57 | * 拿到一个ViewHolder对象 58 | * 59 | * @param convertView 60 | * @param parent 61 | * @param layoutId 62 | * @param position 63 | * @return 64 | */ 65 | public static AdapterHolder get(View convertView, ViewGroup parent, 66 | int layoutId, int position) { 67 | if (convertView == null) { 68 | return new AdapterHolder(parent, layoutId, position); 69 | } else { 70 | return (AdapterHolder) convertView.getTag(); 71 | } 72 | } 73 | 74 | public View getConvertView() { 75 | return mConvertView; 76 | } 77 | 78 | /** 79 | * 通过控件的Id获取对于的控件,如果没有则加入views 80 | * 81 | * @param viewId 82 | * @return 83 | */ 84 | @SuppressWarnings("unchecked") 85 | public T getView(int viewId) { 86 | View view = mViews.get(viewId); 87 | if (view == null) { 88 | view = mConvertView.findViewById(viewId); 89 | mViews.put(viewId, view); 90 | } 91 | return (T) view; 92 | } 93 | 94 | /** 95 | * 为TextView设置字符串 96 | * 97 | * @param viewId 98 | * @param text 99 | * @return 100 | */ 101 | public AdapterHolder setText(int viewId, CharSequence text) { 102 | TextView view = getView(viewId); 103 | view.setText(text); 104 | return this; 105 | } 106 | 107 | /** 108 | * 为ImageView设置图片 109 | * 110 | * @param viewId 111 | * @param drawableId 112 | * @return 113 | */ 114 | public AdapterHolder setImageResource(int viewId, int drawableId) { 115 | ImageView view = getView(viewId); 116 | view.setImageResource(drawableId); 117 | 118 | return this; 119 | } 120 | 121 | /** 122 | * 为ImageView设置图片 123 | * 124 | * @param viewId 125 | * @param bm 126 | * @return 127 | */ 128 | public AdapterHolder setImageBitmap(int viewId, Bitmap bm) { 129 | ImageView view = getView(viewId); 130 | view.setImageBitmap(bm); 131 | return this; 132 | } 133 | 134 | /** 135 | * 为ImageView设置图片 136 | * 137 | * @param viewId 138 | * @param url 139 | * @return 140 | */ 141 | public AdapterHolder setImageByUrl(KJBitmap bitmap, int viewId, String url) { 142 | bitmap.display(getView(viewId), url); 143 | return this; 144 | } 145 | 146 | public int getPosition() { 147 | return mPosition; 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /app/src/main/java/org/kymjs/kjframe/widget/KJAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, 张涛. 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 org.kymjs.kjframe.widget; 17 | 18 | import android.content.Context; 19 | import android.view.LayoutInflater; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | import android.widget.AbsListView; 23 | import android.widget.BaseAdapter; 24 | 25 | import java.util.ArrayList; 26 | import java.util.Collection; 27 | import java.util.List; 28 | import java.util.Set; 29 | 30 | /** 31 | * 对ViewHolder的封装,以及更方便的控制ListView滑动过程中不加载图片 32 | * 33 | * @param 34 | * @author kymjs (https://www.kymjs.com/) 35 | */ 36 | public abstract class KJAdapter extends BaseAdapter implements 37 | AbsListView.OnScrollListener { 38 | 39 | protected Collection mDatas; 40 | protected final int mItemLayoutId; 41 | protected AbsListView mList; 42 | protected boolean isScrolling; 43 | protected Context mCxt; 44 | protected LayoutInflater mInflater; 45 | 46 | private AbsListView.OnScrollListener listener; 47 | 48 | public KJAdapter(AbsListView view, Collection mDatas, int itemLayoutId) { 49 | if (mDatas == null) { 50 | mDatas = new ArrayList(0); 51 | } 52 | this.mDatas = mDatas; 53 | this.mItemLayoutId = itemLayoutId; 54 | this.mList = view; 55 | mCxt = view.getContext(); 56 | mInflater = LayoutInflater.from(mCxt); 57 | mList.setOnScrollListener(this); 58 | } 59 | 60 | public void refresh(Collection datas) { 61 | if (datas == null) { 62 | datas = new ArrayList(0); 63 | } 64 | this.mDatas = datas; 65 | notifyDataSetChanged(); 66 | } 67 | 68 | public void addOnScrollListener(AbsListView.OnScrollListener l) { 69 | this.listener = l; 70 | } 71 | 72 | @Override 73 | public int getCount() { 74 | return mDatas.size(); 75 | } 76 | 77 | @Override 78 | public T getItem(int position) { 79 | if (mDatas instanceof List) { 80 | return ((List) mDatas).get(position); 81 | } else if (mDatas instanceof Set) { 82 | return new ArrayList(mDatas).get(position); 83 | } else { 84 | return null; 85 | } 86 | } 87 | 88 | @Override 89 | public long getItemId(int position) { 90 | return position; 91 | } 92 | 93 | @Override 94 | public View getView(int position, View convertView, ViewGroup parent) { 95 | final AdapterHolder viewHolder = getViewHolder(position, convertView, 96 | parent); 97 | convert(viewHolder, getItem(position), isScrolling, position); 98 | return viewHolder.getConvertView(); 99 | 100 | } 101 | 102 | private AdapterHolder getViewHolder(int position, View convertView, 103 | ViewGroup parent) { 104 | return AdapterHolder.get(convertView, parent, mItemLayoutId, position); 105 | } 106 | 107 | public void convert(AdapterHolder helper, T item, 108 | boolean isScrolling) { 109 | } 110 | 111 | public void convert(AdapterHolder helper, T item, boolean isScrolling, 112 | int position) { 113 | convert(helper, getItem(position), isScrolling); 114 | } 115 | 116 | @Override 117 | public void onScrollStateChanged(AbsListView view, int scrollState) { 118 | // 设置是否滚动的状态 119 | if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { 120 | isScrolling = false; 121 | this.notifyDataSetChanged(); 122 | } else { 123 | isScrolling = true; 124 | } 125 | if (listener != null) { 126 | listener.onScrollStateChanged(view, scrollState); 127 | } 128 | } 129 | 130 | @Override 131 | public void onScroll(AbsListView view, int firstVisibleItem, 132 | int visibleItemCount, int totalItemCount) { 133 | if (listener != null) { 134 | listener.onScroll(view, firstVisibleItem, visibleItemCount, 135 | totalItemCount); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lichenguang8706/KJFrameForAndroid_Modify/dc33b69e1d7279ccf6c73afbab2d894288b1f7df/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lichenguang8706/KJFrameForAndroid_Modify/dc33b69e1d7279ccf6c73afbab2d894288b1f7df/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lichenguang8706/KJFrameForAndroid_Modify/dc33b69e1d7279ccf6c73afbab2d894288b1f7df/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lichenguang8706/KJFrameForAndroid_Modify/dc33b69e1d7279ccf6c73afbab2d894288b1f7df/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lichenguang8706/KJFrameForAndroid_Modify/dc33b69e1d7279ccf6c73afbab2d894288b1f7df/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /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 | kjframe 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/org/kymjs/kjframe/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package org.kymjs.kjframe; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /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:1.3.0' 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 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lichenguang8706/KJFrameForAndroid_Modify/dc33b69e1d7279ccf6c73afbab2d894288b1f7df/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Sep 29 12:28:27 CST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /kjframe.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------