├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── JavaEcho
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── edward
│ │ └── javaecho
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── edward
│ │ │ └── javaecho
│ │ │ ├── StringUtils.java
│ │ │ └── SystemOut.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── edward
│ └── javaecho
│ └── ExampleUnitTest.java
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── edward
│ │ └── edward
│ │ └── rxjava2tutorial
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── directory.json
│ ├── java
│ │ └── com
│ │ │ └── edward
│ │ │ └── rxjava
│ │ │ ├── Rxjava2Demo
│ │ │ ├── Rxjava2Activity.java
│ │ │ ├── Rxjava2_2_Observable.java
│ │ │ ├── Rxjava2_3_Operators.java
│ │ │ ├── Rxjava2_4_Scheduler.java
│ │ │ ├── Rxjava2_5_Flowable.java
│ │ │ ├── Rxjava2_6_Single_Completable_Maybe.java
│ │ │ └── Rxjava2_8_Custom_Operators.java
│ │ │ ├── Rxjava2DemoBean.java
│ │ │ ├── WebViewActivity.java
│ │ │ └── directory
│ │ │ ├── DirectoryActivity.java
│ │ │ └── DirectoryAdapter.java
│ └── res
│ │ ├── drawable
│ │ └── button_selector.xml
│ │ ├── layout
│ │ ├── activity_directory.xml
│ │ ├── activity_directory_item.xml
│ │ ├── activity_rxjava2.xml
│ │ ├── activity_web_view.xml
│ │ └── simple_spinner_item.xml
│ │ ├── mipmap-xhdpi
│ │ └── directory_demo_icon.jpg
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── edward
│ └── edward
│ └── rxjava2tutorial
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.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 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/JavaEcho/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/JavaEcho/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 28
5 |
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion 15
10 | targetSdkVersion 28
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
15 |
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 |
30 | implementation 'com.android.support:appcompat-v7:28.0.0'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | }
35 |
--------------------------------------------------------------------------------
/JavaEcho/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/JavaEcho/src/androidTest/java/com/edward/javaecho/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.edward.javaecho;
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 | * Instrumented 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() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.edward.javaecho.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/JavaEcho/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/JavaEcho/src/main/java/com/edward/javaecho/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.edward.javaecho;
2 |
3 | import android.content.ClipData;
4 | import android.content.ClipboardManager;
5 | import android.content.Context;
6 | import android.widget.Toast;
7 |
8 | /**
9 | * 功能描述:
10 | *
11 | * @author (作者) edward(冯丰枫)
12 | * @link http://www.jianshu.com/u/f7176d6d53d2
13 | * 创建时间: 2019/1/1
14 | */
15 | public class StringUtils {
16 | /**
17 | * 复制文本到系统粘贴版
18 | */
19 | public static void copy(CharSequence text, Context context) {
20 | ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
21 | if (clipboard == null) return;
22 | clipboard.setPrimaryClip(ClipData.newPlainText("text", text));
23 | Toast.makeText(context, "复制成功", Toast.LENGTH_SHORT).show();
24 | }
25 |
26 | /**
27 | * 从系统粘贴板粘贴文本
28 | */
29 | public static String paste(Context context) {
30 | ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
31 | if (clipboard == null) return "";
32 | ClipData clipData = clipboard.getPrimaryClip();
33 | if (clipData != null) {
34 | return clipData.getItemAt(0).getText().toString().trim();
35 | }
36 | return "";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/JavaEcho/src/main/java/com/edward/javaecho/SystemOut.java:
--------------------------------------------------------------------------------
1 | package com.edward.javaecho;
2 |
3 | import android.app.Activity;
4 | import android.widget.TextView;
5 |
6 | /**
7 | * 功能描述:
8 | *
9 | * @author (作者) edward
10 | * 创建时间: 2018/12/17
11 | */
12 | public class SystemOut {
13 | private static Activity mActivity;
14 | private static TextView mTextView;
15 | private static Thread mThread;
16 |
17 |
18 | public static void init(Activity activity, TextView textView) {
19 | mThread = Thread.currentThread();
20 | mActivity = activity;
21 | mTextView = textView;
22 | }
23 |
24 | public static void reset() {
25 | if (mTextView == null) return;
26 | mTextView.setText("");
27 | }
28 |
29 | public static void clear() {
30 | if (mTextView == null) return;
31 | mTextView = null;
32 | }
33 |
34 | public static void println(int i) {
35 | println(Integer.toString(i));
36 | }
37 |
38 | public static void println(final String text) {
39 | System.out.println(text);
40 | if (mThread == Thread.currentThread()) {
41 | if (mTextView == null) return;
42 | mTextView.append(text + "\r\n");
43 | } else {
44 | if (mActivity == null) return;
45 | mActivity.runOnUiThread(new Runnable() {
46 | @Override
47 | public void run() {
48 | if (mTextView == null) return;
49 | mTextView.append(text + "\r\n");
50 | }
51 | });
52 | }
53 | }
54 |
55 | public static void println(final Throwable throwable) {
56 | throwable.printStackTrace();
57 | if (mThread == Thread.currentThread()) {
58 | if (mTextView == null) return;
59 | mTextView.append(throwable.getClass().getSimpleName() + throwable.getMessage() + "\r\n");
60 | for (StackTraceElement stackTraceElement : throwable.getStackTrace()) {
61 | mTextView.append(stackTraceElement.toString() + "\r\n");
62 | }
63 | } else {
64 | if (mActivity == null) return;
65 | mActivity.runOnUiThread(new Runnable() {
66 | @Override
67 | public void run() {
68 | if (mTextView == null) return;
69 | mTextView.append(throwable.getClass().getSimpleName() + throwable.getMessage() + "\r\n");
70 | for (StackTraceElement stackTraceElement : throwable.getStackTrace()) {
71 | mTextView.append(stackTraceElement.toString() + "\r\n");
72 | }
73 | }
74 | });
75 | }
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/JavaEcho/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | JavaEcho
3 |
4 |
--------------------------------------------------------------------------------
/JavaEcho/src/test/java/com/edward/javaecho/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.edward.javaecho;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | android {
3 | compileSdkVersion 28
4 | buildToolsVersion '28.0.3'
5 | defaultConfig {
6 | applicationId "com.edward.edward.rxjava2tutorial"
7 | minSdkVersion 15
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | compileOptions {
20 | sourceCompatibility '1.8'
21 | targetCompatibility '1.8'
22 | }
23 | }
24 |
25 | dependencies {
26 | compile fileTree(dir: 'libs', include: ['*.jar'])
27 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
28 | exclude group: 'com.android.support', module: 'support-annotations'
29 | })
30 | implementation project(':JavaEcho')
31 | implementation 'com.android.support:appcompat-v7:28.0.0'
32 | implementation "com.android.support:recyclerview-v7:28.0.0"
33 | implementation "com.android.support:support-v4:28.0.0"
34 | implementation "com.android.support:design:28.0.0"
35 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
36 | //rxjava2
37 | implementation "io.reactivex.rxjava2:rxjava:2.1.3"
38 | implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
39 | //butterknife
40 | implementation 'com.jakewharton:butterknife:8.8.1'
41 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
42 | //retrofit2
43 | implementation 'com.squareup.retrofit2:retrofit:2.2.0'
44 | implementation 'com.squareup.retrofit2:converter-gson:2.2.0'
45 | implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
46 | //rxlifecycle2
47 | implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
48 | implementation 'com.trello.rxlifecycle2:rxlifecycle-navi:2.1.0'
49 | }
50 |
--------------------------------------------------------------------------------
/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 C:\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/edward/edward/rxjava2tutorial/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.edward.edward.rxjava2tutorial;
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.edward.edward.rxjava2tutorial", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
31 |
32 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/assets/directory.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "index": 1,
4 | "title": "Rxjava2入门教程一:函数响应式编程及概述",
5 | "url": "https://www.jianshu.com/p/15b2f3d7141a",
6 | "demo_class": ""
7 | },
8 | {
9 | "index": 2,
10 | "title": "Rxjava2入门教程二:Observable与Observer响应式编程在Rxjava2中的典型实现",
11 | "url": "https://www.jianshu.com/p/c8150187714c",
12 | "demo_class": "Rxjava2_2_Observable"
13 | },
14 | {
15 | "index": 3,
16 | "title": "Rxjava2入门教程三:Operators操作符",
17 | "url": "https://www.jianshu.com/p/6e71e31c5d3d",
18 | "demo_class": "Rxjava2_3_Operators"
19 | },
20 | {
21 | "index": 4,
22 | "title": "Rxjava2入门教程四:Scheduler线程调度器",
23 | "url": "https://www.jianshu.com/p/12638513424f",
24 | "demo_class": "Rxjava2_4_Scheduler"
25 | },
26 | {
27 | "index": 5,
28 | "title": "Rxjava2入门教程五:Flowable背压支持——对Flowable最全面而详细的讲解",
29 | "url": "https://www.jianshu.com/p/ff8167c1d191",
30 | "demo_class": "Rxjava2_5_Flowable"
31 | },
32 | {
33 | "index": 6,
34 | "title": "Rxjava2入门教程六:Single、Completable、Maybe——简化版的Observable",
35 | "url": "https://www.jianshu.com/p/66a55abbadef",
36 | "demo_class": "Rxjava2_6_Single_Completable_Maybe"
37 | },
38 | {
39 | "index": 8,
40 | "title": "Rxjava2入门教程八:自定义操作符",
41 | "url": "https://www.jianshu.com/p/86c2b53c7117",
42 | "demo_class": "Rxjava2_8_Custom_Operators"
43 | }
44 | ]
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/Rxjava2Demo/Rxjava2Activity.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.Rxjava2Demo;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.reflect.TypeToken;
5 |
6 | import com.edward.javaecho.StringUtils;
7 | import com.edward.javaecho.SystemOut;
8 | import com.edward.rxjava.R;
9 | import com.edward.rxjava.Rxjava2DemoBean;
10 |
11 | import android.os.Bundle;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.text.TextUtils;
14 | import android.view.View;
15 | import android.widget.AdapterView;
16 | import android.widget.ArrayAdapter;
17 | import android.widget.Spinner;
18 | import android.widget.TextView;
19 |
20 | import java.io.BufferedReader;
21 | import java.io.InputStreamReader;
22 | import java.lang.reflect.Method;
23 | import java.util.ArrayList;
24 | import java.util.Arrays;
25 | import java.util.List;
26 | import java.util.concurrent.Callable;
27 |
28 | import butterknife.BindView;
29 | import butterknife.ButterKnife;
30 | import io.reactivex.Observable;
31 | import io.reactivex.Single;
32 | import io.reactivex.android.schedulers.AndroidSchedulers;
33 | import io.reactivex.disposables.Disposable;
34 | import io.reactivex.functions.Consumer;
35 | import io.reactivex.functions.Function;
36 | import io.reactivex.functions.Predicate;
37 | import io.reactivex.observables.GroupedObservable;
38 | import io.reactivex.schedulers.Schedulers;
39 |
40 | /**
41 | * 功能描述:Rxjava2入门教程Demo演示类
42 | *
43 | * @author (作者) edward(冯丰枫)
44 | * @link http://www.jianshu.com/u/f7176d6d53d2
45 | * 创建时间: 2018/12/17
46 | */
47 | public class Rxjava2Activity extends AppCompatActivity {
48 | @BindView(R.id.rxjava_caption)
49 | Spinner rxjava_caption;
50 | @BindView(R.id.rxjava_demo_method)
51 | Spinner rxjava_demo_method;
52 | @BindView(R.id.rxjava_demo_result)
53 | TextView rxjava_demo_result;
54 |
55 | private Disposable mTitleDisposable;
56 | private Disposable mDemoMethodDisposable;
57 | private Disposable mInvokeMethodDisposable;
58 | private List mRxjava2DemoBeans;
59 | private Class mClass;
60 | private List methods;
61 |
62 | @Override
63 | protected void onCreate(Bundle savedInstanceState) {
64 | super.onCreate(savedInstanceState);
65 | setContentView(R.layout.activity_rxjava2);
66 | ButterKnife.bind(this);
67 | rxjava_caption.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
68 | @Override
69 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
70 | initMethodSpinner(position);
71 | }
72 |
73 | @Override
74 | public void onNothingSelected(AdapterView> parent) {
75 |
76 | }
77 | });
78 | rxjava_demo_method.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
79 | @Override
80 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
81 | invokeMethodByName(position);
82 | }
83 |
84 | @Override
85 | public void onNothingSelected(AdapterView> parent) {
86 |
87 | }
88 | });
89 | mRxjava2DemoBeans = new ArrayList<>();
90 | initTitleSpinner();
91 | SystemOut.init(this, rxjava_demo_result);
92 | rxjava_demo_result.setOnLongClickListener(new View.OnLongClickListener() {
93 | @Override
94 | public boolean onLongClick(View v) {
95 | StringUtils.copy(rxjava_demo_result.getText(), Rxjava2Activity.this);
96 | return true;
97 | }
98 | });
99 | }
100 |
101 | /**
102 | * 根据配置文件,初始化Demo列表
103 | */
104 | private void initTitleSpinner() {
105 | if (mTitleDisposable != null && !mTitleDisposable.isDisposed()) mTitleDisposable.dispose();
106 | mTitleDisposable = Single
107 | .fromCallable(new Callable() {
108 | @Override
109 | public BufferedReader call() throws Exception {
110 | return new BufferedReader(new InputStreamReader(getAssets().open("directory.json")));
111 | }
112 | })
113 | .map(new Function>() {
114 | @Override
115 | public List apply(BufferedReader bufferedReader) throws Exception {
116 | return new Gson().fromJson(bufferedReader, new TypeToken>() {
117 | }.getType());
118 | }
119 | })
120 | .flatMapObservable(new Function, Observable>() {
121 | @Override
122 | public Observable apply(List rxjava2DemoBeans) throws Exception {
123 | return Observable.fromIterable(rxjava2DemoBeans);
124 | }
125 | })
126 | .filter(new Predicate() {
127 | @Override
128 | public boolean test(Rxjava2DemoBean rxjava2DemoBean) throws Exception {
129 | return !TextUtils.isEmpty(rxjava2DemoBean.getDemo_class());
130 | }
131 | })
132 | .doOnNext(new Consumer() {
133 | @Override
134 | public void accept(Rxjava2DemoBean rxjava2DemoBean) throws Exception {
135 | mRxjava2DemoBeans.add(rxjava2DemoBean);
136 | }
137 | })
138 | .map(new Function() {
139 | @Override
140 | public String apply(Rxjava2DemoBean rxjava2DemoBean) throws Exception {
141 | return rxjava2DemoBean.getTitle();
142 | }
143 | })
144 | .toList()
145 | .doOnSubscribe(new Consumer() {
146 | @Override
147 | public void accept(Disposable disposable) throws Exception {
148 | mRxjava2DemoBeans.clear();
149 | }
150 | })
151 | .subscribeOn(Schedulers.io())
152 | .observeOn(AndroidSchedulers.mainThread())
153 | .subscribe(new Consumer>() {
154 | @Override
155 | public void accept(List strings) throws Exception {
156 | rxjava_caption.setAdapter(new ArrayAdapter(Rxjava2Activity.this, R.layout.simple_spinner_item, R.id.spinner_text, strings));
157 | }
158 | });
159 | }
160 |
161 | /**
162 | * 根据类的全路径名,获取类中可执行的方法
163 | */
164 | private void initMethodSpinner(int index) {
165 | if (mDemoMethodDisposable != null && !mDemoMethodDisposable.isDisposed()) mDemoMethodDisposable.dispose();
166 | mDemoMethodDisposable =
167 | Single.just(mRxjava2DemoBeans.get(index))
168 | .map(new Function() {
169 | @Override
170 | public String apply(Rxjava2DemoBean rxjava2DemoBean) throws Exception {
171 | return "com.edward.rxjava.Rxjava2Demo." + rxjava2DemoBean.getDemo_class();//拼接Demo类的全路径名
172 | }
173 | })
174 | .map(new Function() {
175 | @Override
176 | public Class apply(String className) throws Exception {
177 | return Class.forName(className);//反射获取Demo类
178 | }
179 | })
180 | .doOnSuccess(new Consumer() {
181 | @Override
182 | public void accept(Class aClass) throws Exception {
183 | mClass = aClass;
184 | }
185 | })
186 | .map(new Function() {
187 | @Override
188 | public Method[] apply(Class aClass) throws Exception {
189 | return aClass.getDeclaredMethods();//获取Deme类中声明的所有方法
190 | }
191 | })
192 | .flatMapObservable(new Function>() {
193 | @Override
194 | public Observable apply(Method[] methods) throws Exception {
195 | return Observable.fromArray(methods);
196 | }
197 | })
198 | .map(new Function() {
199 | @Override
200 | public String apply(Method method) throws Exception {
201 | return method.getName();
202 | }
203 | })
204 | .filter(new Predicate() {
205 | @Override
206 | public boolean test(String s) throws Exception {//根据方法名过滤掉构造方法
207 | return !s.contains("access$super");
208 | }
209 | })
210 | .toList()
211 | .doOnSuccess(new Consumer>() {
212 | @Override
213 | public void accept(List strings) throws Exception {
214 | methods = strings;
215 | }
216 | })
217 | .subscribeOn(Schedulers.io())
218 | .observeOn(AndroidSchedulers.mainThread())
219 | .subscribe(new Consumer>() {
220 | @Override
221 | public void accept(List strings) throws Exception {
222 | rxjava_demo_method.setAdapter(new ArrayAdapter(Rxjava2Activity.this, R.layout.simple_spinner_item, R.id.spinner_text, strings));
223 | }
224 | });
225 |
226 | }
227 |
228 |
229 | /**
230 | * 根据方法名,通过反射执行方法,并将结果通过TextView展示出来
231 | */
232 | private void invokeMethodByName(int index) {
233 | if (mClass == null || methods == null || methods.size() == 0) return;
234 | String methodName = methods.get(index);
235 | if (mInvokeMethodDisposable != null && !mInvokeMethodDisposable.isDisposed()) mInvokeMethodDisposable.dispose();
236 | mInvokeMethodDisposable = Observable
237 | .fromArray(mClass.getDeclaredMethods())
238 | .filter(new Predicate() {
239 | @Override
240 | public boolean test(Method method) throws Exception {
241 | return method.getName().equals(methodName);
242 | }
243 | })
244 | .groupBy(new Function() { //根据方法所需参数的个数进行分组
245 | @Override
246 | public Integer apply(Method method) throws Exception {
247 | return method.getParameterTypes().length;
248 | }
249 | })
250 | .doOnSubscribe(new Consumer() {
251 | @Override
252 | public void accept(Disposable disposable) throws Exception {
253 | SystemOut.reset();
254 | }
255 | })
256 | .subscribe(new Consumer>() {
257 | @Override
258 | public void accept(GroupedObservable observables) throws Exception {
259 | switch (observables.getKey()) {
260 | case 0:
261 | observables.subscribe(new Consumer() {
262 | @Override
263 | public void accept(Method method) throws Exception {
264 | SystemOut.println("执行结果为-->\r\n");
265 | method.invoke(mClass.newInstance());
266 | }
267 | });
268 | break;
269 | case 1:
270 | observables.subscribe(new Consumer() {
271 | @Override
272 | public void accept(Method method) throws Exception {
273 | if (method.getParameterTypes()[0] == List.class) {
274 | List params = Arrays.asList("1", "2", "3", "4", "5", "6", "7");
275 | SystemOut.println("传入参数为-->" + params.toString());
276 | SystemOut.println("执行结果为-->\r\n");
277 | method.invoke(mClass.newInstance(), params);
278 | }
279 | }
280 | });
281 | break;
282 | }
283 | }
284 | });
285 | }
286 |
287 | @Override
288 | protected void onDestroy() {
289 | super.onDestroy();
290 | SystemOut.clear();
291 | if (mTitleDisposable != null && !mTitleDisposable.isDisposed()) mTitleDisposable.dispose();
292 | if (mDemoMethodDisposable != null && !mDemoMethodDisposable.isDisposed()) mDemoMethodDisposable.dispose();
293 | if (mInvokeMethodDisposable != null && !mInvokeMethodDisposable.isDisposed()) mInvokeMethodDisposable.dispose();
294 | }
295 | }
296 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/Rxjava2Demo/Rxjava2_2_Observable.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.Rxjava2Demo;
2 |
3 |
4 | import com.edward.javaecho.SystemOut;
5 |
6 | import android.annotation.SuppressLint;
7 |
8 | import java.util.List;
9 |
10 | import io.reactivex.Observable;
11 | import io.reactivex.ObservableEmitter;
12 | import io.reactivex.ObservableOnSubscribe;
13 | import io.reactivex.Observer;
14 | import io.reactivex.annotations.NonNull;
15 | import io.reactivex.disposables.Disposable;
16 | import io.reactivex.functions.Action;
17 | import io.reactivex.functions.Consumer;
18 |
19 | /**
20 | * 功能描述:Rxjava2入门教程二:Observable与Observer响应式编程在Rxjava2中的典型实现
21 | *
22 | * @author (作者) edward(冯丰枫)
23 | * @link http://www.jianshu.com/u/f7176d6d53d2
24 | * 创建时间: 2017/8/19
25 | */
26 | @SuppressLint("CheckResult")
27 | public class Rxjava2_2_Observable {
28 |
29 | public void demo1() {
30 |
31 | Observable observable = Observable.create(new ObservableOnSubscribe() {
32 | @Override
33 | public void subscribe(ObservableEmitter emitter) throws Exception {
34 | emitter.onNext("Hello World");
35 | emitter.onComplete();
36 | }
37 | });
38 |
39 | Observer observer = new Observer() {
40 | @Override
41 | public void onSubscribe(Disposable d) {
42 |
43 | }
44 |
45 | @Override
46 | public void onNext(String s) {
47 | SystemOut.println(s);
48 | }
49 |
50 | @Override
51 | public void onError(Throwable e) {
52 | SystemOut.println(e);
53 | }
54 |
55 | @Override
56 | public void onComplete() {
57 | SystemOut.println("接受完成");
58 | }
59 | };
60 |
61 | observable.subscribe(observer);
62 | }
63 |
64 | public void demo2() {
65 | Observable
66 | .create(new ObservableOnSubscribe() {
67 | @Override
68 | public void subscribe(ObservableEmitter emitter) throws Exception {
69 | emitter.onNext("Hello World");
70 | emitter.onComplete();
71 | }
72 | })
73 | .subscribe(new Observer() {
74 | @Override
75 | public void onSubscribe(Disposable d) {
76 | }
77 |
78 | @Override
79 | public void onNext(String s) {
80 | SystemOut.println(s);
81 | }
82 |
83 | @Override
84 | public void onError(Throwable e) {
85 | SystemOut.println(e);;
86 | }
87 |
88 | @Override
89 | public void onComplete() {
90 | SystemOut.println("接受完成");
91 | }
92 | });
93 | }
94 |
95 |
96 | public void demo3() {
97 | Observable.just("Hello World")
98 | .subscribe(new Consumer() {
99 | @Override
100 | public void accept(@NonNull String s) throws Exception {
101 | SystemOut.println(s);
102 | }
103 | });
104 | }
105 |
106 |
107 | public void demo3_1() {
108 | Observable.just("Hello World").subscribe(SystemOut::println);
109 | }
110 | public void demo4() {
111 | Observable.just("Hello World")
112 | .subscribe(new Consumer() {
113 | @Override
114 | public void accept(@NonNull String s) throws Exception {
115 | SystemOut.println(s);
116 | }
117 | }, new Consumer() {
118 | @Override
119 | public void accept(@NonNull Throwable throwable) throws Exception {
120 | SystemOut.println(throwable);
121 | }
122 | }, new Action() {
123 | @Override
124 | public void run() throws Exception {
125 | SystemOut.println("接受完成");
126 | }
127 | });
128 | }
129 |
130 | public void demo5(final List list) {
131 | Observable.create(new ObservableOnSubscribe() {
132 | @Override
133 | public void subscribe(ObservableEmitter emitter) throws Exception {
134 | try {
135 | for (String str : list) {
136 | emitter.onNext(str);
137 | }
138 | emitter.onComplete();
139 | } catch (Exception e) {
140 | emitter.onError(e);
141 | }
142 | }
143 | }).subscribe(new Observer() {
144 | @Override
145 | public void onSubscribe(Disposable d) {
146 | }
147 |
148 | @Override
149 | public void onNext(String s) {
150 | SystemOut.println(s);
151 | }
152 |
153 | @Override
154 | public void onError(Throwable e) {
155 | SystemOut.println(e);
156 | }
157 |
158 | @Override
159 | public void onComplete() {
160 | SystemOut.println("接受完成");
161 | }
162 | });
163 | }
164 |
165 | public void demo6(final List list) {
166 | Observable
167 | .fromIterable(list)
168 | .subscribe(new Consumer() {
169 | @Override
170 | public void accept(@NonNull String s) throws Exception {
171 | SystemOut.println(s);
172 | }
173 | });
174 | }
175 |
176 | public void demo6_1(final List list) {
177 | Observable.fromIterable(list).subscribe(SystemOut::println);
178 | }
179 |
180 | public void demo7(final List list) {
181 | Disposable disposable1 = Observable.just("Hello World")
182 | .subscribe(new Consumer() {
183 | @Override
184 | public void accept(@NonNull String s) throws Exception {
185 | SystemOut.println(s);
186 | }
187 | });
188 | Disposable disposable2 = Observable
189 | .fromIterable(list)
190 | .subscribe(new Consumer() {
191 | @Override
192 | public void accept(@NonNull String s) throws Exception {
193 | SystemOut.println(s);
194 | }
195 | });
196 | }
197 |
198 | public void demo8() {
199 | Observable.create(new ObservableOnSubscribe() {
200 | @Override
201 | public void subscribe(ObservableEmitter emitter) throws Exception {
202 | for (int i = 0; i < 10; i++) {
203 | SystemOut.println("发送" + i);
204 | emitter.onNext(i);
205 | }
206 | emitter.onComplete();
207 | }
208 | }).subscribe(new Observer() {
209 | private Disposable disposable;
210 |
211 | @Override
212 | public void onSubscribe(Disposable d) {
213 | disposable = d;
214 | }
215 |
216 | @Override
217 | public void onNext(Integer integer) {
218 | SystemOut.println("接收" + integer);
219 | if (integer > 4) disposable.dispose();
220 | }
221 |
222 | @Override
223 | public void onError(Throwable e) {
224 | SystemOut.println(e);
225 | }
226 |
227 | @Override
228 | public void onComplete() {
229 | SystemOut.println("数据接受完成");
230 | }
231 | });
232 | }
233 | }
234 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/Rxjava2Demo/Rxjava2_3_Operators.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.Rxjava2Demo;
2 |
3 | import com.edward.javaecho.SystemOut;
4 |
5 | import android.annotation.SuppressLint;
6 |
7 | import io.reactivex.Observable;
8 | import io.reactivex.annotations.NonNull;
9 | import io.reactivex.functions.BiFunction;
10 | import io.reactivex.functions.Consumer;
11 | import io.reactivex.functions.Function;
12 | import io.reactivex.functions.Predicate;
13 |
14 | /**
15 | * 功能描述:Rxjava2入门教程三:Operators操作符
16 | *
17 | * @author (作者) edward(冯丰枫)
18 | * @link http://www.jianshu.com/u/f7176d6d53d2
19 | * 创建时间: 2017/8/19
20 | */
21 | @SuppressLint("CheckResult")
22 | public class Rxjava2_3_Operators {
23 |
24 | public void demo1_range() {
25 | Observable
26 | .range(0, 5)
27 | .subscribe(new Consumer() {
28 | @Override
29 | public void accept(Integer integer) throws Exception {
30 | SystemOut.println(integer);
31 | }
32 | });
33 | }
34 |
35 | public void demo2_filter() {
36 | Observable
37 | .range(0, 10)
38 | .filter(new Predicate() {
39 | @Override
40 | public boolean test(Integer integer) throws Exception {
41 | return integer % 3 == 0;
42 | }
43 | })
44 | .subscribe(new Consumer() {
45 | @Override
46 | public void accept(Integer integer) throws Exception {
47 | SystemOut.println(integer);
48 | }
49 | });
50 | }
51 |
52 | public void demo3_distinct() {
53 | Observable.just(1, 1, 2, 3, 1, 2, 2, 4, 5)
54 | .distinct()
55 | .subscribe(new Consumer() {
56 | @Override
57 | public void accept(@NonNull Integer integer) throws Exception {
58 | SystemOut.println(integer);
59 | }
60 | });
61 | }
62 |
63 | public void demo4_distinct_filter() {
64 | Observable.just(1, 1, 2, 3, 1, 2, 2, 4, 5)
65 | .distinct()
66 | .filter(new Predicate() {
67 | @Override
68 | public boolean test(@NonNull Integer integer) throws Exception {
69 | return integer % 2 == 0;
70 | }
71 | })
72 | .subscribe(new Consumer() {
73 | @Override
74 | public void accept(@NonNull Integer integer) throws Exception {
75 | SystemOut.println(integer);
76 | }
77 | });
78 | }
79 |
80 | public void demo5_map() {
81 | Observable.range(0, 5)
82 | .map(new Function() {
83 | @Override
84 | public String apply(@NonNull Integer integer) throws Exception {
85 | return integer + "^2 = " + integer * integer;
86 | }
87 | })
88 | .subscribe(new Consumer() {
89 | @Override
90 | public void accept(@NonNull String s) throws Exception {
91 | SystemOut.println(s);
92 | }
93 | });
94 | }
95 |
96 | public void demo6_flatMap() {
97 | Integer nums1[] = new Integer[]{1, 2, 3, 4};
98 | Integer nums2[] = new Integer[]{5, 6};
99 | Integer nums3[] = new Integer[]{7, 8, 9};
100 | Observable.just(nums1, nums2, nums3)
101 | .flatMap(new Function>() {
102 | @Override
103 | public Observable apply(@NonNull Integer[] integers) throws Exception {
104 | return Observable.fromArray(integers);
105 | }
106 | })
107 | .subscribe(new Consumer() {
108 | @Override
109 | public void accept(@NonNull Integer integer) throws Exception {
110 | SystemOut.println(integer);
111 | }
112 | });
113 | }
114 |
115 | public void demo7_mergeWith() {
116 | Integer nums1[] = new Integer[]{5, 6, 7, 8, 9};
117 | Observable.just(1, 2, 3, 4, 5)
118 | .mergeWith(Observable.fromArray(nums1))
119 | .subscribe(new Consumer() {
120 | @Override
121 | public void accept(@NonNull Integer integer) throws Exception {
122 | SystemOut.println(integer);
123 | }
124 | });
125 | }
126 |
127 | public void demo8_concatWith() {
128 | Integer nums1[] = new Integer[]{5, 6, 7, 8, 9};
129 | Observable.just(1, 2, 3, 4, 5)
130 | .concatWith(Observable.fromArray(nums1))
131 | .subscribe(new Consumer() {
132 | @Override
133 | public void accept(@NonNull Integer integer) throws Exception {
134 | SystemOut.println(integer);
135 | }
136 | });
137 | }
138 |
139 | public void demo9_zipWith() {
140 | String names[] = new String[]{"红娃", "橙娃", "黄娃", "绿娃", "青娃", "蓝娃", "紫娃"};
141 | Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
142 | .zipWith(Observable.fromArray(names), new BiFunction() {
143 | @Override
144 | public String apply(@NonNull Integer integer, @NonNull String s) throws Exception {
145 | return integer + s;
146 | }
147 | })
148 | .subscribe(new Consumer() {
149 | @Override
150 | public void accept(@NonNull String s) throws Exception {
151 | SystemOut.println(s);
152 | }
153 | });
154 | }
155 |
156 | public void demo10_link_all_operators() {
157 | Integer nums1[] = new Integer[]{5, 6, 7, 8, 9};
158 | Integer nums2[] = new Integer[]{3, 4, 5, 6};
159 | String names[] = new String[]{"红娃", "橙娃", "黄娃", "绿娃", "青娃", "蓝娃", "紫娃"};
160 | Observable.just(nums1)
161 | .flatMap(new Function>() {
162 | @Override
163 | public Observable apply(@NonNull Integer[] integers) throws Exception {
164 | return Observable.fromArray(integers);
165 | }
166 | })
167 | .mergeWith(Observable.fromArray(nums2))
168 | .concatWith(Observable.just(1, 2))
169 | .distinct()
170 | .filter(new Predicate() {
171 | @Override
172 | public boolean test(@NonNull Integer integer) throws Exception {
173 | return integer < 5;
174 | }
175 | })
176 | .map(new Function() {
177 | @Override
178 | public String apply(@NonNull Integer integer) throws Exception {
179 | return integer + ":";
180 | }
181 | })
182 | .zipWith(Observable.fromArray(names), new BiFunction() {
183 | @Override
184 | public String apply(@NonNull String s, @NonNull String s2) throws Exception {
185 | return s + s2;
186 | }
187 | })
188 | .subscribe(new Consumer() {
189 | @Override
190 | public void accept(@NonNull String s) throws Exception {
191 | SystemOut.println(s);
192 | }
193 | });
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/Rxjava2Demo/Rxjava2_4_Scheduler.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.Rxjava2Demo;
2 |
3 | import com.edward.javaecho.SystemOut;
4 |
5 | import android.annotation.SuppressLint;
6 |
7 | import io.reactivex.Observable;
8 | import io.reactivex.ObservableEmitter;
9 | import io.reactivex.ObservableOnSubscribe;
10 | import io.reactivex.android.schedulers.AndroidSchedulers;
11 | import io.reactivex.annotations.NonNull;
12 | import io.reactivex.functions.Consumer;
13 | import io.reactivex.functions.Function;
14 | import io.reactivex.schedulers.Schedulers;
15 |
16 | /**
17 | * 功能描述:Rxjava2入门教程四:Scheduler线程调度器
18 | *
19 | * @author (作者) edward(冯丰枫)
20 | * @link http://www.jianshu.com/u/f7176d6d53d2
21 | * 创建时间: 2017/8/19
22 | */
23 | @SuppressLint("CheckResult")
24 | public class Rxjava2_4_Scheduler {
25 |
26 | public void schedulerDemo1() {
27 | Observable
28 | .create(new ObservableOnSubscribe() {
29 | @Override
30 | public void subscribe(ObservableEmitter e) throws Exception {
31 | for (int i = 0; i < 5; i++) {
32 | SystemOut.println("发射线程:" + Thread.currentThread().getName() + "---->" + "发射:" + i);
33 | Thread.sleep(1000);
34 | e.onNext(i);
35 | }
36 | e.onComplete();
37 | }
38 | })
39 | .subscribeOn(Schedulers.io()) //设置可观察对象在Schedulers.io()的线程中发射数据
40 | .observeOn(AndroidSchedulers.mainThread())//设置观察者在AndroidSchedulers.mainThread()的线程中处理数据
41 | .subscribe(new Consumer() {
42 | @Override
43 | public void accept(@NonNull Integer i) throws Exception {
44 | SystemOut.println("接收线程:" + Thread.currentThread().getName() + "---->" + "接收:" + i);
45 | }
46 | });
47 | }
48 |
49 | public void schedulerDemo2() {
50 | Observable
51 | .create(new ObservableOnSubscribe() {
52 | @Override
53 | public void subscribe(ObservableEmitter e) throws Exception {
54 | for (int i = 0; i < 5; i++) {
55 | SystemOut.println("发射线程:" + Thread.currentThread().getName() + "---->" + "发射:" + i);
56 | Thread.sleep(1000);
57 | e.onNext(i);
58 | }
59 | e.onComplete();
60 | }
61 | })
62 | .subscribeOn(Schedulers.io())//设置可观察对象在Schedulers.io()的线程中发射数据
63 | .map(new Function() {
64 | @Override
65 | public Integer apply(@NonNull Integer i) throws Exception {
66 | SystemOut.println("处理线程:" + Thread.currentThread().getName() + "---->" + "处理:" + i);
67 | return i;
68 | }
69 | })
70 | .subscribeOn(Schedulers.newThread())//指定map操作符在Schedulers.newThread()的线程中处理数据
71 | .observeOn(AndroidSchedulers.mainThread())//设置观察者在AndroidSchedulers.mainThread()的线程中处理数据
72 | .subscribe(new Consumer() {
73 | @Override
74 | public void accept(@NonNull Integer i) throws Exception {
75 | SystemOut.println("接收线程:" + Thread.currentThread().getName() + "---->" + "接收:" + i);
76 | }
77 | });
78 | }
79 |
80 | public void schedulerDemo3() {
81 | Observable
82 | .create(new ObservableOnSubscribe() {
83 | @Override
84 | public void subscribe(ObservableEmitter e) throws Exception {
85 | for (int i = 0; i < 2; i++) {
86 | SystemOut.println("发射线程:" + Thread.currentThread().getName() + "---->" + "发射:" + i);
87 | Thread.sleep(1000);
88 | e.onNext(i);
89 | }
90 | e.onComplete();
91 | }
92 | })
93 | .subscribeOn(Schedulers.io())//设置可观察对象在Schedulers.io()的线程中发射数据
94 | .observeOn(Schedulers.newThread())//指定map操作符在Schedulers.newThread()的线程中处理数据
95 | .map(new Function() {
96 | @Override
97 | public Integer apply(@NonNull Integer i) throws Exception {
98 | SystemOut.println("处理线程:" + Thread.currentThread().getName() + "---->" + "处理:" + i);
99 | return i;
100 | }
101 | })
102 | .observeOn(AndroidSchedulers.mainThread())//设置观察者在AndroidSchedulers.mainThread()的线程中处理数据
103 | .subscribe(new Consumer() {
104 | @Override
105 | public void accept(@NonNull Integer i) throws Exception {
106 | SystemOut.println("接收线程:" + Thread.currentThread().getName() + "---->" + "接收:" + i);
107 | }
108 | });
109 | }
110 |
111 | public void schedulerDemo4() {
112 | Observable
113 | .create(new ObservableOnSubscribe() {
114 | @Override
115 | public void subscribe(ObservableEmitter e) throws Exception {
116 | for (int i = 0; i < 5; i++) {
117 | SystemOut.println("发射线程:" + Thread.currentThread().getName() + "---->" + "发射:" + i);
118 | Thread.sleep(1000);
119 | e.onNext(i);
120 | }
121 | e.onComplete();
122 | }
123 | })
124 | .subscribeOn(Schedulers.io())//设置可观察对象在Schedulers.io()的线程中发射数据
125 | .observeOn(Schedulers.trampoline())//设置观察者在当前线程中j接收数据
126 | .subscribe(new Consumer() {
127 | @Override
128 | public void accept(@NonNull Integer i) throws Exception {
129 | Thread.sleep(2000);//休息2s后再处理数据
130 | SystemOut.println("接收线程:" + Thread.currentThread().getName() + "---->" + "接收:" + i);
131 | }
132 | });
133 | }
134 |
135 | public void schedulerDemo5() {
136 | Observable
137 | .create(new ObservableOnSubscribe() {
138 | @Override
139 | public void subscribe(ObservableEmitter e) throws Exception {
140 | for (int i = 0; i < 3; i++) {
141 | SystemOut.println("发射线程:" + Thread.currentThread().getName() + "---->" + "发射:" + i);
142 | Thread.sleep(1000);
143 | e.onNext(i);
144 | }
145 | e.onComplete();
146 | }
147 | })
148 | .subscribeOn(Schedulers.single())//设置可观察对象在Schedulers.single()的线程中发射数据
149 | .observeOn(Schedulers.single())//指定map操作符在Schedulers.single()的线程中处理数据
150 | .map(new Function() {
151 | @Override
152 | public Integer apply(@NonNull Integer i) throws Exception {
153 | SystemOut.println("处理线程:" + Thread.currentThread().getName() + "---->" + "处理:" + i);
154 | return i;
155 | }
156 | })
157 | .observeOn(Schedulers.single())//设置观察者在Schedulers.single()的线程中j接收数据
158 | .subscribe(new Consumer() {
159 | @Override
160 | public void accept(@NonNull Integer i) throws Exception {
161 | SystemOut.println("接收线程:" + Thread.currentThread().getName() + "---->" + "接收:" + i);
162 | }
163 | });
164 | }
165 |
166 | }
167 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/Rxjava2Demo/Rxjava2_5_Flowable.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.Rxjava2Demo;
2 |
3 | import com.edward.javaecho.SystemOut;
4 |
5 | import org.reactivestreams.Subscriber;
6 | import org.reactivestreams.Subscription;
7 |
8 | import android.annotation.SuppressLint;
9 |
10 | import io.reactivex.BackpressureStrategy;
11 | import io.reactivex.Flowable;
12 | import io.reactivex.FlowableEmitter;
13 | import io.reactivex.FlowableOnSubscribe;
14 | import io.reactivex.Observable;
15 | import io.reactivex.ObservableEmitter;
16 | import io.reactivex.ObservableOnSubscribe;
17 | import io.reactivex.Observer;
18 | import io.reactivex.annotations.NonNull;
19 | import io.reactivex.disposables.Disposable;
20 | import io.reactivex.functions.Consumer;
21 | import io.reactivex.schedulers.Schedulers;
22 |
23 | /**
24 | * 功能描述:Rxjava2入门教程五:Flowable背压支持——几乎可以说是对Flowable最全面而详细的讲解
25 | *
26 | * @author (作者) edward(冯丰枫)
27 | * @link http://www.jianshu.com/u/f7176d6d53d2
28 | * 创建时间: 2017/8/19
29 | */
30 | @SuppressLint("CheckResult")
31 | public class Rxjava2_5_Flowable {
32 |
33 | public void demo0(){
34 | SystemOut.println("本节部分Demo会导致app内存溢出或闪退,需要结合控制台查看运行结果");
35 | }
36 |
37 | public void demo1() {
38 | Observable
39 | .create(new ObservableOnSubscribe() {
40 | @Override
41 | public void subscribe(ObservableEmitter e) throws Exception {
42 | int i = 0;
43 | while (true) {
44 | i++;
45 | e.onNext(i);
46 | }
47 | }
48 | })
49 | .subscribeOn(Schedulers.newThread())
50 | .observeOn(Schedulers.newThread())
51 | .subscribe(new Consumer() {
52 | @Override
53 | public void accept(Integer integer) throws Exception {
54 | Thread.sleep(5000);
55 | SystemOut.println(integer);
56 | }
57 | });
58 | }
59 |
60 | public void demo2() {
61 | Flowable
62 | .create(new FlowableOnSubscribe() {
63 | @Override
64 | public void subscribe(FlowableEmitter e) throws Exception {
65 | SystemOut.println("发射----> 1");
66 | e.onNext(1);
67 | SystemOut.println("发射----> 2");
68 | e.onNext(2);
69 | SystemOut.println("发射----> 3");
70 | e.onNext(3);
71 | SystemOut.println("发射----> 完成");
72 | e.onComplete();
73 | }
74 | }, BackpressureStrategy.BUFFER) //create方法中多了一个BackpressureStrategy类型的参数
75 | .subscribeOn(Schedulers.newThread())//为上下游分别指定各自的线程
76 | .observeOn(Schedulers.newThread())
77 | .subscribe(new Subscriber() {
78 | @Override
79 | public void onSubscribe(Subscription s) { //onSubscribe回调的参数不是Disposable而是Subscription
80 | s.request(Long.MAX_VALUE); //注意此处,暂时先这么设置
81 |
82 | }
83 |
84 | @Override
85 | public void onNext(Integer integer) {
86 | SystemOut.println("接收----> " + integer);
87 | }
88 |
89 | @Override
90 | public void onError(Throwable t) {
91 | }
92 |
93 | @Override
94 | public void onComplete() {
95 | SystemOut.println("接收----> 完成");
96 | }
97 | });
98 | }
99 |
100 | public void demo3() {
101 | Flowable
102 | .create(new FlowableOnSubscribe() {
103 | @Override
104 | public void subscribe(FlowableEmitter e) throws Exception {
105 | for (int i = 1; i <= 129; i++) {
106 | e.onNext(i);
107 | }
108 | e.onComplete();
109 | }
110 | }, BackpressureStrategy.ERROR)
111 | .subscribeOn(Schedulers.newThread())
112 | .observeOn(Schedulers.newThread())
113 | .subscribe(new Subscriber() {
114 | @Override
115 | public void onSubscribe(Subscription s) {
116 | s.request(Long.MAX_VALUE); //注意此处,暂时先这么设置
117 | }
118 |
119 | @Override
120 | public void onNext(Integer integer) {
121 | try {
122 | Thread.sleep(10000);
123 | } catch (InterruptedException ignore) {
124 | }
125 | SystemOut.println(integer);
126 | }
127 |
128 | @Override
129 | public void onError(Throwable t) {
130 | SystemOut.println(t);
131 | }
132 |
133 | @Override
134 | public void onComplete() {
135 | SystemOut.println("接收----> 完成");
136 | }
137 | });
138 | }
139 |
140 | public void demo4() {
141 | Flowable
142 | .create(new FlowableOnSubscribe() {
143 | @Override
144 | public void subscribe(FlowableEmitter e) throws Exception {
145 | String threadName = Thread.currentThread().getName();
146 | SystemOut.println(threadName + "开始发射数据" + System.currentTimeMillis());
147 | for (int i = 1; i <= 500; i++) {
148 | SystemOut.println(threadName + "发射---->" + i);
149 | e.onNext(i);
150 | try {
151 | Thread.sleep(100);//每隔100毫秒发射一次数据
152 | } catch (Exception ignore) {
153 | }
154 | }
155 | SystemOut.println(threadName + "发射数据结束" + System.currentTimeMillis());
156 | e.onComplete();
157 | }
158 | }, BackpressureStrategy.DROP)
159 | .subscribeOn(Schedulers.newThread())
160 | .observeOn(Schedulers.newThread())
161 | .subscribe(new Subscriber() {
162 | @Override
163 | public void onSubscribe(Subscription s) {
164 | s.request(Long.MAX_VALUE); //注意此处,暂时先这么设置
165 | }
166 |
167 | @Override
168 | public void onNext(Integer integer) {
169 | try {
170 | Thread.sleep(300);//每隔300毫秒接收一次数据
171 | } catch (InterruptedException ignore) {
172 | }
173 | SystemOut.println(Thread.currentThread().getName() + "接收---------->" + integer);
174 | }
175 |
176 | @Override
177 | public void onError(Throwable t) {
178 | SystemOut.println(t);
179 | }
180 |
181 | @Override
182 | public void onComplete() {
183 | SystemOut.println(Thread.currentThread().getName() + "接收----> 完成");
184 | }
185 | });
186 | }
187 |
188 | public void demo5() {
189 | Flowable
190 | .create(new FlowableOnSubscribe() {
191 | @Override
192 | public void subscribe(FlowableEmitter e) throws Exception {
193 | String threadName = Thread.currentThread().getName();
194 | SystemOut.println(threadName + "开始发射数据" + System.currentTimeMillis());
195 | for (int i = 1; i <= 500; i++) {
196 | SystemOut.println(threadName + "发射---->" + i);
197 | e.onNext(i);
198 | try {
199 | Thread.sleep(100);
200 | } catch (Exception ignore) {
201 | }
202 | }
203 | SystemOut.println(threadName + "发射数据结束" + System.currentTimeMillis());
204 | e.onComplete();
205 |
206 | }
207 | }, BackpressureStrategy.LATEST)
208 | .subscribeOn(Schedulers.newThread())
209 | .observeOn(Schedulers.newThread())
210 | .subscribe(new Subscriber() {
211 | @Override
212 | public void onSubscribe(Subscription s) {
213 | s.request(Long.MAX_VALUE); //注意此处,暂时先这么设置
214 | }
215 |
216 | @Override
217 | public void onNext(Integer integer) {
218 | try {
219 | Thread.sleep(300);
220 | } catch (InterruptedException ignore) {
221 | }
222 | SystemOut.println(Thread.currentThread().getName() + "接收---------->" + integer);
223 | }
224 |
225 | @Override
226 | public void onError(Throwable t) {
227 | SystemOut.println(t);
228 | }
229 |
230 | @Override
231 | public void onComplete() {
232 | SystemOut.println(Thread.currentThread().getName() + "接收----> 完成");
233 | }
234 | });
235 | }
236 |
237 | public void demo6() {
238 | Flowable
239 | .create(new FlowableOnSubscribe() {
240 | @Override
241 | public void subscribe(FlowableEmitter e) throws Exception {
242 | int i = 0;
243 | while (true) {
244 | i++;
245 | e.onNext(i);
246 | }
247 | }
248 | }, BackpressureStrategy.BUFFER)
249 | .subscribeOn(Schedulers.newThread())
250 | .observeOn(Schedulers.newThread())
251 | .subscribe(new Consumer() {
252 | @Override
253 | public void accept(@NonNull Integer integer) throws Exception {
254 | Thread.sleep(5000);
255 | SystemOut.println(integer);
256 | }
257 | });
258 | }
259 |
260 | public void demo7() {
261 | Flowable
262 | .create(new FlowableOnSubscribe() {
263 | @Override
264 | public void subscribe(FlowableEmitter e) throws Exception {
265 | for (int i = 0; i < 500; i++) {
266 | e.onNext(i);
267 | }
268 | e.onComplete();
269 | }
270 | }, BackpressureStrategy.DROP)
271 | .observeOn(Schedulers.newThread())
272 | .subscribeOn(Schedulers.newThread())
273 | .subscribe(new Consumer() {
274 | @Override
275 | public void accept(@NonNull Integer integer) throws Exception {
276 | SystemOut.println(integer);
277 | }
278 | });
279 | }
280 |
281 | public void demo8() {
282 | Flowable.range(0, 500)
283 | .onBackpressureDrop()
284 | .subscribeOn(Schedulers.newThread())
285 | .observeOn(Schedulers.newThread())
286 | .subscribe(new Consumer() {
287 | @Override
288 | public void accept(@NonNull Integer integer) throws Exception {
289 | SystemOut.println(integer);
290 | }
291 | });
292 | }
293 |
294 | public void demo9() {
295 | Flowable
296 | .create(new FlowableOnSubscribe() {
297 | @Override
298 | public void subscribe(FlowableEmitter e) throws Exception {
299 | SystemOut.println("发射----> 1");
300 | e.onNext(1);
301 | SystemOut.println("发射----> 2");
302 | e.onNext(2);
303 | SystemOut.println("发射----> 3");
304 | e.onNext(3);
305 | SystemOut.println("发射----> 完成");
306 | e.onComplete();
307 | }
308 | }, BackpressureStrategy.BUFFER) //create方法中多了一个BackpressureStrategy类型的参数
309 | .subscribeOn(Schedulers.newThread())//为上下游分别指定各自的线程
310 | .observeOn(Schedulers.newThread())
311 | .subscribe(new Subscriber() {
312 | @Override
313 | public void onSubscribe(Subscription s) {
314 | //去掉代码s.request(Long.MAX_VALUE);
315 | }
316 |
317 | @Override
318 | public void onNext(Integer integer) {
319 | SystemOut.println("接收----> " + integer);
320 | }
321 |
322 | @Override
323 | public void onError(Throwable t) {
324 | }
325 |
326 | @Override
327 | public void onComplete() {
328 | SystemOut.println("接收----> 完成");
329 | }
330 | });
331 | }
332 |
333 | public void demo10() {
334 | Flowable
335 | .create(new FlowableOnSubscribe() {
336 | @Override
337 | public void subscribe(FlowableEmitter e) throws Exception {
338 | SystemOut.println("发射----> 1");
339 | e.onNext(1);
340 | SystemOut.println("发射----> 2");
341 | e.onNext(2);
342 | SystemOut.println("发射----> 3");
343 | e.onNext(3);
344 | SystemOut.println("发射----> 完成");
345 | e.onComplete();
346 | }
347 | }, BackpressureStrategy.BUFFER) //create方法中多了一个BackpressureStrategy类型的参数
348 | .subscribeOn(Schedulers.newThread())//为上下游分别指定各自的线程
349 | .observeOn(Schedulers.newThread())
350 | .subscribe(new Subscriber() {
351 | @Override
352 | public void onSubscribe(Subscription s) {
353 | s.request(2);//设置Subscriber的消费能力为2
354 | }
355 |
356 | @Override
357 | public void onNext(Integer integer) {
358 | SystemOut.println("接收----> " + integer);
359 | }
360 |
361 | @Override
362 | public void onError(Throwable t) {
363 | }
364 |
365 | @Override
366 | public void onComplete() {
367 | SystemOut.println("接收----> 完成");
368 | }
369 | });
370 | }
371 |
372 | public void demo11() {
373 | Flowable
374 | .create(new FlowableOnSubscribe() {
375 | @Override
376 | public void subscribe(FlowableEmitter e) throws Exception {
377 | String threadName = Thread.currentThread().getName();
378 | for (int i = 1; i <= 10; i++) {
379 | SystemOut.println(threadName + "发射---->" + i);
380 | e.onNext(i);
381 | }
382 | SystemOut.println(threadName + "发射数据结束" + System.currentTimeMillis());
383 | e.onComplete();
384 | }
385 | }, BackpressureStrategy.BUFFER)
386 | .subscribeOn(Schedulers.newThread())
387 | .observeOn(Schedulers.newThread())
388 | .subscribe(new Subscriber() {
389 | @Override
390 | public void onSubscribe(Subscription s) {
391 | s.request(3);//调用两次request
392 | s.request(4);
393 | }
394 |
395 | @Override
396 | public void onNext(Integer integer) {
397 | SystemOut.println(Thread.currentThread().getName() + "接收---------->" + integer);
398 | }
399 |
400 | @Override
401 | public void onError(Throwable t) {
402 | SystemOut.println(t);
403 | }
404 |
405 | @Override
406 | public void onComplete() {
407 | SystemOut.println(Thread.currentThread().getName() + "接收----> 完成");
408 | }
409 | });
410 | }
411 |
412 | public void demo12() {
413 | Flowable
414 | .create(new FlowableOnSubscribe() {
415 | @Override
416 | public void subscribe(FlowableEmitter e) throws Exception {
417 | for (int i = 1; i < 130; i++) {
418 | SystemOut.println("发射---->" + i);
419 | e.onNext(i);
420 | }
421 | e.onComplete();
422 | }
423 | }, BackpressureStrategy.ERROR)
424 | .subscribeOn(Schedulers.newThread())
425 | .observeOn(Schedulers.newThread())
426 | .subscribe(new Subscriber() {
427 | @Override
428 | public void onSubscribe(Subscription s) {
429 | s.request(1);
430 | }
431 |
432 | @Override
433 | public void onNext(Integer integer) {
434 | SystemOut.println("接收------>" + integer);
435 | }
436 |
437 | @Override
438 | public void onError(Throwable t) {
439 | SystemOut.println(t);
440 | }
441 |
442 | @Override
443 | public void onComplete() {
444 | SystemOut.println("接收------>完成");
445 | }
446 | });
447 | }
448 |
449 | public void demo13() {
450 | Flowable
451 | .create(new FlowableOnSubscribe() {
452 | @Override
453 | public void subscribe(FlowableEmitter e) throws Exception {
454 | String threadName = Thread.currentThread().getName();
455 | for (int i = 1; i <= 5; i++) {
456 | SystemOut.println("当前未完成的请求数量-->" + e.requested());
457 | SystemOut.println(threadName + "发射---->" + i);
458 | e.onNext(i);
459 | }
460 | SystemOut.println(threadName + "发射数据结束" + System.currentTimeMillis());
461 | e.onComplete();
462 | }
463 | }, BackpressureStrategy.BUFFER)//上下游运行在同一线程中
464 | .subscribe(new Subscriber() {
465 | @Override
466 | public void onSubscribe(Subscription s) {
467 | s.request(3);
468 | }
469 |
470 | @Override
471 | public void onNext(Integer integer) {
472 | SystemOut.println(Thread.currentThread().getName() + "接收---------->" + integer);
473 | }
474 |
475 | @Override
476 | public void onError(Throwable t) {
477 | SystemOut.println(t);
478 | }
479 |
480 | @Override
481 | public void onComplete() {
482 | SystemOut.println(Thread.currentThread().getName() + "接收----> 完成");
483 | }
484 | });
485 | }
486 |
487 | public void demo14() {
488 | Flowable
489 | .create(new FlowableOnSubscribe() {
490 | @Override
491 | public void subscribe(FlowableEmitter e) throws Exception {
492 | String threadName = Thread.currentThread().getName();
493 | for (int i = 1; i <= 5; i++) {
494 | SystemOut.println("当前未完成的请求数量-->" + e.requested());
495 | SystemOut.println(threadName + "发射---->" + i);
496 | e.onNext(i);
497 | }
498 | SystemOut.println(threadName + "发射数据结束" + System.currentTimeMillis());
499 | e.onComplete();
500 | }
501 | }, BackpressureStrategy.BUFFER)
502 | .subscribeOn(Schedulers.newThread())//添加两行代码,为上下游分配独立的线程
503 | .observeOn(Schedulers.newThread())
504 | .subscribe(new Subscriber() {
505 | @Override
506 | public void onSubscribe(Subscription s) {
507 | s.request(3);
508 | }
509 |
510 | @Override
511 | public void onNext(Integer integer) {
512 | SystemOut.println(Thread.currentThread().getName() + "接收---------->" + integer);
513 | }
514 |
515 | @Override
516 | public void onError(Throwable t) {
517 | SystemOut.println(t);
518 | }
519 |
520 | @Override
521 | public void onComplete() {
522 | SystemOut.println(Thread.currentThread().getName() + "接收----> 完成");
523 | }
524 | });
525 | }
526 |
527 | public void demo15() {
528 | Flowable
529 | .create(new FlowableOnSubscribe() {
530 | @Override
531 | public void subscribe(FlowableEmitter e) throws Exception {
532 | String threadName = Thread.currentThread().getName();
533 | for (int i = 1; i <= 5; i++) {
534 | SystemOut.println("当前未完成的请求数量-->" + e.requested());
535 | SystemOut.println(threadName + "发射---->" + i);
536 | e.onNext(i);
537 | }
538 | SystemOut.println(threadName + "发射数据结束" + System.currentTimeMillis());
539 | e.onComplete();
540 | }
541 | }, BackpressureStrategy.BUFFER)
542 | .subscribeOn(Schedulers.newThread())//添加两行代码,为上下游分配独立的线程
543 | .observeOn(Schedulers.newThread())
544 | .subscribe(new Subscriber() {
545 | @Override
546 | public void onSubscribe(Subscription s) {
547 | s.request(500);
548 | }
549 |
550 | @Override
551 | public void onNext(Integer integer) {
552 | SystemOut.println(Thread.currentThread().getName() + "接收---------->" + integer);
553 | }
554 |
555 | @Override
556 | public void onError(Throwable t) {
557 | SystemOut.println(t);
558 | }
559 |
560 | @Override
561 | public void onComplete() {
562 | SystemOut.println(Thread.currentThread().getName() + "接收----> 完成");
563 | }
564 | });
565 | }
566 |
567 | public void demo16() {
568 | Flowable
569 | .create(new FlowableOnSubscribe() {
570 | @Override
571 | public void subscribe(FlowableEmitter e) throws Exception {
572 | String threadName = Thread.currentThread().getName();
573 | for (int i = 1; i <= 150; i++) {
574 | SystemOut.println("当前未完成的请求数量-->" + e.requested());
575 | SystemOut.println(threadName + "发射---->" + i);
576 | e.onNext(i);
577 | }
578 | SystemOut.println(threadName + "发射数据结束" + System.currentTimeMillis());
579 | e.onComplete();
580 | }
581 | }, BackpressureStrategy.BUFFER)
582 | .subscribeOn(Schedulers.newThread())
583 | .observeOn(Schedulers.newThread())
584 | .subscribe(new Subscriber() {
585 | @Override
586 | public void onSubscribe(Subscription s) {
587 | s.request(150);
588 | }
589 |
590 | @Override
591 | public void onNext(Integer integer) {
592 | SystemOut.println(Thread.currentThread().getName() + "接收---------->" + integer);
593 | }
594 |
595 | @Override
596 | public void onError(Throwable t) {
597 | SystemOut.println(t);
598 | }
599 |
600 | @Override
601 | public void onComplete() {
602 | SystemOut.println(Thread.currentThread().getName() + "接收----> 完成");
603 | }
604 | });
605 | }
606 |
607 | public void demo17() {
608 | Observable
609 | .create(new ObservableOnSubscribe() {
610 | @Override
611 | public void subscribe(ObservableEmitter e) throws Exception {
612 | int i = 0;
613 | while (true) {
614 | i++;
615 | SystemOut.println("发射---->" + i);
616 | e.onNext(i);
617 | }
618 | }
619 | })
620 | .subscribeOn(Schedulers.newThread())
621 | .observeOn(Schedulers.newThread())
622 | .subscribe(new Observer() {
623 | @Override
624 | public void onSubscribe(Disposable d) {
625 | }
626 |
627 | @Override
628 | public void onNext(Integer integer) {
629 | try {
630 | Thread.sleep(50);
631 | SystemOut.println("接收------>" + integer);
632 | } catch (InterruptedException ignore) {
633 | }
634 | }
635 |
636 | @Override
637 | public void onError(Throwable e) {
638 | SystemOut.println(e);
639 | }
640 |
641 | @Override
642 | public void onComplete() {
643 | SystemOut.println("接收------>完成");
644 | }
645 | });
646 | }
647 |
648 | public void demo18() {
649 | Flowable
650 | .create(new FlowableOnSubscribe() {
651 | @Override
652 | public void subscribe(FlowableEmitter e) throws Exception {
653 | int i = 0;
654 | while (true) {
655 | if (e.requested() == 0) continue;//此处添加代码,让flowable按需发送数据
656 | SystemOut.println("发射---->" + i);
657 | i++;
658 | e.onNext(i);
659 | }
660 | }
661 | }, BackpressureStrategy.MISSING)
662 | .subscribeOn(Schedulers.newThread())
663 | .observeOn(Schedulers.newThread())
664 | .subscribe(new Subscriber() {
665 | private Subscription mSubscription;
666 |
667 | @Override
668 | public void onSubscribe(Subscription s) {
669 | s.request(1); //设置初始请求数据量为1
670 | mSubscription = s;
671 | }
672 |
673 | @Override
674 | public void onNext(Integer integer) {
675 | try {
676 | Thread.sleep(50);
677 | SystemOut.println("接收------>" + integer);
678 | mSubscription.request(1);//每接收到一条数据增加一条请求量
679 | } catch (InterruptedException ignore) {
680 | }
681 | }
682 |
683 | @Override
684 | public void onError(Throwable t) {
685 | }
686 |
687 | @Override
688 | public void onComplete() {
689 | }
690 | });
691 | }
692 |
693 | }
694 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/Rxjava2Demo/Rxjava2_6_Single_Completable_Maybe.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.Rxjava2Demo;
2 |
3 | import com.edward.javaecho.SystemOut;
4 |
5 | import io.reactivex.Completable;
6 | import io.reactivex.CompletableEmitter;
7 | import io.reactivex.CompletableObserver;
8 | import io.reactivex.CompletableOnSubscribe;
9 | import io.reactivex.Maybe;
10 | import io.reactivex.MaybeEmitter;
11 | import io.reactivex.MaybeObserver;
12 | import io.reactivex.MaybeOnSubscribe;
13 | import io.reactivex.Single;
14 | import io.reactivex.SingleEmitter;
15 | import io.reactivex.SingleObserver;
16 | import io.reactivex.SingleOnSubscribe;
17 | import io.reactivex.disposables.Disposable;
18 |
19 | /**
20 | * 功能描述:Rxjava2入门教程六:Single、Completable、Maybe——简化版的Observable
21 | *
22 | * @author (作者) edward(冯丰枫)
23 | * @link http://www.jianshu.com/u/f7176d6d53d2
24 | * 创建时间: 2017/9/3
25 | */
26 | public class Rxjava2_6_Single_Completable_Maybe {
27 |
28 | public void singleDemo1() {
29 | Single
30 | .create(new SingleOnSubscribe() {
31 | @Override
32 | public void subscribe(SingleEmitter e) throws Exception {
33 | e.onSuccess(0);
34 | }
35 | })
36 | .subscribe(new SingleObserver() {
37 | @Override
38 | public void onSubscribe(Disposable d) {
39 |
40 | }
41 |
42 | @Override
43 | public void onSuccess(Integer integer) {
44 | SystemOut.println(integer);
45 | }
46 |
47 | @Override
48 | public void onError(Throwable e) {
49 | SystemOut.println(e);
50 | }
51 | });
52 | }
53 |
54 | public void singleDemo2() {
55 | Single
56 | .create(new SingleOnSubscribe() {
57 | @Override
58 | public void subscribe(SingleEmitter e) throws Exception {
59 | e.onError(new Exception("测试异常"));
60 | }
61 | })
62 | .subscribe(new SingleObserver() {
63 | @Override
64 | public void onSubscribe(Disposable d) {
65 |
66 | }
67 |
68 | @Override
69 | public void onSuccess(Integer integer) {
70 | SystemOut.println(integer);
71 | }
72 |
73 | @Override
74 | public void onError(Throwable e) {
75 | SystemOut.println(e);
76 | }
77 | });
78 | }
79 |
80 |
81 | public void completableDemo1() {
82 | Completable
83 | .create(new CompletableOnSubscribe() {
84 | @Override
85 | public void subscribe(CompletableEmitter e) throws Exception {
86 | e.onComplete();
87 | }
88 | })
89 | .subscribe(new CompletableObserver() {
90 | @Override
91 | public void onSubscribe(Disposable d) {
92 |
93 | }
94 |
95 | @Override
96 | public void onComplete() {
97 | SystemOut.println("执行完成");
98 | }
99 |
100 | @Override
101 | public void onError(Throwable e) {
102 | SystemOut.println(e);
103 | }
104 | });
105 | }
106 |
107 | public void completableDemo2() {
108 | Completable
109 | .create(new CompletableOnSubscribe() {
110 | @Override
111 | public void subscribe(CompletableEmitter e) throws Exception {
112 | e.onError(new Exception("测试异常"));
113 | }
114 | })
115 | .subscribe(new CompletableObserver() {
116 | @Override
117 | public void onSubscribe(Disposable d) {
118 |
119 | }
120 |
121 | @Override
122 | public void onComplete() {
123 | SystemOut.println("执行完成");
124 | }
125 |
126 | @Override
127 | public void onError(Throwable e) {
128 | SystemOut.println(e);
129 | }
130 | });
131 | }
132 |
133 | public void maybeDemo1() {
134 | Maybe
135 | .create(new MaybeOnSubscribe() {
136 | @Override
137 | public void subscribe(MaybeEmitter e) throws Exception {
138 | e.onSuccess(1);
139 | e.onComplete();
140 | }
141 | })
142 | .subscribe(new MaybeObserver() {
143 | @Override
144 | public void onSubscribe(Disposable d) {
145 |
146 | }
147 |
148 | @Override
149 | public void onSuccess(Integer integer) {
150 | SystemOut.println(integer);
151 | }
152 |
153 | @Override
154 | public void onError(Throwable e) {
155 | SystemOut.println(e);
156 | }
157 |
158 | @Override
159 | public void onComplete() {
160 | SystemOut.println("执行完成");
161 | }
162 | });
163 | }
164 |
165 | public void maybeDemo2() {
166 | Maybe
167 | .create(new MaybeOnSubscribe() {
168 | @Override
169 | public void subscribe(MaybeEmitter e) throws Exception {
170 | e.onSuccess(1);
171 | e.onError(new Exception("测试异常"));
172 | }
173 | })
174 | .subscribe(new MaybeObserver() {
175 | @Override
176 | public void onSubscribe(Disposable d) {
177 |
178 | }
179 |
180 | @Override
181 | public void onSuccess(Integer integer) {
182 | SystemOut.println(integer);
183 | }
184 |
185 | @Override
186 | public void onError(Throwable e) {
187 | SystemOut.println(e);
188 | }
189 |
190 | @Override
191 | public void onComplete() {
192 | SystemOut.println("执行完成");
193 | }
194 | });
195 | }
196 |
197 | }
198 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/Rxjava2Demo/Rxjava2_8_Custom_Operators.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.Rxjava2Demo;
2 |
3 | import com.edward.javaecho.SystemOut;
4 |
5 | import java.util.concurrent.Callable;
6 |
7 | import io.reactivex.Observable;
8 | import io.reactivex.ObservableOperator;
9 | import io.reactivex.ObservableSource;
10 | import io.reactivex.ObservableTransformer;
11 | import io.reactivex.Observer;
12 | import io.reactivex.Single;
13 | import io.reactivex.SingleObserver;
14 | import io.reactivex.SingleOperator;
15 | import io.reactivex.android.schedulers.AndroidSchedulers;
16 | import io.reactivex.disposables.Disposable;
17 | import io.reactivex.functions.Function;
18 | import io.reactivex.schedulers.Schedulers;
19 |
20 | /**
21 | * 功能描述:Rxjava2入门教程八:自定义操作符
22 | *
23 | * @author (作者) edward(冯丰枫)
24 | * @link http://www.jianshu.com/u/f7176d6d53d2
25 | * 创建时间: 2017/9/3
26 | */
27 | public class Rxjava2_8_Custom_Operators {
28 | private Disposable mDisposable;
29 |
30 | public void demo1() {
31 | Observable
32 | .just(1, 2, 3, 4)
33 | .lift(new SQOperator())
34 | .subscribe(new Observer() {
35 | @Override
36 | public void onSubscribe(Disposable d) {
37 |
38 | }
39 |
40 | @Override
41 | public void onNext(Integer integer) {
42 | SystemOut.println(integer);
43 | }
44 |
45 | @Override
46 | public void onError(Throwable e) {
47 | SystemOut.println(e);
48 | }
49 |
50 | @Override
51 | public void onComplete() {
52 | SystemOut.println("完成");
53 | }
54 | });
55 | }
56 |
57 | public void demo2() {
58 | Observable.just("Hello", "Rxjava")
59 | .lift(new ToCharOperator())
60 | .map(new Function() {
61 | @Override
62 | public String apply(Character character) throws Exception {
63 | SystemOut.println(character);
64 | return character.toString();
65 | }
66 | })
67 | .subscribe(new Observer() {
68 | @Override
69 | public void onSubscribe(Disposable d) {
70 |
71 | }
72 |
73 | @Override
74 | public void onNext(String s) {
75 | SystemOut.println(s);
76 | }
77 |
78 | @Override
79 | public void onError(Throwable e) {
80 | SystemOut.println(e);
81 | }
82 |
83 | @Override
84 | public void onComplete() {
85 | SystemOut.println("完成");
86 | }
87 | });
88 | }
89 |
90 | public void demo3() {
91 | Observable.just(1, 2, 3, 4)
92 | .compose(new SQTransFormer())
93 | .subscribe(new Observer() {
94 | @Override
95 | public void onSubscribe(Disposable d) {
96 |
97 | }
98 |
99 | @Override
100 | public void onNext(Integer integer) {
101 | SystemOut.println(integer);
102 | }
103 |
104 | @Override
105 | public void onError(Throwable e) {
106 | SystemOut.println(e);
107 | }
108 |
109 | @Override
110 | public void onComplete() {
111 | SystemOut.println("完成");
112 | }
113 | });
114 | }
115 |
116 | public void demo4() {
117 | Observable
118 | .fromCallable(new Callable() {
119 | @Override
120 | public String call() throws Exception {
121 | SystemOut.println("call:当前线程-->" + Thread.currentThread().getName());
122 | return "Hello Rxjava";
123 | }
124 | })
125 | .subscribeOn(Schedulers.io())
126 | .observeOn(AndroidSchedulers.mainThread())
127 | .onTerminateDetach()//订阅关系取消时,解除上游对下游的引用
128 | .subscribe(new Observer() {
129 | @Override
130 | public void onSubscribe(Disposable d) {
131 | SystemOut.println("onSubscribe:当前线程-->" + Thread.currentThread().getName());
132 | }
133 |
134 | @Override
135 | public void onNext(String s) {
136 | SystemOut.println("onNext:当前线程-->" + Thread.currentThread().getName());
137 | SystemOut.println(s);
138 | }
139 |
140 | @Override
141 | public void onError(Throwable e) {
142 | SystemOut.println("onError:当前线程-->" + Thread.currentThread().getName());
143 | }
144 |
145 | @Override
146 | public void onComplete() {
147 | SystemOut.println("onComplete:当前线程-->" + Thread.currentThread().getName());
148 | }
149 | });
150 | }
151 |
152 | public void demo5() {
153 | Observable
154 | .fromCallable(new Callable() {
155 | @Override
156 | public String call() throws Exception {
157 | SystemOut.println("call:当前线程-->" + Thread.currentThread().getName());
158 | return "Hello Rxjava";
159 | }
160 | })
161 | .compose(new SchedulersTransFormer<>())
162 | .subscribe(new Observer() {
163 | @Override
164 | public void onSubscribe(Disposable d) {
165 | SystemOut.println("onSubscribe:当前线程-->" + Thread.currentThread().getName());
166 | }
167 |
168 | @Override
169 | public void onNext(String s) {
170 | SystemOut.println("onNext:当前线程-->" + Thread.currentThread().getName());
171 | SystemOut.println(s);
172 | }
173 |
174 | @Override
175 | public void onError(Throwable e) {
176 | SystemOut.println("onError:当前线程-->" + Thread.currentThread().getName());
177 | }
178 |
179 | @Override
180 | public void onComplete() {
181 | SystemOut.println("onComplete:当前线程-->" + Thread.currentThread().getName());
182 | }
183 | });
184 | }
185 |
186 | public void demo6() {
187 | Single
188 | .just(3)
189 | .lift(new SQSingleOperator())
190 | .subscribe(new SingleObserver() {
191 | @Override
192 | public void onSubscribe(Disposable d) {
193 | SystemOut.println("开始订阅");
194 | }
195 |
196 | @Override
197 | public void onSuccess(Integer integer) {
198 | SystemOut.println(integer);
199 | }
200 |
201 | @Override
202 | public void onError(Throwable e) {
203 | SystemOut.println(e);
204 | }
205 | });
206 | }
207 |
208 | public static class SQOperator implements ObservableOperator {
209 |
210 | @Override
211 | public Observer super Integer> apply(Observer super Integer> observer) throws Exception {
212 | return new Observer() {
213 | private Disposable mDisposable;
214 |
215 | @Override
216 | public void onSubscribe(Disposable d) {
217 | mDisposable = d;
218 | observer.onSubscribe(d);
219 | }
220 |
221 | @Override
222 | public void onNext(Integer integer) {
223 | if (!mDisposable.isDisposed()) observer.onNext(integer * integer);
224 | }
225 |
226 | @Override
227 | public void onError(Throwable e) {
228 | if (!mDisposable.isDisposed()) observer.onError(e);
229 | }
230 |
231 | @Override
232 | public void onComplete() {
233 | if (!mDisposable.isDisposed()) observer.onComplete();
234 | }
235 | };
236 | }
237 | }
238 |
239 | public static class ToCharOperator implements ObservableOperator {
240 |
241 |
242 | @Override
243 | public Observer super String> apply(Observer super Character> observer) throws Exception {
244 | return new Observer() {
245 | private Disposable mDisposable;
246 |
247 | @Override
248 | public void onSubscribe(Disposable d) {
249 | mDisposable = d;
250 | }
251 |
252 | @Override
253 | public void onNext(String s) {
254 | for (Character character : s.toCharArray()) {
255 | if (mDisposable.isDisposed()) break;
256 | observer.onNext(character);
257 | }
258 | }
259 |
260 | @Override
261 | public void onError(Throwable e) {
262 | if (!mDisposable.isDisposed()) observer.onError(e);
263 | }
264 |
265 | @Override
266 | public void onComplete() {
267 | if (!mDisposable.isDisposed()) observer.onComplete();
268 | }
269 | };
270 | }
271 | }
272 |
273 | public static class SQTransFormer implements ObservableTransformer {
274 |
275 |
276 | @Override
277 | public ObservableSource apply(Observable upstream) {
278 | return upstream.map(new Function() {
279 | @Override
280 | public Integer apply(Integer integer) throws Exception {
281 | return integer * integer;
282 | }
283 | });
284 | }
285 | }
286 |
287 | public static class SchedulersTransFormer implements ObservableTransformer {
288 |
289 | @Override
290 | public ObservableSource apply(Observable upstream) {
291 | return upstream
292 | .subscribeOn(Schedulers.io())
293 | .observeOn(AndroidSchedulers.mainThread())
294 | .onTerminateDetach();//订阅关系取消时,解除上游对下游的引用;
295 | }
296 | }
297 |
298 | public static class SQSingleOperator implements SingleOperator {
299 |
300 | @Override
301 | public SingleObserver super Integer> apply(SingleObserver super Integer> observer) throws Exception {
302 | return new SingleObserver() {
303 | private Disposable mDisposable;
304 |
305 | @Override
306 | public void onSubscribe(Disposable d) {
307 | mDisposable = d;
308 | observer.onSubscribe(d);
309 | }
310 |
311 | @Override
312 | public void onSuccess(Integer integer) {
313 | observer.onSuccess(integer * integer);
314 | }
315 |
316 | @Override
317 | public void onError(Throwable e) {
318 | observer.onError(e);
319 | }
320 | };
321 | }
322 | }
323 |
324 |
325 | }
326 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/Rxjava2DemoBean.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava;
2 |
3 | /**
4 | * 功能描述:
5 | *
6 | * @author (作者) edward(冯丰枫)
7 | * @link http://www.jianshu.com/u/f7176d6d53d2
8 | * 创建时间: 2018/12/15
9 | */
10 | public class Rxjava2DemoBean {
11 | private int index;
12 | private String title;
13 | private String url;
14 | private String demo_class;
15 |
16 | public int getIndex() {
17 | return index;
18 | }
19 |
20 | public void setIndex(int index) {
21 | this.index = index;
22 | }
23 |
24 | public String getTitle() {
25 | return title;
26 | }
27 |
28 | public void setTitle(String title) {
29 | this.title = title;
30 | }
31 |
32 | public String getUrl() {
33 | return url;
34 | }
35 |
36 | public void setUrl(String url) {
37 | this.url = url;
38 | }
39 |
40 | public String getDemo_class() {
41 | return demo_class;
42 | }
43 |
44 | public void setDemo_class(String demo_class) {
45 | this.demo_class = demo_class;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/WebViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava;
2 |
3 | import com.edward.rxjava.R;
4 |
5 | import android.os.Build;
6 | import android.os.Bundle;
7 | import android.support.annotation.Nullable;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.view.KeyEvent;
10 | import android.webkit.WebSettings;
11 | import android.webkit.WebView;
12 | import android.webkit.WebViewClient;
13 |
14 | import butterknife.BindView;
15 | import butterknife.ButterKnife;
16 |
17 | public class WebViewActivity extends AppCompatActivity {
18 | @BindView(R.id.web_view)
19 | WebView web_view;
20 |
21 | @Override
22 | protected void onCreate(@Nullable Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | setContentView(R.layout.activity_web_view);
25 | ButterKnife.bind(this);
26 | web_view.getSettings().setJavaScriptEnabled(true);
27 | web_view.getSettings().setDomStorageEnabled(true);
28 | web_view.getSettings().setUseWideViewPort(true);
29 | web_view.getSettings().setSavePassword(false);
30 | web_view.getSettings().setPluginState(WebSettings.PluginState.ON);
31 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
32 | web_view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
33 | }
34 | web_view.loadUrl(getIntent().getStringExtra("url"));
35 | web_view.setWebViewClient(new WebViewClient() {
36 | @Override
37 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
38 | view.loadUrl(url);
39 | return true;
40 | }
41 | });
42 | }
43 |
44 | @Override
45 | public boolean onKeyDown(int keyCode, KeyEvent event) {
46 | if (keyCode == KeyEvent.KEYCODE_BACK) {
47 | goBackIgnoreErrorPage();
48 | return true;
49 | }
50 | return super.onKeyDown(keyCode, event);
51 | }
52 |
53 | public void goBackIgnoreErrorPage() {
54 | if (web_view.canGoBack()) {
55 | web_view.goBack();//返回上一页面
56 | } else {
57 | finish();
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/directory/DirectoryActivity.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.directory;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.reflect.TypeToken;
5 |
6 | import com.edward.rxjava.R;
7 | import com.edward.rxjava.Rxjava2Demo.Rxjava2Activity;
8 | import com.edward.rxjava.Rxjava2DemoBean;
9 |
10 | import android.content.Intent;
11 | import android.os.Bundle;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.support.v7.widget.LinearLayoutManager;
14 | import android.support.v7.widget.RecyclerView;
15 | import android.widget.ImageView;
16 |
17 | import java.io.BufferedReader;
18 | import java.io.InputStreamReader;
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | import butterknife.BindView;
23 | import butterknife.ButterKnife;
24 | import butterknife.OnClick;
25 | import io.reactivex.Observable;
26 | import io.reactivex.android.schedulers.AndroidSchedulers;
27 | import io.reactivex.disposables.Disposable;
28 | import io.reactivex.functions.Function;
29 | import io.reactivex.schedulers.Schedulers;
30 |
31 | public class DirectoryActivity extends AppCompatActivity {
32 | @BindView(R.id.directory_list)
33 | RecyclerView directory_list;
34 | @BindView(R.id.directory_demo)
35 | ImageView directory_demo;
36 | private Disposable mDisposable;
37 |
38 | @Override
39 | protected void onCreate(Bundle savedInstanceState) {
40 | super.onCreate(savedInstanceState);
41 | setContentView(R.layout.activity_directory);
42 | ButterKnife.bind(this);
43 | directory_list.setLayoutManager(new LinearLayoutManager(this));
44 | final DirectoryAdapter adapter = new DirectoryAdapter();
45 | directory_list.setAdapter(adapter);
46 | mDisposable = Observable
47 | .fromCallable(() -> new BufferedReader(new InputStreamReader(getAssets().open("directory.json"))))
48 | .map((Function>) bufferedReader -> new Gson().fromJson(bufferedReader, new TypeToken>() {
49 | }.getType()))
50 | .subscribeOn(Schedulers.io())
51 | .observeOn(AndroidSchedulers.mainThread())
52 | .subscribe(adapter::notifyDataSetChanged);
53 | }
54 |
55 | @OnClick(R.id.directory_demo)
56 | public void onDemoClick() {
57 | startActivity(new Intent(this, Rxjava2Activity.class));
58 | }
59 |
60 |
61 | @Override
62 | protected void onDestroy() {
63 | super.onDestroy();
64 | if (!mDisposable.isDisposed()) mDisposable.dispose();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/edward/rxjava/directory/DirectoryAdapter.java:
--------------------------------------------------------------------------------
1 | package com.edward.rxjava.directory;
2 |
3 | import com.edward.rxjava.R;
4 | import com.edward.rxjava.Rxjava2DemoBean;
5 | import com.edward.rxjava.WebViewActivity;
6 |
7 | import android.content.Intent;
8 | import android.support.annotation.NonNull;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.view.LayoutInflater;
11 | import android.view.ViewGroup;
12 | import android.widget.TextView;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | import butterknife.BindView;
18 | import butterknife.ButterKnife;
19 |
20 | /**
21 | * 功能描述:
22 | *
23 | * @author (作者) edward(冯丰枫)
24 | * @link http://www.jianshu.com/u/f7176d6d53d2
25 | * 创建时间: 2018/12/15
26 | */
27 | public class DirectoryAdapter extends RecyclerView.Adapter {
28 | private final List mList;
29 |
30 | DirectoryAdapter() {
31 | mList = new ArrayList<>();
32 | }
33 |
34 | void notifyDataSetChanged(List rxjava2DemoBeans) {
35 | mList.clear();
36 | mList.addAll(rxjava2DemoBeans);
37 | this.notifyDataSetChanged();
38 | }
39 |
40 | @NonNull
41 | @Override
42 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
43 | return new ViewHolder(viewGroup);
44 | }
45 |
46 | @Override
47 | public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
48 | viewHolder.setData(mList.get(i));
49 | }
50 |
51 | @Override
52 | public int getItemCount() {
53 | return mList.size();
54 | }
55 |
56 | static class ViewHolder extends RecyclerView.ViewHolder {
57 | @BindView(R.id.directory_item_text)
58 | TextView directory_item_text;
59 |
60 | ViewHolder(@NonNull ViewGroup viewGroup) {
61 | super(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_directory_item, viewGroup, false));
62 | ButterKnife.bind(this, itemView);
63 | }
64 |
65 | void setData(Rxjava2DemoBean rxjava2DemoBean) {
66 | directory_item_text.setText(rxjava2DemoBean.getTitle());
67 | itemView.setOnClickListener(v -> {
68 | Intent intent = new Intent(v.getContext(), WebViewActivity.class);
69 | intent.putExtra("url", rxjava2DemoBean.getUrl());
70 | v.getContext().startActivity(intent);
71 | });
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_directory.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
15 |
21 |
22 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_directory_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_rxjava2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
20 |
26 |
27 |
33 |
34 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_web_view.xml:
--------------------------------------------------------------------------------
1 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/simple_spinner_item.xml:
--------------------------------------------------------------------------------
1 |
5 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/directory_demo_icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengchuanfang/Rxjava2Tutorial/a103cfed797dc05c0da4ce877ad0201db7026bd1/app/src/main/res/mipmap-xhdpi/directory_demo_icon.jpg
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 | #66000000
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Rxjava2Tutorial
3 | Rxjava2入门教程
4 | start
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/test/java/com/edward/edward/rxjava2tutorial/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.edward.edward.rxjava2tutorial;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | google()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.2.1'
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 | google()
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
25 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengchuanfang/Rxjava2Tutorial/a103cfed797dc05c0da4ce877ad0201db7026bd1/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Dec 16 11:18:42 CST 2018
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-4.6-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 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':JavaEcho'
2 |
--------------------------------------------------------------------------------