2017-02-19 40 views
5

Chcę zastąpić mój AsyncTask z RxJava w Androidzie. Mój obecny AsyncTask idzie tak:Chcę użyć paska postępu z RxJava, jak to możliwe z AsyncTask

public class ProgressBarAsyncTask extends AsyncTask<Void,Void,Void> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     ringProgressDialog = ProgressDialog.show(context,"MyProgressBarTitle","Working please wait",true, false);     
    } 

    @Override 
    protected Void doInBackground(Void... void) { 
     //do work 
     myTask(); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void void) { 
     super.onPostExecute(); 
     ringProgressDialog.dismiss(); 
    } 
} 

Oto moja wymiana RxJava:

public static Observable<Void> getObservable(final Context context,final String... params) { 

     return Observable.defer(new Func0<Observable<Void>>() { 
      @Override 
      public Observable<Void> call() { 
      return Observable.just(myTask()); 
      } 
     }); 

    } 

    public static Subscriber<Void> getSubscriber() { 
    Subscriber<Void> subscriber = new Subscriber<Void>() { 
     @Override 
     public void onCompleted() { 
      ringProgressDialog.dismiss(); 

     } 

     @Override 
     public void onError(Throwable e) { 
      Log.d(TAG,e.toString()); 

     } 

     @Override 
     public void onNext(Void aVoid) { 
      manipulateData(); 

     } 
    }; 
    return subscriber; 
} 

mój aktywny:

public class MainActivity extends Activity { 
    private ProgressDialog ringProgressDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     GetNumberObservable.Observable() 
         .subscribeOn(Schedulers.io()) 
         .observeOn(AndroidSchedulers.mainThread())) 
         .subscribe(getSubscriber()); 
    } 
} 

Jak mogę naśladować metody onPreExecute() w AsyncTask gdzie wywołać progressDialog?

+0

Użyj metody doOnNext() – Tuby

+0

@Tuby Jak to zrobić? –

+0

wyszukaj tę klasę https://github.com/TwistedEquations/android-rxmvp-tutorial/blob/master/app/src/main/java/com/twistedeqations/rxmvp/sample/activities/home/mvp/HomePresenter.java, używa doOnNext do ustawienia showLoading na true, co włącza pasek postępu, możesz wywołać ringProgressDialog.show() w tej metodzie. – Tuby

Odpowiedz

3
  • W RxJava masz do operatorów, które tworzy Observable wydarzenia cyklu życia słuchaczy, w przypadku, gdy chcesz zrobić coś (zaktualizować UI) przed rozpoczęciem zadania, co oznacza chcesz zdarzenie doOnSubscribe. (Marginesie to prawda, ze „na zimno” obserwable który rozpoczął thier pracy podczas subscrbied do - jak Twoim przypadku) Wystarczy uważaj zadzwonić .observeOn(AndroidSchedulers.mainThread())) przed doOnSubscribe, aby otrzymywać powiadomienia o mainThread, jak jesteś aktualizowanie Interfejs użytkownika.
  • Zamiast używać zarówno defer i just

    return Observable.defer(new Func0<Observable<Void>>() { 
        @Override 
        public Observable<Void> call() { 
         return Observable.just(myTask()); 
        } 
        }); 
    

    można użyć fromCallable:

    Observable.fromCallable(new Callable<Object>() { 
         @Override 
         public Object call() throws Exception { 
          return myTask(); 
         } 
        }) 
    
1

Oto jak zrobiłbym to:

public final class ProgressOrResult<T> { 
    final int progress; 
    final T result; 
    public ProgressOrResult(int progress, T result) { 
     this.progress = progress; 
     this.result = result; 
    } 
} 

ProgressDialog ringProgressDialog = ProgressDialog.show(
    context, "MyProgressBarTitle", "Working please wait", true, false);     


Observable.fromEmitter((Emitter<ProgressOrResult> emitter) -> { 
    // generate "progress" 
    int sum = 0; 
    for (int i = 1; i <= 100; i++) { 
     sum += i; 
     emitter.onNext(new ProgressOrResult(i, null)); 
     Thread.sleep(1); 
    } 
    // generate "result" 
    emitter.onNext(new ProgressOrResult(100, sum)); 
    emitter.onComplete(); 

}, BackpressureMode.BUFFER) 
.subscribeOn(Schedulers.io()) 
.observeOn(AndroidSchedulers.mainThread()) 
.subscribe(result -> { 
    if (pr.result == null) { 
     ringProgressDialog.setProgress(pr.progress); 
    } else { 
     ringProgressDialog.dismiss();   

     // process the result here 
    } 
}, error -> { 
    // handle error here 
}) 
0

Shameless Promotion

Utworzyłem RxLoading library za to, to może to zrobić i dużo więcej,

można po prostu zrobić coś takiego:

networkCall().compose(RxLoading.<>create(loadingLayout)).subscribe(...); 

składa się z 2 klas , niestandardowy widok (loadingLayout) i RxLoading, który jest transformer, który skleja wszystko razem, możesz wybrać pracę z jednym lub dwoma z nich. Jeśli chcesz RxLoading z prostym paskiem postępu, wystarczy zaimplementować interfejs i gotowe.

możesz sprawdzić więcej na GitHub page.