├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── us │ │ └── mifeng │ │ └── rxjava │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── us │ │ │ └── mifeng │ │ │ └── rxjava │ │ │ ├── MainActivity.java │ │ │ ├── NetActivity.java │ │ │ ├── WelcomeActivity.java │ │ │ ├── beans │ │ │ ├── Weather.java │ │ │ └── XMLWeather.java │ │ │ └── net │ │ │ └── HttpUtils.java │ └── res │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── activity_net.xml │ │ └── activity_welcome.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── us │ └── mifeng │ └── rxjava │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── retrofit ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── us │ │ └── mifeng │ │ └── retrofit │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── us │ │ │ └── mifeng │ │ │ ├── beans │ │ │ ├── PhoneResult.java │ │ │ └── TvInfo.java │ │ │ ├── inte │ │ │ ├── GitHubService.java │ │ │ ├── PhoneService.java │ │ │ └── TvService.java │ │ │ ├── net │ │ │ └── RetrofitWrapper.java │ │ │ └── retrofit │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── us │ └── mifeng │ └── retrofit │ └── ExampleUnitTest.java └── 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/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.8 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.2" 6 | defaultConfig { 7 | applicationId "us.mifeng.rxjava" 8 | minSdkVersion 19 9 | targetSdkVersion 24 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | jackOptions{ 14 | enabled true 15 | } 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | compileOptions { 24 | targetCompatibility 1.8 25 | sourceCompatibility 1.8 26 | } 27 | } 28 | 29 | dependencies { 30 | compile fileTree(dir: 'libs', include: ['*.jar']) 31 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 32 | exclude group: 'com.android.support', module: 'support-annotations' 33 | }) 34 | compile 'com.android.support:appcompat-v7:24.2.1' 35 | compile 'io.reactivex:rxandroid:1.2.0' 36 | compile 'io.reactivex:rxjava:1.1.5' 37 | testCompile 'junit:junit:4.12' 38 | } 39 | -------------------------------------------------------------------------------- /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:\installPackage\studio_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 | -------------------------------------------------------------------------------- /app/src/androidTest/java/us/mifeng/rxjava/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package us.mifeng.rxjava; 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("us.mifeng.rxjava", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/us/mifeng/rxjava/MainActivity.java: -------------------------------------------------------------------------------- 1 | package us.mifeng.rxjava; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.util.Log; 6 | import android.view.View; 7 | 8 | import java.io.File; 9 | import java.util.List; 10 | import java.util.Random; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | import rx.Observable; 14 | import rx.Subscriber; 15 | import rx.functions.Action0; 16 | import rx.functions.Action1; 17 | import rx.functions.Func0; 18 | import rx.functions.Func1; 19 | import rx.functions.Func2; 20 | import rx.observables.GroupedObservable; 21 | import rx.schedulers.Schedulers; 22 | 23 | public class MainActivity extends AppCompatActivity { 24 | 25 | private int i; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_main); 31 | //rxTest(); 32 | //rxTest1(); 33 | //rxTest2(); 34 | //rxTest3(); 35 | //rxTest4(); 36 | //rxText5(); 37 | //rxText6(); 38 | //rxTest7(); 39 | //rxTest8(); 40 | //rxTest9(); 41 | //rxTest10(); 42 | //rxBuffer(); 43 | //groupBy(); 44 | //cast(); 45 | //scan(); 46 | filter(); 47 | } 48 | private void filter(){ 49 | Observable.just(1,2,3,4,5,6).filter(new Func1() { 50 | @Override 51 | public Boolean call(Integer integer) { 52 | return integer<4; 53 | } 54 | }).subscribe(new Subscriber() { 55 | @Override 56 | public void onCompleted() { 57 | 58 | } 59 | 60 | @Override 61 | public void onError(Throwable e) { 62 | 63 | } 64 | 65 | @Override 66 | public void onNext(Integer integer) { 67 | log("filter"+integer); 68 | } 69 | }); 70 | } 71 | private void cast(){ 72 | Observable.just(1,2,3,4,5,6).cast(Integer.class).subscribe(new Action1() { 73 | @Override 74 | public void call(Integer integer) { 75 | log(integer+""); 76 | } 77 | }); 78 | } 79 | private void scan(){ 80 | Observable.just(1,2,3,4,5,6).scan(new Func2() { 81 | @Override 82 | public Integer call(Integer integer, Integer integer2) { 83 | return integer+integer2; 84 | } 85 | }).subscribe(new Subscriber() { 86 | @Override 87 | public void onCompleted() { 88 | 89 | } 90 | 91 | @Override 92 | public void onError(Throwable e) { 93 | 94 | } 95 | 96 | @Override 97 | public void onNext(Integer integer) { 98 | log("==>"+integer); 99 | } 100 | }); 101 | } 102 | private void groupBy(){ 103 | Observable.interval(1,TimeUnit.SECONDS).take(10).groupBy(new Func1() { 104 | @Override 105 | public Long call(Long aLong) { 106 | return aLong%3; 107 | } 108 | }).subscribe(new Action1>() { 109 | @Override 110 | public void call(GroupedObservable result) { 111 | result.subscribe(new Action1() { 112 | @Override 113 | public void call(Long aLong) { 114 | log("key"+result.getKey()+",value"+aLong); 115 | } 116 | }); 117 | } 118 | }); 119 | } 120 | private ObservablelistFiles(File f){ 121 | if (f.isDirectory()){ 122 | return Observable.from(f.listFiles()).flatMap(new Func1>() { 123 | @Override 124 | public Observable call(File file) { 125 | return listFiles(file); 126 | } 127 | }); 128 | }else{ 129 | return Observable.just(f); 130 | } 131 | } 132 | public void click(View view){ 133 | log(getApplicationContext().getExternalCacheDir().isDirectory()+""); 134 | Observable.just(getApplicationContext().getExternalCacheDir()).flatMap(new Func1>() { 135 | @Override 136 | public Observable call(File file) { 137 | return listFiles(file); 138 | } 139 | }).subscribe(new Action1() { 140 | @Override 141 | public void call(File file) { 142 | log(file.getAbsolutePath()); 143 | } 144 | }); 145 | } 146 | 147 | private void rxBuffer() { 148 | final String[]mails = new String[]{"Here is an email!", "Another email!", "Yet another email!"}; 149 | //每隔一秒就随机发布一个邮件 150 | ObservableendLessMail = Observable.create(new Observable.OnSubscribe() { 151 | @Override 152 | public void call(Subscriber subscriber) { 153 | try { 154 | if (subscriber.isUnsubscribed()){ 155 | return; 156 | } 157 | Random random = new Random(); 158 | while(true){ 159 | String mail = mails[random.nextInt(mails.length)]; 160 | subscriber.onNext(mail); 161 | Thread.sleep(1000); 162 | } 163 | }catch (Exception e){ 164 | subscriber.onError(e); 165 | } 166 | } 167 | }).subscribeOn(Schedulers.io()); 168 | //把上面产生的邮件缓存到列表中,并每隔3秒通知订阅着 169 | endLessMail.buffer(3,TimeUnit.SECONDS).subscribe(new Action1>() { 170 | @Override 171 | public void call(List strings) { 172 | log(String.format("You've got %d new messages! Here they are!",strings.size())); 173 | for (int i=0;i myObservable = Observable.create(new rx.Observable.OnSubscribe() { 184 | @Override 185 | public void call(Subscriber subscriber) { 186 | subscriber.onNext("hello word"); 187 | subscriber.onCompleted(); 188 | } 189 | }); 190 | /**----------接收出,观察者----------------*/ 191 | SubscribermySubscriber = new Subscriber() { 192 | @Override 193 | public void onCompleted() { 194 | 195 | } 196 | 197 | @Override 198 | public void onError(Throwable e) { 199 | 200 | } 201 | 202 | @Override 203 | public void onNext(String s) { 204 | //Log.i("tag","onNext--------------->"+s); 205 | } 206 | }; 207 | /**-----------注册观察者---------------*/ 208 | myObservable.subscribe(mySubscriber); 209 | } 210 | public void rxTest1(){ 211 | /**-----------简化步骤------------------*/ 212 | Observable.just(6).subscribe(new Action1() { 213 | @Override 214 | public void call(Integer integer) { 215 | // Log.i("tag","Integer------------>"+integer); 216 | } 217 | }); 218 | Observable.just("String args").subscribe(new Action1() { 219 | @Override 220 | public void call(String s) { 221 | //Log.i("tag","s--------------->"+s); 222 | } 223 | }); 224 | } 225 | public void rxTest2(){ 226 | Observable.just("I an-->").map(new Func1() { 227 | @Override 228 | public String call(String s) { 229 | return s+"map"; 230 | } 231 | }).subscribe(new Action1() { 232 | @Override 233 | public void call(String s) { 234 | //Log.i("tag","maps----------------->"+s); 235 | } 236 | }); 237 | } 238 | private void rxTest3() { 239 | Observable.create(new Observable.OnSubscribe() { 240 | @Override 241 | public void call(Subscriber subscriber) { 242 | try { 243 | if (!subscriber.isUnsubscribed()){ 244 | for(int i=0;i<5;i++){ 245 | subscriber.onNext(i); 246 | } 247 | subscriber.onCompleted(); 248 | } 249 | }catch (Exception e){ 250 | e.printStackTrace(); 251 | } 252 | } 253 | }).subscribe(new Subscriber() { 254 | @Override 255 | public void onCompleted() { 256 | log("onCompleted"); 257 | } 258 | 259 | @Override 260 | public void onError(Throwable e) { 261 | log(e.getMessage()); 262 | } 263 | 264 | @Override 265 | public void onNext(Integer integer) { 266 | log(integer+""); 267 | } 268 | }); 269 | } 270 | private void rxTest4(){ 271 | Integer[]items ={0,1,2,3,4,5}; 272 | Observable myObservable = Observable.from(items); 273 | myObservable.subscribe(new Action1() { 274 | @Override 275 | public void call(Integer item) { 276 | System.out.println(item); 277 | log(item+""); 278 | } 279 | }, new Action1() { 280 | @Override 281 | public void call(Throwable throwable) { 282 | // System.out.print("error encountered" + throwable.getMessage()); 283 | log("error encountered" + throwable.getMessage()); 284 | } 285 | }, new Action0() { 286 | @Override 287 | public void call() { 288 | //System.out.println("sequence complite"); 289 | log("sequence complite"); 290 | } 291 | }); 292 | } 293 | private void rxText5(){ 294 | Observable myObservable = Observable.just(1,2,3,4,5,6); 295 | myObservable.subscribe(new Subscriber() { 296 | @Override 297 | public void onCompleted() { 298 | log("完成"); 299 | } 300 | 301 | @Override 302 | public void onError(Throwable e) { 303 | log(e.getMessage()); 304 | } 305 | 306 | @Override 307 | public void onNext(Integer o) { 308 | log("========x======"+o.toString()); 309 | } 310 | }); 311 | } 312 | private void rxText6(){ 313 | i = 10; 314 | Observable justObservable = Observable.just(i); 315 | i = 120; 316 | Observable deferObservable = Observable.defer(new Func0>() { 317 | @Override 318 | public Observable call() { 319 | return Observable.just(i); 320 | } 321 | }); 322 | i = 1531; 323 | justObservable.subscribe(new Subscriber() { 324 | @Override 325 | public void onCompleted() { 326 | log("just完成"); 327 | } 328 | 329 | @Override 330 | public void onError(Throwable e) { 331 | 332 | } 333 | 334 | @Override 335 | public void onNext(Integer o) { 336 | log("j==========>ust"+o); 337 | } 338 | }); 339 | deferObservable.subscribe(new Subscriber() { 340 | @Override 341 | public void onCompleted() { 342 | log("defer完成"); 343 | } 344 | 345 | @Override 346 | public void onError(Throwable e) { 347 | 348 | } 349 | 350 | @Override 351 | public void onNext(Integer o) { 352 | log("defer=========>"+o); 353 | } 354 | }); 355 | } 356 | public void rxTest7(){ 357 | Observable.timer(2,2, TimeUnit.SECONDS).subscribe(new Subscriber() { 358 | @Override 359 | public void onCompleted() { 360 | log("完成"); 361 | } 362 | 363 | @Override 364 | public void onError(Throwable e) { 365 | 366 | } 367 | 368 | @Override 369 | public void onNext(Long aLong) { 370 | log("next"+aLong); 371 | } 372 | }); 373 | } 374 | private void rxTest8(){ 375 | Observable.range(3,10).repeat(3).subscribe(new Subscriber() { 376 | @Override 377 | public void onCompleted() { 378 | log("完成"); 379 | } 380 | 381 | @Override 382 | public void onError(Throwable e) { 383 | 384 | } 385 | 386 | @Override 387 | public void onNext(Integer integer) { 388 | log("next===>"+integer); 389 | } 390 | }); 391 | } 392 | private void rxTest9(){ 393 | Observable.just(1,2,3).repeatWhen(new Func1, Observable>() { 394 | @Override 395 | public Observable call(final Observable observable) { 396 | return observable.zipWith(Observable.range(1, 6), new Func2() { 397 | @Override 398 | public Integer call(Void aVoid, Integer integer) { 399 | return integer; 400 | } 401 | }).flatMap(new Func1>() { 402 | @Override 403 | public Observable call(Integer integer) { 404 | log("delay repeat the===========>"+integer); 405 | return Observable.timer(1,TimeUnit.SECONDS); 406 | } 407 | }); 408 | } 409 | }).subscribe(new Subscriber() { 410 | @Override 411 | public void onCompleted() { 412 | 413 | } 414 | 415 | @Override 416 | public void onError(Throwable e) { 417 | 418 | } 419 | 420 | @Override 421 | public void onNext(Integer integer) { 422 | 423 | } 424 | }); 425 | } 426 | private void rxTest10(){ 427 | ObservableerrorObservable = Observable.error(new Exception("this is error")); 428 | Observableobservable1 = Observable.timer(0,1000,TimeUnit.SECONDS) 429 | .map(new Func1() { 430 | @Override 431 | public Long call(Long aLong) { 432 | return aLong*5; 433 | } 434 | }).take(3).mergeWith(errorObservable.delay(3500,TimeUnit.SECONDS)); 435 | Observableobservable2 = Observable.timer(500,1000,TimeUnit.SECONDS) 436 | .map(new Func1() { 437 | @Override 438 | public Long call(Long aLong) { 439 | return aLong*5; 440 | } 441 | }).take(5); 442 | Observable.mergeDelayError(observable1,observable2) 443 | .subscribe(new Subscriber() { 444 | @Override 445 | public void onCompleted() { 446 | Log.i("tag","-----onCompleted----------->"); 447 | } 448 | 449 | @Override 450 | public void onError(Throwable e) { 451 | Log.i("tag","-----onError----------->"+e.getMessage()); 452 | } 453 | 454 | @Override 455 | public void onNext(Long aLong) { 456 | Log.i("tag","-----onNext----------->"+aLong); 457 | } 458 | }); 459 | } 460 | public void log(String str){ 461 | Log.i("tag","-----------------------"+str); 462 | } 463 | private void study(){ 464 | 465 | 466 | } 467 | } 468 | -------------------------------------------------------------------------------- /app/src/main/java/us/mifeng/rxjava/NetActivity.java: -------------------------------------------------------------------------------- 1 | package us.mifeng.rxjava; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.text.TextUtils; 6 | import android.util.Log; 7 | import android.view.View; 8 | import android.widget.EditText; 9 | import android.widget.TextView; 10 | import android.widget.Toast; 11 | 12 | import rx.Observable; 13 | import rx.Subscriber; 14 | import rx.Subscription; 15 | import rx.android.schedulers.AndroidSchedulers; 16 | import rx.schedulers.Schedulers; 17 | import us.mifeng.rxjava.beans.Weather; 18 | import us.mifeng.rxjava.beans.XMLWeather; 19 | import us.mifeng.rxjava.net.HttpUtils; 20 | 21 | import static us.mifeng.rxjava.R.id.weather; 22 | 23 | public class NetActivity extends AppCompatActivity implements View.OnClickListener{ 24 | /**天气预报的API地址*/ 25 | private static final String WEATHRE_API_URL="http://php.weather.sina.com.cn/xml.php?city=%s&password=DJOYnieT8234jlsK&day=0"; 26 | private static final String path = "http://www.weather.com.cn/data/cityinfo/101010100.html"; 27 | private EditText cityET; 28 | private TextView queryET; 29 | private TextView weatherET; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.activity_net); 35 | init(); 36 | 37 | 38 | } 39 | 40 | private void init() { 41 | cityET = (EditText) findViewById(R.id.searchText); 42 | queryET = (TextView) findViewById(R.id.query); 43 | weatherET = (TextView) findViewById(weather); 44 | queryET.setOnClickListener(this); 45 | weatherET.setOnClickListener(this); 46 | } 47 | private void observableAsNormal(final String city){ 48 | /** 49 | * Observable:可观察这对象创建, 50 | * OnSubscribe:在订阅的时候,预约数据处理,在这儿就是预约天气接口数据的请求与数据解析 51 | *通过onNext(),onError(),onComplete()方法通知预约着。 52 | * Observable.subscribe()方法对Observable进行了订阅。 53 | *subscribeOn()指明了在订阅的时候,数据在那个线程中运行 54 | * observeOn()指明了观察者在那个线程中运行。 55 | * */ 56 | Subscription subscribe = Observable.create(new Observable.OnSubscribe() { 57 | 58 | @Override 59 | public void call(Subscriber subscriber) { 60 | if (subscriber.isUnsubscribed()) { 61 | return; 62 | } 63 | try { 64 | String weatherXml = new HttpUtils().getWheather(WEATHRE_API_URL, city); 65 | Weather weather = new XMLWeather().parseWeather(weatherXml); 66 | subscriber.onNext(weather); 67 | subscriber.onCompleted(); 68 | } catch (Exception e) { 69 | subscriber.onError(e); 70 | } 71 | } 72 | }).subscribeOn(Schedulers.newThread()) 73 | .observeOn(AndroidSchedulers.mainThread()) 74 | .subscribe(new Subscriber() { 75 | @Override 76 | public void onCompleted() { 77 | Log.i("tag","---------------onCompleted-------------"); 78 | } 79 | 80 | @Override 81 | public void onError(Throwable e) { 82 | Log.i("tag","---------e-----------"+e.getMessage()); 83 | } 84 | 85 | @Override 86 | public void onNext(Weather weather) { 87 | if (weather != null) { 88 | weatherET.setText(weather.toString()); 89 | } 90 | Log.i("tag","-------weather为空-------------"+weather); 91 | } 92 | }); 93 | } 94 | private void observableAsLambda(String city){ 95 | Subscription subscribe = Observable.create(subscriber -> { 96 | try { 97 | if (subscriber.isUnsubscribed()) return; 98 | String weatherXml = new HttpUtils().getWheather(WEATHRE_API_URL, city); 99 | Weather weather = new XMLWeather().parseWeather(weatherXml); 100 | subscriber.onNext(weather); 101 | subscriber.onCompleted(); 102 | } catch (Exception e) { 103 | subscriber.onError(e); 104 | } 105 | }).subscribeOn(Schedulers.newThread()) 106 | .observeOn(AndroidSchedulers.mainThread()) 107 | .subscribe(weather -> { 108 | if (weather != null) { 109 | weatherET.setText(weather.toString()); 110 | } 111 | }, e -> { 112 | Toast.makeText(NetActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); 113 | }); 114 | } 115 | public void fun(){ 116 | Observableobservable = Observable.create(new Observable.OnSubscribe() { 117 | @Override 118 | public void call(Subscriber subscriber) { 119 | if (subscriber.isUnsubscribed()){ 120 | return; 121 | } 122 | try { 123 | String ss = new HttpUtils().getString(path); 124 | subscriber.onNext(ss); 125 | subscriber.onCompleted(); 126 | }catch (Exception e){ 127 | subscriber.onError(e); 128 | } 129 | } 130 | }); 131 | observable.subscribeOn(Schedulers.newThread()) 132 | .observeOn(AndroidSchedulers.mainThread()) 133 | .subscribe(ss->{ 134 | if (ss!=null){ 135 | weatherET.setText(ss); 136 | } 137 | },e->{ 138 | Toast.makeText(NetActivity.this,"------"+e.getMessage(),Toast.LENGTH_LONG).show(); 139 | }); 140 | } 141 | 142 | @Override 143 | public void onClick(View v) { 144 | if (v.getId()==R.id.query){ 145 | weatherET.setText(""); 146 | String city = cityET.getText().toString(); 147 | if (TextUtils.isEmpty(city)){ 148 | Toast.makeText(NetActivity.this,"城市名不能为空",Toast.LENGTH_LONG).show(); 149 | return; 150 | } 151 | //observableAsNormal(city); 152 | //observableAsLambda(city); 153 | fun(); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /app/src/main/java/us/mifeng/rxjava/WelcomeActivity.java: -------------------------------------------------------------------------------- 1 | package us.mifeng.rxjava; 2 | 3 | import android.content.Intent; 4 | import android.graphics.Bitmap; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.widget.ImageView; 8 | 9 | import java.util.concurrent.TimeUnit; 10 | 11 | import rx.Observable; 12 | import rx.Subscriber; 13 | import rx.android.schedulers.AndroidSchedulers; 14 | import rx.functions.Action1; 15 | import rx.functions.Func1; 16 | import rx.schedulers.Schedulers; 17 | 18 | public class WelcomeActivity extends AppCompatActivity { 19 | private int num = 5; 20 | private ImageView imageView; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_welcome); 26 | imageView = (ImageView) findViewById(R.id.imageview); 27 | skip(); 28 | //showAdvertisment(); 29 | } 30 | 31 | private void showAdvertisment() { 32 | Observable loadBitmapFromLocal = Observable.create(new Observable.OnSubscribe() { 33 | 34 | @Override 35 | public void call(Subscriber o) { 36 | o.onNext(""); 37 | } 38 | }); 39 | Observable loadBitmapFromNet = Observable.create(new Observable.OnSubscribe() { 40 | @Override 41 | public void call(Subscriber o) { 42 | o.onNext(""); 43 | } 44 | }); 45 | Observable.mergeDelayError(loadBitmapFromLocal.subscribeOn(Schedulers.io()), 46 | loadBitmapFromNet.subscribeOn(Schedulers.newThread()), 47 | Observable.timer(3,TimeUnit.SECONDS).map(new Func1() { 48 | @Override 49 | public Object call(Object o) { 50 | return null; 51 | } 52 | }).sample(3,TimeUnit.SECONDS,AndroidSchedulers.mainThread())).flatMap(new Func1() { 53 | @Override 54 | public Object call(Bitmap bitmap) { 55 | if (bitmap==null){ 56 | return Observable.empty(); 57 | }else{ 58 | imageView.setImageBitmap(bitmap); 59 | return Observable.timer(3,TimeUnit.SECONDS,AndroidSchedulers.mainThread()); 60 | } 61 | } 62 | }).subscribe(new Action1() { 63 | @Override 64 | public void call(Object o) { 65 | startActivity(new Intent(WelcomeActivity.this,MainActivity.class)); 66 | 67 | } 68 | }); 69 | 70 | } 71 | 72 | private void skip() { 73 | Observable.timer(1,TimeUnit.SECONDS, AndroidSchedulers.mainThread()).map(new Func1() { 74 | @Override 75 | public Object call(Long aLong) { 76 | // Log.i("tag","----------------->"+(num-aLong)); 77 | startActivity(new Intent(WelcomeActivity.this,MainActivity.class)); 78 | finish(); 79 | return null; 80 | } 81 | }).subscribe(); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/us/mifeng/rxjava/beans/Weather.java: -------------------------------------------------------------------------------- 1 | package us.mifeng.rxjava.beans; 2 | 3 | /** 4 | * Created by 黑夜之火 on 2017/3/26. 5 | */ 6 | 7 | public class Weather { 8 | String city; 9 | String data; 10 | String temperature; 11 | String direction; 12 | String power; 13 | String status; 14 | 15 | @Override 16 | public String toString() { 17 | return "Weather{" + 18 | "city='" + city + '\'' + 19 | ", data='" + data + '\'' + 20 | ", temperature='" + temperature + '\'' + 21 | ", direction='" + direction + '\'' + 22 | ", power='" + power + '\'' + 23 | ", status='" + status + '\'' + 24 | '}'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/us/mifeng/rxjava/beans/XMLWeather.java: -------------------------------------------------------------------------------- 1 | package us.mifeng.rxjava.beans; 2 | 3 | import android.util.Xml; 4 | 5 | import org.xmlpull.v1.XmlPullParser; 6 | 7 | import java.io.StringReader; 8 | 9 | /** 10 | * Created by 黑夜之火 on 2017/3/26. 11 | */ 12 | 13 | public class XMLWeather { 14 | public Weather parseWeather(String weatherXml){ 15 | //采用Pull方式解析xml 16 | StringReader reader = new StringReader(weatherXml); 17 | XmlPullParser xmlParser = Xml.newPullParser(); 18 | Weather weather = null; 19 | try { 20 | xmlParser.setInput(reader); 21 | int eventType = xmlParser.getEventType(); 22 | while(eventType != XmlPullParser.END_DOCUMENT){ 23 | switch (eventType){ 24 | case XmlPullParser.START_DOCUMENT: 25 | weather = new Weather(); 26 | break; 27 | case XmlPullParser.START_TAG: 28 | String nodeName = xmlParser.getName(); 29 | if("city".equals(nodeName)){ 30 | weather.city = xmlParser.nextText(); 31 | } else if("savedate_weather".equals(nodeName)){ 32 | weather.data = xmlParser.nextText(); 33 | } else if("temperature1".equals(nodeName)) { 34 | weather.temperature = xmlParser.nextText(); 35 | } else if("temperature2".equals(nodeName)){ 36 | weather.temperature += "-" + xmlParser.nextText(); 37 | } else if("direction1".equals(nodeName)){ 38 | weather.direction = xmlParser.nextText(); 39 | } else if("power1".equals(nodeName)){ 40 | weather.power = xmlParser.nextText(); 41 | } else if("status1".equals(nodeName)){ 42 | weather.status = xmlParser.nextText(); 43 | } 44 | break; 45 | } 46 | eventType = xmlParser.next(); 47 | } 48 | return weather; 49 | } catch(Exception e) { 50 | e.printStackTrace(); 51 | return null; 52 | } finally { 53 | reader.close(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/us/mifeng/rxjava/net/HttpUtils.java: -------------------------------------------------------------------------------- 1 | package us.mifeng.rxjava.net; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | import java.net.HttpURLConnection; 10 | import java.net.MalformedURLException; 11 | import java.net.URL; 12 | import java.net.URLEncoder; 13 | 14 | /** 15 | * Created by 黑夜之火 on 2017/3/26. 16 | */ 17 | 18 | public class HttpUtils { 19 | public String getWheather(String path,String city){ 20 | //String cityStr = URLEncoder.encode(city); 21 | BufferedReader reader = null; 22 | String urlString = String.format(path, URLEncoder.encode(city)); 23 | 24 | HttpURLConnection conn = null; 25 | try { 26 | URL url = new URL(urlString); 27 | conn = (HttpURLConnection) url.openConnection(); 28 | conn.setRequestMethod("GET"); 29 | conn.setConnectTimeout(50000); 30 | conn.connect(); 31 | InputStream inputStream = conn.getInputStream(); 32 | reader = new BufferedReader(new InputStreamReader(inputStream)); 33 | StringBuffer buffer = new StringBuffer(); 34 | String line = ""; 35 | while(!TextUtils.isEmpty(line=reader.readLine())){ 36 | buffer.append(line); 37 | } 38 | return buffer.toString(); 39 | } catch (MalformedURLException e) { 40 | e.printStackTrace(); 41 | } catch (IOException e) { 42 | e.printStackTrace(); 43 | }finally { 44 | if (conn!=null){ 45 | conn.disconnect(); 46 | if (reader!=null){ 47 | try { 48 | reader.close(); 49 | } catch (IOException e) { 50 | e.printStackTrace(); 51 | } 52 | } 53 | } 54 | } 55 | return null; 56 | } 57 | public String getString(String path){ 58 | return "首先就是创建Observable,创建Observable有很多种方式,这里使用了Observable.create的方式;Observable.create()需要传入一个参数,这个参数其实是一个回调接口,在这个接口方法里我们处理开网络请求和解析xml的工作,并在最后通过onNext()、onCompleted()和onError()通知Subscriber(订阅者); \n" + 59 | "然后就是调用Observable.subscribe()方法对Observable进行订阅。这里要注意,如果不调用Observable.subscribe()方法,刚才在Observable.create()处理的网络请求和解析xml的代码是不会执行的,这也就解释了本文开头所说的“如果没有观察者(即Subscribers),Observables是不会发出任何事件的” \n" + 60 | "说了那么多,好像也没有开线程处理网络请求啊,这样不会报错吗?别急,认真看上面的代码,我还写了两个方法subscribeOn(Schedulers.newThread())和observeOn(AndroidSchedulers.mainThread()),没错,奥妙就在于此: \n" + 61 | "3.1 subscribeOn(Schedulers.newThread())表示开一个新线程处理Observable.create()方法里的逻辑,也就是处理网络请求和解析xml工作 \n" + 62 | "3.2 observeOn(AndroidSchedulers.mainThread())表示subscriber所运行的线程是在UI线程上,也就是更新控件的操作是在UI线程上 \n" + 63 | "3.3 如果这里只有subscribeOn()方法而没有observeOn()方法,那么Observable.create()和subscriber()都是运行在subscribeOn()所指定的线程中; \n" + 64 | "3.4 如果这里只有observeOn()方法而没有subscribeOn()方法,那么Observable.create()运行在主线程(UI线程)中,而subscriber()是运行在observeOn()所指定的线程中(本例的observeOn()恰好是指定主线程而已) "; 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 |