Asynchronous multithreading

Delay trigger

Cyclic timing trigger

One, foreword

In the project development, network request, file read and write, start sub-thread for time-consuming operation, delay return or close prompt box, polling interface to obtain processing results, sub-thread to send content to the main thread update interface and so on. When confronted with these problems or requirements, each programmer will use their preferred or customary usage to implement or interface problems. The result, of course, is that the feature is finished or the problem is fixed. However, the differences in code style, incomplete use, use method is not optimal, and so on more or less there are some defects. Such as:

  • Ali’s Java programming specification does not recommend the explicit use of Thread
  • Using AsyncTask directly can cause memory leaks or weak usage and result in null Pointers
  • Use Handler to perform complex operations to update the interface
  • Delayed operations with postDelayed() cannot be used with child threads
  • Using TimerTask to poll complex update pages is particularly desirable for code uniformity, simplicity, security, and optimal performance. So I thought RxJava might be able to realize this wish. Try and study the record of Demo, use error or better scheme, please comment.

Second, the ground

  1. RxJava libraries are integrated first in the RxJava integration project
api 'the IO. Reactivex. Rxjava2: rxandroid: 2.1.0'
api 'the IO. Reactivex. Rxjava2: rxjava: 2.2.5'
api 'com. Squareup. Retrofit2: retrofit: 2.5.0'
api 'com. Squareup. Retrofit2: adapter - rxjava2:2.4.0'
api 'com. Squareup. Retrofit2: converter - gson: 2.5.0'
Copy the code

For details about how to use RxJava, see using RxJava2 on Android.

  1. RxJava multithreading to use RxJava multithreading operation principle, usage and other, please refer to Andoid how to use RxJava 2 multithreading programming. .

  2. Scheduler is used for multi-threaded operations. Please refer to MY understanding of RxJava for the parameters of Schedulers.

Three, asynchronous

The most straightforward use is for a new Thread() to create a child Thread and then send a Message to update the page using an EventMessage or Handler. A better approach is to create thread pools that centrally manage threads, reuse threads, and control the total number of threads, but it takes a little more time to maintain and optimize. However, it is not recommended to create a thread pool for each Activity or fragment, because performance and thread reuse rates are not necessary.

private void testCreate() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                Log.e("wyn"."ObservableEmitter");

                Log.e("wyn"."ObservableEmitter thread is " + Thread.currentThread().getName());


                long a = 1;
                for (int i = 0; i < 1000000000; i++) {
                    a = a + (a + 1);
                }

                Log.e("wyn"."a is " + a);

                emitter.onNext("wang" + a);
                emitter.onNext("yinan");

                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this.observerString);
    }
Copy the code

Printed result

The 2019-01-18 11:03:08. 326, 27120-27120 /? E/wyn: onSubscribe 2019-01-18 11:03:08.326 27120-27120/? E/wyn: onSubscribe thread is main 2019-01-18 11:03:08.328 27120-27138/? E/ Wyn: ObservableEmitter 2019-01-18 11:03:08.325 ObservableEmitter E/wyn: The 2019-01-18 11:03:13 ObservableEmitter thread is RxCachedThreadScheduler - 1. 226, 27120-27138 / com. Example. RxThread E/wyn: A is 1 2019-01-18 11:03:13. 227, 27120-27120 / com. Example. The RxThread D/wyn: The 2019-01-18 11:03:13 onNext is wang - 1. 227, 27120-27120 / com. Example. The RxThread E/wyn: OnNext thread is the main 11:03:13. 2019-01-18, 229, 27120-27120 / com. Example. The RxThread D/wyn: OnNext is yinan 11:03:13. 2019-01-18, 229, 27120-27120 / com. Example. The RxThread E/wyn: OnNext thread is the main 11:03:13. 2019-01-18, 229, 27120-27120 / com. Example. The RxThread E/wyn: OnComplete 11:03:13. 2019-01-18, 229, 27120-27120 / com. Example. The RxThread E/wyn: the onComplete thread is mainCopy the code

Focus on

Create method is used to easily implement subthread operation (subscribeOn sets subthread type), send content (onNext sends content) to the main thread (observeOn is set to operate in the main thread) update interface.

Fourth, the delay

The most straightforward scenario is that postDelayed() triggers a delayed action. If a postDelayed() operation is performed on a child thread, it cannot be used directly and will crash.

private void testTimer() {
        Observable.timer(3, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this.observer);
    }
Copy the code

Output:

The 2019-01-18 11:31:11. 820, 28231-28231 / com. Example. The RxThread E/wyn: OnSubscribe 11:31:11. 2019-01-18, 820, 28231-28231 / com. Example. The RxThread E/wyn: OnSubscribe thread is the main 11:31:14. 2019-01-18, 832, 28231-28231 / com. Example. The RxThread D/wyn: The 2019-01-18 11:31:14 onNext is 0. 833, 28231-28231 / com. Example. The RxThread E/wyn: OnNext thread is the main 11:31:14. 2019-01-18, 835, 28231-28231 / com. Example. The RxThread E/wyn: OnComplete 11:31:14. 2019-01-18, 835, 28231-28231 / com. Example. The RxThread E/wyn: the onComplete thread is mainCopy the code

