entries = dexfile.entries();
36 |
37 | while (entries.hasMoreElements()) {
38 | String element = entries.nextElement();
39 | if (element.contains(packageName)) {
40 | paths.add(element);
41 | }
42 | }
43 | }
44 |
45 | return paths;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/saf-core/src/main/java/com/safframework/saf/utils/ResourceUtil.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.safframework.saf.utils;
5 |
6 | import android.content.Context;
7 | import android.content.pm.PackageInfo;
8 | import android.content.pm.PackageManager;
9 | import android.content.pm.PackageManager.NameNotFoundException;
10 |
11 | import java.lang.reflect.Field;
12 |
13 | /**
14 | * 通过反射获取资源文件的帮助类
15 | * 使用方法,可现在app的引导页面中使用如下的语句:
16 | *
17 | * ResourceUtil.GEN_PACKAGE_NAME = ResourceUtil.getPackageName(contex)+".R";
18 | *
19 | *
20 | * 然后就可以使用了
21 | * @author Tony Shen
22 | *
23 | */
24 | public class ResourceUtil {
25 |
26 | public static String GEN_PACKAGE_NAME = "";
27 |
28 | /**
29 | * 获取app的包名
30 | * @param contex
31 | * @return
32 | */
33 | public static String getPackageName(Context contex) {
34 | PackageManager manager = contex.getPackageManager();
35 | try {
36 | PackageInfo info = manager.getPackageInfo(contex.getPackageName(), 0);
37 | return info.packageName;
38 | } catch (NameNotFoundException e) {
39 | e.printStackTrace();
40 | }
41 | return null;
42 | }
43 |
44 | public static void setPackageName(String packageName) {
45 | StringBuilder sb = new StringBuilder();
46 | sb.append(packageName);
47 | sb.append(".R");
48 | GEN_PACKAGE_NAME = sb.toString();
49 | }
50 |
51 | /**
52 | * 获取android资源id
53 | * @param packageName 调用方包的名称
54 | * @param resFileName 资源文件名
55 | * @param parameterName
56 | * @return
57 | */
58 | public static int getResourceId(String packageName, String resFileName,
59 | String parameterName) {
60 | if ((packageName != null) && (resFileName != null)
61 | && (parameterName != null))
62 | try {
63 | Class localClass = Class.forName(packageName + "$"
64 | + resFileName);
65 | Field localField = localClass.getField(parameterName);
66 | Object localObject = localField.get(localClass.newInstance());
67 | return Integer.parseInt(localObject.toString());
68 | } catch (Exception e) {
69 | e.printStackTrace();
70 | }
71 | return -1;
72 | }
73 |
74 | /**
75 | * 获取android资源id
76 | * @param resFileName 资源文件名
77 | * @param parameterName
78 | * @return
79 | */
80 | public static int getResourceId(String resFileName,
81 | String parameterName) {
82 | return getResourceId(GEN_PACKAGE_NAME, resFileName,parameterName);
83 | }
84 |
85 | /**
86 | * 获取工程中资源id
87 | * @param parameterName
88 | * @return
89 | */
90 | public static int getResourceId(String parameterName) {
91 | return getResourceId("id",parameterName);
92 | }
93 |
94 | /**
95 | * 获取工程中array资源id
96 | * @param parameterName
97 | * @return
98 | */
99 | public static int getResourceArrayId(String parameterName) {
100 | return getResourceId("array",parameterName);
101 | }
102 |
103 | /**
104 | * 获取工程中color资源id
105 | * @param parameterName
106 | * @return
107 | */
108 | public static int getResourceColorId(String parameterName) {
109 | return getResourceId("color",parameterName);
110 | }
111 |
112 | /**
113 | * 获取工程中drawable资源id
114 | * @param parameterName
115 | * @return
116 | */
117 | public static int getResourceDrawableId(String parameterName) {
118 | return getResourceId("drawable",parameterName);
119 | }
120 |
121 | /**
122 | * 获取工程中layout资源id
123 | * @param parameterName
124 | * @return
125 | */
126 | public static int getResourceLayoutId(String parameterName) {
127 | return getResourceId("layout",parameterName);
128 | }
129 |
130 | /**
131 | * 获取工程中string资源id
132 | * @param parameterName
133 | * @return
134 | */
135 | public static int getResourceStringId(String parameterName) {
136 | return getResourceId("string",parameterName);
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/saf-core/src/main/java/com/safframework/saf/utils/ViewUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.safframework.saf.utils;
5 |
6 | import android.graphics.Rect;
7 | import android.text.Editable;
8 | import android.text.TextWatcher;
9 | import android.util.DisplayMetrics;
10 | import android.view.TouchDelegate;
11 | import android.view.View;
12 | import android.widget.Button;
13 | import android.widget.EditText;
14 |
15 | import com.safframework.tony.common.utils.Preconditions;
16 |
17 | /**
18 | * @author Tony Shen
19 | *
20 | */
21 | public class ViewUtils {
22 |
23 | /**
24 | * 增加view的点击区域,当view是一张小图或者不方便点击时可采用此方法
25 | *
26 | * @param amount
27 | * @param delegate
28 | */
29 | public static void increaseHitRectBy(final int amount, final View delegate) {
30 | increaseHitRectBy(amount, amount, amount, amount, delegate);
31 | }
32 |
33 | /**
34 | *
35 | * @param top
36 | * @param left
37 | * @param bottom
38 | * @param right
39 | * @param delegate
40 | */
41 | public static void increaseHitRectBy(final int top, final int left,
42 | final int bottom, final int right, final View delegate) {
43 | final View parent = (View) delegate.getParent();
44 | if (parent != null && delegate.getContext() != null) {
45 | parent.post(new Runnable() {
46 | // Post in the parent's message queue to make sure the parent
47 | // lays out its children before we call getHitRect()
48 | public void run() {
49 | final float densityDpi = delegate.getContext()
50 | .getResources().getDisplayMetrics().densityDpi;
51 | final Rect r = new Rect();
52 | delegate.getHitRect(r);
53 | r.top -= transformToDensityPixel(top, densityDpi);
54 | r.left -= transformToDensityPixel(left, densityDpi);
55 | r.bottom += transformToDensityPixel(bottom, densityDpi);
56 | r.right += transformToDensityPixel(right, densityDpi);
57 | parent.setTouchDelegate(new TouchDelegate(r, delegate));
58 | }
59 | });
60 | }
61 | }
62 |
63 | public static int transformToDensityPixel(int regularPixel,
64 | DisplayMetrics displayMetrics) {
65 | return transformToDensityPixel(regularPixel, displayMetrics.densityDpi);
66 | }
67 |
68 | public static int transformToDensityPixel(int regularPixel, float densityDpi) {
69 | return (int) (regularPixel * densityDpi);
70 | }
71 |
72 | public static boolean checkBtnEnable(EditText... editTexts) {
73 | boolean enable = true;
74 | for (EditText each : editTexts) {
75 | if (Preconditions.isBlank(each.getText())) {
76 | enable = false;
77 | break;
78 | }
79 | }
80 | return enable;
81 | }
82 |
83 | public static void checkNotBlank(final Button button,
84 | final EditText... editTexts) {
85 | TextWatcher notBlank = new TextWatcher() {
86 | @Override
87 | public void beforeTextChanged(CharSequence charSequence, int i,
88 | int i2, int i3) {
89 |
90 | }
91 |
92 | @Override
93 | public void onTextChanged(CharSequence charSequence, int i, int i2,
94 | int i3) {
95 | if (checkBtnEnable(editTexts)) {
96 | button.setEnabled(true);
97 | } else {
98 | button.setEnabled(false);
99 | }
100 | }
101 |
102 | @Override
103 | public void afterTextChanged(Editable editable) {
104 |
105 | }
106 | };
107 |
108 | for (EditText each : editTexts) {
109 | each.addTextChangedListener(notBlank);
110 | }
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/saf-core/src/main/java/com/safframework/saf/view/LightDialog.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package com.safframework.saf.view;
5 |
6 | import android.app.AlertDialog;
7 | import android.content.Context;
8 |
9 | import com.safframework.saf.utils.SAFUtils;
10 |
11 | /**
12 | * Holo Light theme的dialog
13 | * 用法如下:
14 | *
15 | *
16 | * LightDialog dialog = LightDialog.create(this,"title","test");
17 | * dialog.show();
18 | *
19 | *
20 | * @author Tony Shen
21 | *
22 | */
23 | public class LightDialog extends AlertDialog{
24 |
25 | /**
26 | * 创建LightDialog,在android4.0及以上的版本dialog采用Holo Light theme
27 | *
28 | * @param context
29 | * @return light alert dialog
30 | */
31 | public static LightDialog create(Context context) {
32 | LightDialog dialog;
33 | if (SAFUtils.isICSOrHigher())
34 | dialog = new LightDialog(context, 3);
35 | else {
36 | dialog = new LightDialog(context);
37 | dialog.setInverseBackgroundForced(true);
38 | }
39 | return dialog;
40 | }
41 |
42 | public static LightDialog create(Context context, String title, String message) {
43 | LightDialog dialog = create(context);
44 | dialog.setTitle(title);
45 | dialog.setMessage(message);
46 | return dialog;
47 | }
48 |
49 | public static LightDialog create(Context context, int title, int message) {
50 | LightDialog dialog = create(context);
51 | dialog.setTitle(title);
52 | dialog.setMessage(context.getString(message));
53 | return dialog;
54 | }
55 |
56 | public static LightDialog create(Context context, int title, String message) {
57 | LightDialog dialog = create(context);
58 | dialog.setTitle(title);
59 | dialog.setMessage(message);
60 | return dialog;
61 | }
62 |
63 | public static LightDialog create(Context context, String title, int message) {
64 | return create(context, title, context.getString(message));
65 | }
66 |
67 | protected LightDialog(Context context) {
68 | super(context);
69 | }
70 |
71 | /**
72 | * @param context
73 | * @param theme
74 | */
75 | protected LightDialog(Context context, int theme) {
76 | super(context, theme);
77 | }
78 |
79 | public LightDialog setPositiveButton(int text, OnClickListener listener) {
80 | return setPositiveButton(getContext().getString(text), listener);
81 | }
82 |
83 | public LightDialog setPositiveButton(CharSequence text,
84 | OnClickListener listener) {
85 | setButton(BUTTON_POSITIVE, text, listener);
86 | return this;
87 | }
88 |
89 | public LightDialog setPositiveButton(OnClickListener listener) {
90 | return setPositiveButton(android.R.string.ok, listener);
91 | }
92 |
93 | public LightDialog setNegativeButton(int text, OnClickListener listener) {
94 | return setNegativeButton(getContext().getString(text), listener);
95 | }
96 |
97 | public LightDialog setNegativeButton(CharSequence text,
98 | OnClickListener listener) {
99 | setButton(BUTTON_NEGATIVE, text, listener);
100 | return this;
101 | }
102 |
103 | public LightDialog setNegativeButton(OnClickListener listener) {
104 | return setNegativeButton(android.R.string.cancel, listener);
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/saf-core/src/main/java/com/safframework/saf/view/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * SAF常用的组件
3 | */
4 | package com.safframework.saf.view;
--------------------------------------------------------------------------------
/saf-core/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzhizi715/SAF/e32a9ad8bec474e85c2cf168fe61a2cf2f3e4374/saf-core/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/saf-core/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzhizi715/SAF/e32a9ad8bec474e85c2cf168fe61a2cf2f3e4374/saf-core/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/saf-core/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzhizi715/SAF/e32a9ad8bec474e85c2cf168fe61a2cf2f3e4374/saf-core/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/saf-core/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzhizi715/SAF/e32a9ad8bec474e85c2cf168fe61a2cf2f3e4374/saf-core/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/saf-core/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/saf-core/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/saf-core/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SAF
3 |
4 | Hello world!
5 | Settings
6 |
7 |
--------------------------------------------------------------------------------
/saf-core/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/saf-permission/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/saf-permission/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | def cfg = rootProject.ext.configuration // 配置
5 | def libs = rootProject.ext.libraries // 库
6 |
7 | android {
8 | compileSdkVersion cfg.compileVersion
9 | buildToolsVersion cfg.buildToolsVersion
10 |
11 | defaultConfig {
12 | minSdkVersion 11
13 | targetSdkVersion 25
14 | versionCode 1
15 | versionName "1.0"
16 |
17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 |
19 | }
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | }
27 |
28 | dependencies {
29 | compile fileTree(dir: 'libs', include: ['*.jar'])
30 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
31 | exclude group: 'com.android.support', module: 'support-annotations'
32 | })
33 | compileOnly 'com.android.support:appcompat-v7:25.1.1'
34 | testCompile 'junit:junit:4.12'
35 |
36 | compileOnly rootProject.ext.rxJava
37 | compileOnly rootProject.ext.rxAndroid
38 | }
39 |
40 | repositories {
41 | jcenter()
42 | }
43 |
44 | allprojects {
45 | repositories {
46 | jcenter()
47 | }
48 | //加上这些
49 | tasks.withType(Javadoc) {
50 | options{ encoding "UTF-8"
51 | charSet 'UTF-8'
52 | links "http://docs.oracle.com/javase/7/docs/api"
53 | }
54 | }
55 | }
56 |
57 | publish{
58 | userOrg = 'fengzhizi715'
59 | groupId = 'com.safframework'
60 | artifactId = 'saf-permission'
61 | publishVersion = '1.1.0'
62 | desc = 'this is a permission library for android'
63 | website = 'https://github.com/fengzhizi715/SAF'
64 | }
--------------------------------------------------------------------------------
/saf-permission/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 /usr/local/Cellar/android-sdk/24.3.4/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/saf-permission/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/saf-permission/src/main/java/com/safframework/permission/Permission.java:
--------------------------------------------------------------------------------
1 | package com.safframework.permission;
2 |
3 | /**
4 | * Created by Tony Shen on 2017/6/23.
5 | */
6 |
7 | public class Permission {
8 |
9 | public final String name;
10 | public final boolean granted;
11 | public final boolean shouldShowRequestPermissionRationale;
12 |
13 | public Permission(String name, boolean granted) {
14 | this(name, granted, false);
15 | }
16 |
17 | public Permission(String name, boolean granted, boolean shouldShowRequestPermissionRationale) {
18 | this.name = name;
19 | this.granted = granted;
20 | this.shouldShowRequestPermissionRationale = shouldShowRequestPermissionRationale;
21 | }
22 |
23 | @Override
24 | @SuppressWarnings("SimplifiableIfStatement")
25 | public boolean equals(final Object o) {
26 | if (this == o) return true;
27 | if (o == null || getClass() != o.getClass()) return false;
28 |
29 | final Permission that = (Permission) o;
30 |
31 | if (granted != that.granted) return false;
32 | if (shouldShowRequestPermissionRationale != that.shouldShowRequestPermissionRationale)
33 | return false;
34 | return name.equals(that.name);
35 | }
36 |
37 | @Override
38 | public int hashCode() {
39 | int result = name.hashCode();
40 | result = 31 * result + (granted ? 1 : 0);
41 | result = 31 * result + (shouldShowRequestPermissionRationale ? 1 : 0);
42 | return result;
43 | }
44 |
45 | @Override
46 | public String toString() {
47 | return "Permission{" +
48 | "name='" + name + '\'' +
49 | ", granted=" + granted +
50 | ", shouldShowRequestPermissionRationale=" + shouldShowRequestPermissionRationale +
51 | '}';
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/saf-permission/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | saf-permission
3 |
4 |
--------------------------------------------------------------------------------
/saf-queue/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/saf-queue/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | def cfg = rootProject.ext.configuration // 配置
5 | def libs = rootProject.ext.libraries // 库
6 |
7 | android {
8 | compileSdkVersion cfg.compileVersion
9 | buildToolsVersion cfg.buildToolsVersion
10 |
11 | defaultConfig {
12 | minSdkVersion 9
13 | targetSdkVersion 25
14 | versionCode 1
15 | versionName "1.0"
16 |
17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 |
19 | }
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | }
27 |
28 | dependencies {
29 | compile fileTree(dir: 'libs', include: ['*.jar'])
30 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
31 | exclude group: 'com.android.support', module: 'support-annotations'
32 | })
33 | compile 'com.android.support:appcompat-v7:25.1.1'
34 | testCompile 'junit:junit:4.12'
35 | }
36 |
37 | repositories {
38 | jcenter()
39 | }
40 |
41 | allprojects {
42 | repositories {
43 | jcenter()
44 | }
45 | //加上这些
46 | tasks.withType(Javadoc) {
47 | options{ encoding "UTF-8"
48 | charSet 'UTF-8'
49 | links "http://docs.oracle.com/javase/7/docs/api"
50 | }
51 | }
52 | }
53 |
54 | publish{
55 | userOrg = 'fengzhizi715'
56 | groupId = 'com.safframework'
57 | artifactId = 'saf-queue'
58 | publishVersion = '1.0.1'
59 | desc = 'this is a queue library for android'
60 | website = 'https://github.com/fengzhizi715/SAF'
61 | }
--------------------------------------------------------------------------------
/saf-queue/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 /usr/local/Cellar/android-sdk/23.0.2/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 |
--------------------------------------------------------------------------------
/saf-queue/src/androidTest/java/com/safframework/queue/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.safframework.queue;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.safframework.queue.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/saf-queue/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/saf-queue/src/main/java/com/safframework/queue/Operation.java:
--------------------------------------------------------------------------------
1 | package com.safframework.queue;
2 |
3 | import android.os.Bundle;
4 |
5 | /**
6 | * Created by tony on 2017/4/15.
7 | */
8 |
9 | public interface Operation {
10 |
11 | void run(Queue queue, Bundle bundle);
12 | }
13 |
--------------------------------------------------------------------------------
/saf-queue/src/main/java/com/safframework/queue/OperationRunnable.java:
--------------------------------------------------------------------------------
1 | package com.safframework.queue;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 |
6 | import java.lang.ref.WeakReference;
7 |
8 | /**
9 | * Created by tony on 2017/4/15.
10 | */
11 |
12 | public class OperationRunnable implements Runnable {
13 |
14 | private Operation operation = null;
15 | private Type type = Type.NORMAL;
16 | private Object token = null;
17 | private long time = 0;
18 | private WeakReference owner;
19 | private static final Handler handler = new Handler(Looper.getMainLooper());
20 |
21 | protected OperationRunnable(Queue queue, Operation operation) {
22 | this(queue, operation, Type.NORMAL, null, 0);
23 | }
24 |
25 | public static void runOnUiThread(Runnable runnable) {
26 | handler.post(runnable);
27 | }
28 |
29 | public static void runOnUiThreadAfterDelay(Runnable runnable, long delayTimeMillis) {
30 | handler.postDelayed(runnable, delayTimeMillis);
31 | }
32 |
33 | public static void removeOperationOnUiThread(Runnable runnable) {
34 | handler.removeCallbacks(runnable);
35 | }
36 |
37 | public static void sleep(long sleepTimeMillis) {
38 | try {
39 | Thread.sleep(sleepTimeMillis);
40 | } catch (Exception e) {
41 | }
42 | }
43 |
44 | protected enum Type {
45 |
46 | NORMAL,
47 | ATFIRST,
48 | ATTIME,
49 | ATTIME_WITH_TOKEN,
50 | DELAY,
51 | }
52 |
53 | protected OperationRunnable(Queue queue, Operation operation, Type type, Object token, long time) {
54 | this.owner = new WeakReference(queue);
55 | this.operation = operation;
56 | this.type = type;
57 | this.token = token;
58 | this.time = time;
59 | }
60 |
61 | @Override
62 | public boolean equals(Object o) {
63 | if (this == o) return true;
64 | if (o == null || getClass() != o.getClass()) return false;
65 |
66 | OperationRunnable that = (OperationRunnable) o;
67 |
68 | if (!operation.equals(that.operation)) return false;
69 | return token != null ? token.equals(that.token) : that.token == null;
70 |
71 | }
72 |
73 | @Override
74 | public int hashCode() {
75 | int result = operation.hashCode();
76 | result = 31 * result + (token != null ? token.hashCode() : 0);
77 | return result;
78 | }
79 |
80 | @Override
81 | public void run() {
82 |
83 | Queue queue = owner.get();
84 | if(queue != null && queue.isActivated()) {
85 | operation.run(queue, queue.getBundle());
86 | }
87 |
88 | }
89 |
90 | protected void queueing(Handler handler) {
91 | switch (type) {
92 | case NORMAL:
93 | handler.post(this);
94 | break;
95 | case ATFIRST:
96 | handler.postAtFrontOfQueue(this);
97 | break;
98 | case ATTIME:
99 | handler.postAtTime(this, time);
100 | break;
101 | case ATTIME_WITH_TOKEN:
102 | handler.postAtTime(this, token, time);
103 | break;
104 | case DELAY:
105 | handler.postDelayed(this, time);
106 | break;
107 | default:
108 | handler.post(this);
109 | break;
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/saf-queue/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | saf-queue
3 |
4 |
--------------------------------------------------------------------------------
/saf-rxlifecycle/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/saf-rxlifecycle/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | def cfg = rootProject.ext.configuration // 配置
5 | def libs = rootProject.ext.libraries // 库
6 |
7 | android {
8 | compileSdkVersion cfg.compileVersion
9 | buildToolsVersion cfg.buildToolsVersion
10 |
11 | defaultConfig {
12 | minSdkVersion cfg.minSdk
13 | targetSdkVersion cfg.targetSdk
14 | versionCode 1
15 | versionName cfg.saf_version_name
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | lintOptions {
24 | abortOnError false
25 | }
26 | }
27 |
28 | dependencies {
29 | compile fileTree(dir: 'libs', include: ['*.jar'])
30 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
31 | exclude group: 'com.android.support', module: 'support-annotations'
32 | })
33 | compile 'com.android.support:appcompat-v7:25.1.1'
34 | testCompile 'junit:junit:4.12'
35 |
36 | compile rootProject.ext.rxJava
37 | compile rootProject.ext.rxAndroid
38 | }
39 |
40 | repositories {
41 | jcenter()
42 | }
43 |
44 | allprojects {
45 | repositories {
46 | jcenter()
47 | }
48 | //加上这些
49 | tasks.withType(Javadoc) {
50 | options{ encoding "UTF-8"
51 | charSet 'UTF-8'
52 | links "http://docs.oracle.com/javase/7/docs/api"
53 | }
54 | }
55 | }
56 |
57 | publish{
58 | userOrg = 'fengzhizi715'
59 | groupId = 'com.safframework'
60 | artifactId = 'saf-rxlifecycle'
61 | publishVersion = '1.1.2'
62 | desc = 'this is a lifecycle library for rxjava2 in android'
63 | website = 'https://github.com/fengzhizi715/SAF'
64 | }
--------------------------------------------------------------------------------
/saf-rxlifecycle/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 /usr/local/Cellar/android-sdk/24.3.4/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/saf-rxlifecycle/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/saf-rxlifecycle/src/main/java/com/safframework/lifecycle/BindingFragment.java:
--------------------------------------------------------------------------------
1 | package com.safframework.lifecycle;
2 |
3 | import android.app.Activity;
4 | import android.app.Fragment;
5 | import android.content.Context;
6 | import android.os.Build;
7 | import android.os.Bundle;
8 | import android.support.annotation.Nullable;
9 | import android.support.annotation.RequiresApi;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 |
14 | /**
15 | * Created by tony on 2017/12/26.
16 | */
17 | @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
18 | public class BindingFragment extends Fragment {
19 |
20 | private final LifecyclePublisher lifecyclePublisher = new LifecyclePublisher();
21 |
22 | public BindingFragment() {
23 | }
24 |
25 | public LifecyclePublisher getLifecyclePublisher() {
26 | return lifecyclePublisher;
27 | }
28 |
29 | @Override
30 | public void onAttach(Context context) {
31 | super.onAttach(context);
32 | lifecyclePublisher.onAttach();
33 | }
34 |
35 | @Override
36 | public void onAttach(Activity activity) {
37 | super.onAttach(activity);
38 | lifecyclePublisher.onAttach();
39 | }
40 |
41 | @Override
42 | public void onCreate(@Nullable Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | lifecyclePublisher.onCreate();
45 | }
46 |
47 | @Nullable
48 | @Override
49 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
50 | lifecyclePublisher.onCreateView();
51 | return null;
52 | }
53 |
54 | @Override
55 | public void onStart() {
56 | super.onStart();
57 | lifecyclePublisher.onStart();
58 | }
59 |
60 | @Override
61 | public void onResume() {
62 | super.onResume();
63 | lifecyclePublisher.onResume();
64 | }
65 |
66 | @Override
67 | public void onPause() {
68 | super.onPause();
69 | lifecyclePublisher.onPause();
70 | }
71 |
72 | @Override
73 | public void onStop() {
74 | super.onStop();
75 | lifecyclePublisher.onStop();
76 | }
77 |
78 | @Override
79 | public void onDestroyView() {
80 | super.onDestroyView();
81 | lifecyclePublisher.onDestroyView();
82 | }
83 |
84 | @Override
85 | public void onDestroy() {
86 | super.onDestroy();
87 | lifecyclePublisher.onDestroy();
88 | }
89 |
90 | @Override
91 | public void onDetach() {
92 | super.onDetach();
93 | lifecyclePublisher.onDetach();
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/saf-rxlifecycle/src/main/java/com/safframework/lifecycle/BindingV4Fragment.java:
--------------------------------------------------------------------------------
1 | package com.safframework.lifecycle;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.support.annotation.Nullable;
7 | import android.support.v4.app.Fragment;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 |
12 | /**
13 | * Created by Tony Shen on 2017/5/25.
14 | */
15 |
16 | public class BindingV4Fragment extends Fragment {
17 |
18 | private final LifecyclePublisher lifecyclePublisher = new LifecyclePublisher();
19 |
20 | public BindingV4Fragment() {
21 | }
22 |
23 | public LifecyclePublisher getLifecyclePublisher() {
24 | return lifecyclePublisher;
25 | }
26 |
27 | @Override
28 | public void onAttach(Context context) {
29 | super.onAttach(context);
30 | lifecyclePublisher.onAttach();
31 | }
32 |
33 | @Override
34 | public void onAttach(Activity activity) {
35 | super.onAttach(activity);
36 | lifecyclePublisher.onAttach();
37 | }
38 |
39 | @Override
40 | public void onCreate(@Nullable Bundle savedInstanceState) {
41 | super.onCreate(savedInstanceState);
42 | lifecyclePublisher.onCreate();
43 | }
44 |
45 | @Nullable
46 | @Override
47 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
48 | lifecyclePublisher.onCreateView();
49 | return null;
50 | }
51 |
52 | @Override
53 | public void onStart() {
54 | super.onStart();
55 | lifecyclePublisher.onStart();
56 | }
57 |
58 | @Override
59 | public void onResume() {
60 | super.onResume();
61 | lifecyclePublisher.onResume();
62 | }
63 |
64 | @Override
65 | public void onPause() {
66 | super.onPause();
67 | lifecyclePublisher.onPause();
68 | }
69 |
70 | @Override
71 | public void onStop() {
72 | super.onStop();
73 | lifecyclePublisher.onStop();
74 | }
75 |
76 | @Override
77 | public void onDestroyView() {
78 | super.onDestroyView();
79 | lifecyclePublisher.onDestroyView();
80 | }
81 |
82 | @Override
83 | public void onDestroy() {
84 | super.onDestroy();
85 | lifecyclePublisher.onDestroy();
86 | }
87 |
88 | @Override
89 | public void onDetach() {
90 | super.onDetach();
91 | lifecyclePublisher.onDetach();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/saf-rxlifecycle/src/main/java/com/safframework/lifecycle/LifecyclePublisher.java:
--------------------------------------------------------------------------------
1 | package com.safframework.lifecycle;
2 |
3 | import android.support.annotation.IntDef;
4 |
5 | import io.reactivex.processors.BehaviorProcessor;
6 |
7 | /**
8 | * Created by Tony Shen on 2017/5/25.
9 | */
10 |
11 | public class LifecyclePublisher {
12 |
13 | public static final int ON_ATTACH = 0;
14 | public static final int ON_CREATE = 1;
15 | public static final int ON_CREATE_VIEW = 2;
16 | public static final int ON_START = 3;
17 | public static final int ON_RESUME = 4;
18 | public static final int ON_PAUSE = 5;
19 | public static final int ON_STOP = 6;
20 | public static final int ON_DESTROY_VIEW = 7;
21 | public static final int ON_DESTROY = 8;
22 | public static final int ON_DETACH = 9;
23 |
24 | private final BehaviorProcessor behavior = BehaviorProcessor.create();
25 |
26 | @IntDef({ON_ATTACH, ON_CREATE, ON_CREATE_VIEW,
27 | ON_START, ON_RESUME,
28 | ON_PAUSE, ON_STOP,
29 | ON_DESTROY_VIEW, ON_DESTROY, ON_DETACH})
30 | public @interface Event {
31 | }
32 |
33 | public BehaviorProcessor getBehavior() {
34 | return behavior;
35 | }
36 |
37 | public void onAttach() {
38 | behavior.onNext(ON_ATTACH);
39 | }
40 |
41 | public void onCreate() {
42 | behavior.onNext(ON_CREATE);
43 | }
44 |
45 | public void onCreateView() {
46 | behavior.onNext(ON_CREATE_VIEW);
47 | }
48 |
49 | public void onStart() {
50 | behavior.onNext(ON_START);
51 | }
52 |
53 | public void onResume() {
54 | behavior.onNext(ON_RESUME);
55 | }
56 |
57 | public void onPause() {
58 | behavior.onNext(ON_PAUSE);
59 | }
60 |
61 | public void onStop() {
62 | behavior.onNext(ON_STOP);
63 | }
64 |
65 | public void onDestroyView() {
66 | behavior.onNext(ON_DESTROY_VIEW);
67 | }
68 |
69 | public void onDestroy() {
70 | behavior.onNext(ON_DESTROY);
71 | }
72 |
73 | public void onDetach() {
74 | behavior.onNext(ON_DETACH);
75 | }
76 | }
--------------------------------------------------------------------------------
/saf-rxlifecycle/src/main/java/com/safframework/lifecycle/RxLifecycle.java:
--------------------------------------------------------------------------------
1 | package com.safframework.lifecycle;
2 |
3 | import android.app.Fragment;
4 | import android.app.FragmentManager;
5 | import android.app.FragmentTransaction;
6 | import android.os.Build;
7 | import android.support.annotation.NonNull;
8 | import android.support.annotation.RequiresApi;
9 | import android.support.v7.app.AppCompatActivity;
10 |
11 | import io.reactivex.Flowable;
12 | import io.reactivex.Observable;
13 |
14 | /**
15 | * Created by Tony Shen on 2017/5/25.
16 | */
17 |
18 | public class RxLifecycle {
19 |
20 | private static final String FRAGMENT_TAG = "_BINDING_FRAGMENT_";
21 | private final LifecyclePublisher lifecyclePublisher;
22 |
23 | @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
24 | public static RxLifecycle bind(@NonNull AppCompatActivity targetActivity) {
25 | return bind(targetActivity.getSupportFragmentManager());
26 | }
27 |
28 |
29 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
30 | public static RxLifecycle bind(@NonNull Fragment targetFragment) {
31 | return bind(targetFragment.getChildFragmentManager());
32 | }
33 |
34 | @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
35 | public static RxLifecycle bind(@NonNull FragmentManager fragmentManager) {
36 | BindingFragment fragment = (BindingFragment) fragmentManager.findFragmentByTag(FRAGMENT_TAG);
37 | if (fragment == null) {
38 | fragment = new BindingFragment();
39 |
40 | final FragmentTransaction transaction = fragmentManager.beginTransaction();
41 | transaction.add(fragment, FRAGMENT_TAG);
42 | transaction.commit();
43 |
44 | } else if (Build.VERSION.SDK_INT >= 13 && fragment.isDetached()) {
45 | final FragmentTransaction transaction = fragmentManager.beginTransaction();
46 | transaction.attach(fragment);
47 | transaction.commit();
48 | }
49 |
50 | return bind(fragment.getLifecyclePublisher());
51 | }
52 |
53 | public static RxLifecycle bind(@NonNull android.support.v4.app.Fragment targetFragment) {
54 | return bind(targetFragment.getChildFragmentManager());
55 | }
56 |
57 | public static RxLifecycle bind(@NonNull android.support.v4.app.FragmentManager fragmentManager) {
58 | BindingV4Fragment fragment = (BindingV4Fragment) fragmentManager.findFragmentByTag(FRAGMENT_TAG);
59 | if (fragment == null) {
60 | fragment = new BindingV4Fragment();
61 |
62 | final android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
63 | transaction.add(fragment, FRAGMENT_TAG);
64 | transaction.commit();
65 | } else if (fragment.isDetached()) {
66 |
67 | final android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
68 | transaction.attach(fragment);
69 | transaction.commit();
70 | }
71 |
72 | return bind(fragment.getLifecyclePublisher());
73 | }
74 |
75 | public static RxLifecycle bind(@NonNull LifecyclePublisher lifecyclePublisher) {
76 | return new RxLifecycle(lifecyclePublisher);
77 | }
78 |
79 | private RxLifecycle() throws IllegalAccessException {
80 | throw new IllegalAccessException();
81 | }
82 |
83 | private RxLifecycle(@NonNull LifecyclePublisher lifecyclePublisher) {
84 | this.lifecyclePublisher = lifecyclePublisher;
85 | }
86 |
87 | public Flowable asFlowable() {
88 | return lifecyclePublisher.getBehavior();
89 | }
90 |
91 | public Observable asObservable() {
92 | return lifecyclePublisher.getBehavior().toObservable();
93 | }
94 |
95 | public LifecycleTransformer toLifecycleTransformer() {
96 | return new LifecycleTransformer(lifecyclePublisher.getBehavior());
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/saf-rxlifecycle/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | saf-rxlifecycle
3 |
4 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':saf-core'
2 | include ':saf-queue'
3 | include ':saf-cache'
4 | include ':saf-permission'
5 | include ':saf-rxlifecycle'
6 | include 'app'
7 |
--------------------------------------------------------------------------------