Android manages multiple rxJava requests on rotation device

I am using MVVM for an Android application and I want to manage requests and rxJava while rotating the device, how can I turn off the request after the rotary device and countinue from the last request?

this is my simple code to know how i can do this but i cannot find any document and sample code about it

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    binding = DataBindingUtil.setContentView(this, R.layout.activity_register);
    ...
    Observer<String> myObserver = new Observer<String>() {
        @Override
        public void onError(Throwable e) {
            // Called when the observable encounters an error
        }

        @Override
        public void onComplete() {

        }

        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(String s) {
            // Called each time the observable emits data
            Log.e("MY OBSERVER", s);
        }
    };

    Observable.just("Hello").subscribe(myObserver);
}

I am using the latest version rxJava

+6
source share
5 answers

Rotation processing is a great task for Android. There are several ways to do this.

1- :. . - ui.

2- : - . retainInstanceState true. , .

? retainInstanceState true , .

MVVM, ViewModel , setRetainInstanceState = true

3. Singleton:. , Activity/Fragment .

4- : . , .

: Path Priority Job Queue : https://github.com/path/android-priority-jobqueue

. Google. ( Worker Fragment, .) https://github.com/savepopulation/bulk-action

+3

:

  • - Singleton Application, , .
  • , /

/. , , .

, , , , .

Loaders RxJava, .

+2

Fragment # setRetainInstance (true). , . , Observable - https://github.com/krpiotrek/RetainFragmentSample

0

@Override
public void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
}

, , ,

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if(savedInstanceState == null){
   //saved instance is null
}else{
    //get your stored values here
    counter = savedInstanceState.getInt("value",0); //here zero is the default value
 }
}
0

As I do this, you need to have one-on-one class (or any long live object, as explained earlier with savepopulation, but the trick is to store the loaded data in a BehaviorSubject and subscribe to this object in Activity instead of the original network request .

Thus:

public class MyNetworkSingleton {
  // This static service survives orientation changes
  public static MyNetworkSingleton INSTANCE = new MyNetworkSingleton();

  private final BehaviorSubject<String> dataSubject = BehaviorSubject.create();

  public Observable<String> getData() {
     if (!dataSubject.hasValue()) {
        refreshData(); // No data is loaded yet, load initial data from network
     }

     return dataSubject;
  }

  public void refreshData() {
     someDataSourceCall().subscribe(new Observer<String>() {
       @Override
       public void onError(Throwable e) {
           // Remember, this point also needs error handling of some form,
           // e.g. propagating the error to the UI as a Toast
       }

       @Override
       public void onComplete() {

       }

       @Override
       public void onSubscribe(Disposable d) {

       }

       @Override
       public void onNext(String data) {
          dataSubject.onNext(data); // this refreshes the internally stored data
       }
     });
  }

  private Observable<String> someDataSourceCall() {
     return // some network request here etc. where you get your data from
  }
}

and then:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    Observer<String> myObserver = new Observer<String>() {
        @Override
        public void onError(Throwable e) {
            // Called when the observable encounters an error
        }

        @Override
        public void onComplete() {

        }

        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(String s) {
            // Called each time the observable emits data
            Log.e("MY OBSERVER", s);
        }
    };

    MyNetworkSingleton.INSTANCE.getData().subscribe(myObserver);

    myRefreshButton.setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            // refresh data from network only when button is pressed
            MyNetworkSingleton.INSTANCE.refreshData();
        }
    });
}

Thus, only for the first time you will need data from the network that will be downloaded or when the user clicks the update button ( myRefreshButton).

0
source

Source: https://habr.com/ru/post/1015876/


All Articles