Timer can delay operation in child thread, so the output is:

The 2019-01-18 11:33:14. 018, 28398-28419 /? E/wyn: onSubscribe 2019-01-18 11:33:14.019 28398-28419/? E/wyn: onSubscribe thread is the thread - 2 2019-01-18 11:33:17. 026, 28398-28398 / com. Example. The RxThread D/wyn: The 2019-01-18 11:33:17 onNext is 0. 027, 28398-28398 / com. Example. The RxThread E/wyn: OnNext thread is the main 11:33:17. 2019-01-18, 029, 28398-28398 / com. Example. The RxThread E/wyn: OnComplete 11:33:17. 2019-01-18, 030, 28398-28398 / com. Example. The RxThread E/wyn: the onComplete thread is mainCopy the code

Focus on

Timer sets the delay time and then updates the main thread interface.

Five, timing, polling, cycle

General polling interface to obtain data or countdown display content, using TimerTask to achieve, and then using Handler to send Message update interface.

private void testInterval() {
        Observable.interval(3, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this.observer);
    }
Copy the code

Output result:

The 2019-01-18 11:41:42. 108, 29064-29064 /? E/ Wyn: onSubscribe 2019-01-18 11:41:42.108 29064-29064/? E/wyn: onSubscribe thread is the main 11:41:45. 2019-01-18, 115, 29064-29064 / com. Example. The RxThread D/wyn: The 2019-01-18 11:41:45 onNext is 0. 115, 29064-29064 / com. Example. The RxThread E/wyn: OnNext thread is the main 11:41:48. 2019-01-18, 112, 29064-29064 / com. Example. The RxThread D/wyn: OnNext is 1 2019-01-18 11:41:48. 112, 29064-29064 / com. Example. The RxThread E/wyn: OnNext thread is the main 11:41:51. 2019-01-18, 113, 29064-29064 / com. Example. The RxThread D/wyn: The 2019-01-18 11:41:51 onNext is 2. 114, 29064-29064 / com. Example. RxThread E/wyn: OnNext thread is the main 11:41:54. 2019-01-18, 113, 29064-29064 / com. Example. The RxThread D/wyn: OnNext is 3 2019-01-18 11:41:54. 114, 29064-29064 / com. Example. The RxThread E/wyn: onNext thread is the main...Copy the code

Focus on

Interval Specifies the time at which operations are performed on the main thread.

Six, supplement

The observer and observerString used in the test code,

private Observer<Long> observer = new Observer<Long>() {
        Disposable disposable;

        @Override
        public void onSubscribe(Disposable d) {
            Log.e("wyn"."onSubscribe");

            Log.e("wyn"."onSubscribe thread is " + Thread.currentThread().getName());

            disposable = d;
        }

        @Override
        public void onNext(Long s) {
            Log.d("wyn"."onNext is " + s);

            Log.e("wyn"."onNext thread is " + Thread.currentThread().getName());

            tvContent.setText(s + "");

            if (s == 10) {
                disposable.dispose();
            }
        }

        @Override
        public void onError(Throwable e) {
            Log.e("wyn"."onError");

            Log.e("wyn"."onError thread is " + Thread.currentThread().getName());
        }

        @Override
        public void onComplete() {
            Log.e("wyn"."onComplete");

            Log.e("wyn"."onComplete thread is "+ Thread.currentThread().getName()); }}; private Observer<String> observerString = new Observer<String>() { Disposable disposable; @Override public void onSubscribe(Disposable d) { Log.e("wyn"."onSubscribe");

            Log.e("wyn"."onSubscribe thread is " + Thread.currentThread().getName());

            disposable = d;
        }

        @Override
        public void onNext(String s) {
            Log.d("wyn"."onNext is " + s);

            Log.e("wyn"."onNext thread is " + Thread.currentThread().getName());

            tvContent.setText(s);
        }

        @Override
        public void onError(Throwable e) {
            Log.e("wyn"."onError");

            Log.e("wyn"."onError thread is " + Thread.currentThread().getName());
        }

        @Override
        public void onComplete() {
            Log.e("wyn"."onComplete");

            Log.e("wyn"."onComplete thread is "+ Thread.currentThread().getName()); }};Copy the code

Seventh, pay attention to

When selecting child thread operations, use schedulers.io () if there are file operations. Otherwise, Schedulers.computation() is recommended.

Eight, other

Android has a lot of null pointer crashes, according to ummon’s iOS and Android crashes. Why not have a nil type, system-level, to protect global null Pointers? Less broken, more happy!!

// END