Cannot resolve method 'subscribe(anonymous io.reactivex.Observer<model.TwitterResponse>)' - java

This code was working before but after I update the code, it started showing
Cannot resolve method 'subscribe(anonymous io.reactivex.Observer<model.TwitterResponse>)'
Below is the sample code
public void callTwitterApi(final DisposableObserver observer, String URL, String twitterModel) {
RestClient.getInstance(mActivity).getService().callTwitter(URL,twitterModel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<TwitterResponse>() {
#Override
public void onSubscribe(Disposable d) { }
#Override
public void onNext(TwitterResponse o) {observer.onNext(o); }
#Override
public void onError(Throwable e) { observer.onError(e); }
#Override
public void onComplete() { observer.onComplete();
}
});
}

Related

Calling dispose() when passing a subscriber that overrides onSubscribe

I am new to RxJava and if I understand correctly the Observer is passed the Disposable on the onSubscribe so it can manually stop the processing if the dispose() has already been called.
I created the following code:
#NonNull Observable<Long> src = Observable.interval(1, TimeUnit.SECONDS);
src.subscribe(new Observer<Long>() {
private Disposable d;
#Override
public void onSubscribe(#NonNull Disposable d) {
this.d = d;
}
#Override
public void onNext(#NonNull Long aLong) {
if(!d.isDisposed()) {
System.out.println("Number onNext = " + aLong);
}
}
#Override
public void onError(#NonNull Throwable e) {
}
#Override
public void onComplete() {
System.out.println("completed");
}
});
but I can't figure out how to call dispose() for that subscription. subscribe with passing Observer as an argument returns void and subscribeWith does not accept my Observer without compile errors.
How is this supposed to work? What am I misunderstanding here?
The JavaDocs of Observable has a straightforward example:
Disposable d = Observable.just("Hello world!")
.delay(1, TimeUnit.SECONDS)
.subscribeWith(new DisposableObserver<String>() {
#Override public void onStart() {
System.out.println("Start!");
}
#Override public void onNext(String t) {
System.out.println(t);
}
#Override public void onError(Throwable t) {
t.printStackTrace();
}
#Override public void onComplete() {
System.out.println("Done!");
}
});
Thread.sleep(500);
// the sequence can now be disposed via dispose()
d.dispose();
Edit
The following examples are ways to get the Disposable out of the onSubscribe method but are generally not recommended:
// field in the owner class
Disposable disposable;
public void doReactive() {
Observable<Long> src = Observable.interval(1, TimeUnit.SECONDS);
src.subscribe(new Observer<Long>() {
#Override
public void onSubscribe(#NonNull Disposable d) {
disposable = d;
}
// ...
});
}
public void cleanup() {
if (disposable != null) {
disposable.dispose();
disposable = null;
}
}
or
SerialDisposable sd = new SerialDisposable();
Observable<Long> src = Observable.interval(1, TimeUnit.SECONDS);
src.subscribe(new Observer<Long>() {
#Override
public void onSubscribe(#NonNull Disposable d) {
sd.set(d);
}
// ...
});
// ...
sd.dispose();
You can use the DisposableObserver which can be easily disposed when you are done observing.
#NonNull Observable<Long> src = Observable.interval(1, TimeUnit.SECONDS);
src.subscribe(new DisposableObserver<Long>() {
#Override
public void onNext(#NotNull Long aLong) {
//Do anything you want to do..
dispose();
}
#Override
public void onError(#NotNull Throwable e) {
//Handle the errors here..
dispose();
}
#Override
public void onComplete() {
dispose();
}
});
You can also use CompositeDisposable to dispose many observers at one time, For more details check this out.
https://www.tutorialspoint.com/rxjava/rxjava_compositedisposable.htm

Nested callback is too deep

How to replace nested callbacks (Testing.java) for easy reading like this:
if(isValidGenderID() && isValidReligionID() && isValidMaritalID()){
// DO PRIMARY TASK
}
Nested callbacks are too deep, making the program not easy to read!. How to resolved this problem?
//PersonValidation.java
public static void isValidGenderID(#NonNull Context context, int genderID, final IGenderDataSource.IIsExistGenderIDCallback callback) {
GenderDataSource.getInstance(context).isExistGenderID(genderID, new IGenderDataSource.IIsExistGenderIDCallback() {
#Override
public void onSuccess(boolean result) {
callback.onSuccess(result);
}
#Override
public void onFailure(String result) {
callback.onFailure(result);
}
});
}
public static void isValidReligionID(#NonNull Context context, int religionID, final IReligionDataSource.IIsExistReligionIDCallback callback) {
ReligionDataSource.getInstance(context).isExistReligionID(religionID, new IReligionDataSource.IIsExistReligionIDCallback() {
#Override
public void onSuccess(boolean result) {
callback.onSuccess(result);
}
#Override
public void onFailure(String result) {
callback.onFailure(result);
}
});
}
public static void isValidMaritalID(#NonNull Context context, int maritalID, final IMaritalDataSource.IIsExistMaritalIDCallback callback) {
MaritalDataSource.getInstance(context).isExistMaritalID(maritalID, new IMaritalDataSource.IIsExistMaritalIDCallback() {
#Override
public void onSuccess(boolean result) {
callback.onSuccess(result);
}
#Override
public void onFailure(String result) {
callback.onFailure(result);
}
});
}
// GenderDataSource.java
#Override
public void isExistGenderID(final int ID, #NonNull final IIsExistGenderIDCallback callback) {
Runnable r = new Runnable() {
#Override
public void run() {
db.sqlRawQuery();
callback.onSuccess();
}
};
appExecutors.getLocalDb().execute(r);
}
// ReligionDataSource.java
#Override
public void isExistReligionID(final int ID, #NonNull final IIsExistReligionIDCallback callback) {
Runnable r = new Runnable() {
#Override
public void run() {
db.sqlRawQuery();
callback.onSuccess();
}
};
appExecutors.getLocalDb().execute(r);
}
// MaritalDataSource.java
#Override
public void isExistMaritalID(final int ID, #NonNull final IIsExistMaritalIDCallback callback) {
Runnable r = new Runnable() {
#Override
public void run() {
db.sqlRawQuery();
callback.onSuccess();
}
};
appExecutors.getLocalDb().execute(r);
}
// Testing.java (Nested calls are too deep, making the program not easy to read)
#Override
public void createCustomer(#NonNull final Customer customer, #NonNull final ICustomerDataSource.ICreateCustomerCallback callback) {
//
// isValidGenderID?
//
isValidGenderID(context, customer.getGenderID(), new IGenderDataSource.IIsExistGenderIDCallback() {
#Override
public void onSuccess(boolean result) {
if (result) {
//
// isValidReligionID?
//
isValidReligionID(context, customer.getReligionID(), new IReligionDataSource.IIsExistReligionIDCallback() {
#Override
public void onSuccess(boolean result) {
if (result) {
//
// isValidMaritalID?
//
isValidMaritalID(context, customer.getMaritalID(), new IMaritalDataSource.IIsExistMaritalIDCallback() {
#Override
public void onSuccess(boolean result) {
if (result) {
//
// DO PRIMARY TASK
//
} else {
callback.onFailure("Marital is not valid");
}
}
#Override
public void onFailure(String result) {
callback.onFailure(result);
}
});
//
} else {
callback.onFailure("Religion is not valid!");
}
}
#Override
public void onFailure(String result) {
callback.onFailure(result);
}
});
//
} else {
callback.onFailure("Gender is not valid!");
}
}
#Override
public void onFailure(String result) {
callback.onFailure(result);
}
});
}

Getting error while setting speechRecognition.startListenenig() and pass the intent

I get error when I set SPR.startlistenening() method I want to use continuously speech recognition and perform tasks based on results.
I am making an app that countinuously uses speech recognition and do specific task on results:
#Override
protected void onStart() {
super.onStart();
setSPR();
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,1);
SPR.startListening(intent);
}
private void setSPR() {
if (SpeechRecognizer.isRecognitionAvailable(this)){
SpeechRecognizer.createSpeechRecognizer(this);
SPR.setRecognitionListener(new RecognitionListener() {
#Override
public void onReadyForSpeech(Bundle params) {
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float rmsdB) {
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int error) {
}
#Override
public void onResults(Bundle bundle) {
ArrayList<String> results = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
setRecognitionResults(results.get(0));
}
#Override
public void onPartialResults(Bundle partialResults) {
}
#Override
public void onEvent(int eventType, Bundle params) { }
});
}
}
Error >>>
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.speech.SpeechRecognizer.startListening(android.content.Intent)'
on a null object reference at
com.teamdev.talkingtorch.MainActivity.onStart(MainActivity.java:74) at
android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1341)
at android.app.Activity.performStart(Activity.java:7278) at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2937)

How to Throw an Exception in OnNext using RxJava/RxAndroid

I am using Retrofit for the network call in my android app. Now if the response if something wrong (maybe wrong data), I do not want the onComplete to be executed. Please see the code snippet,
restClient.getService().getProjectDetail(projectId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<List<Project>>() {
#Override
public void onNext(List<Project> value) {
/*Something wrong in the data and I would like to execute onError*/
}
#Override
public void onError(Throwable e) {
handleError(e, 0, "");
hideProgressDialog();
}
#Override
public void onComplete() {
hideProgressDialog();
}
});
Thanks in advance.
Since your end-consumer can crash, the straightforward way is to catch that exception and delegate to onError:
.subscribeWith(new DisposableObserver<List<Project>>() {
#Override
public void onNext(List<Project> value) {
try {
// something that can crash
} catch (Throwable ex) {
// tell the upstream we can't accept any more data
dispose();
// do the error handling
onError(ex);
}
}
#Override
public void onError(Throwable e) {
handleError(e, 0, "");
hideProgressDialog();
}
#Override
public void onComplete() {
hideProgressDialog();
}
});
On a side note, RxJava does pretty much this in its own operators when dealing with potentially failing user functions: try-catch, cancel the source and signal through onError.
You can use flatMap. ex:
restClient.getService().getProjectDetail(projectId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(new Function<Integer, Observable<List<Project>>>() {
#Override
public Observable<List<Project>> apply(List<Project> x) {
if(validate(x)){
return Observable.error(new Exception("Response is invalid"));
}else {
return Observable.just(x);
}
}
public boolean validate(List<Project> x){
return x.size()==0;
}
})
.subscribeWith(new DisposableObserver<List<Project>>() {
#Override
public void onNext(List<Project> value) {
/*Something wrong in the data and I would like to execute onError*/
}
#Override
public void onError(Throwable e) {
handleError(e, 0, "");
hideProgressDialog();
}
#Override
public void onComplete() {
hideProgressDialog();
}
});
example other:
Observable.just(1)
.flatMap(new Function<Integer, Observable<Integer>>() {
#Override
public Observable<Integer> apply(Integer x) {
if(validate(x)){
return Observable.error(new Exception("Response is invalid"));
}else {
return Observable.just(x);
}
}
public boolean validate(Integer x){
return x==1;
}
})
.subscribe(new Observer<Integer>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onComplete() {
}
#Override
public void onError(Throwable e) {
Log.e("ERROR", e.getMessage());
}
#Override
public void onNext(Integer integer) {
Log.d("flatMap", "onNext: " + integer.toString());
}
});
You are questioning the basic behaviour of rx-java. if you want call hideProgressDialog only once. you should delete that from onError. the sequence must destroy after problem.
but if you want to get other items in onNext and avoid onError you can use this method on your observable chain:onErrorResumeNext
restClient.getService().getProjectDetail(projectId).onErrorResumeNext(/*Func1*/)
consider this method will emit List<Project> in onNext instead of onError. and onComplete would not call
as long as you use retrofit the onNext only will invoke one times. so the better solution is the first one

Retrofit 2 Observable in RxJaxa 1: How to convert to RxJava 2

I was using this code in Retrofit and Rx Java 1 to return an observable from a Retrofit call like this:
mCompositeSubscription.add(
ServiceFactory.createRetrofitService().setLike(mediaId,sessionMgr.getAuthToken())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ResponseBody>() {
#Override
public final void onCompleted( ) {}
#Override
public final void onError(Throwable e) {
userMessageHandler.showDialog(mParentActivity,mParentActivity.getString(R.string.error_setting_data_title),
mParentActivity.getString(R.string.error_set_like_msg) + e.getMessage(),0);
}
#Override
public void onNext(ResponseBody response) { }
})
);
I can't figure out how to convert it to RX Java 2. I have come up with this but not sure it is right:
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableObserver<User>(){
#Override
public void onNext(User user) {
authMgr.setUser(user);
}
#Override
public void onError(Throwable t) {
mProgressDlg.dismiss();
alertDlg.showIt(mResources.getString(R.string.err_register),
t.getMessage(), "",
"", mParentActivity, JAlertDialog.POSITIVE,null);
}
#Override
public void onComplete() { }
});
You should be able to use the RxJava2 adapter in retrofit. This will allow you to have your Retrofit API return RxJava2 types.
Here's a solid example: https://medium.com/3xplore/handling-api-calls-using-retrofit-2-and-rxjava-2-1871c891b6ae
I came up with this but I'm still testing...
mCompositeDisposable.add( ServiceFactory.createRetrofitService().registerNewUser(BuildConfig.CLIENT_KEY, data.email,
data.fname, data.lname, data.birthday,data.city,
data.state, mAvatarUrl, coords, Long.toString(mSessionId) ,
data.pwd, layerMgr.getNonce() )
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<User>(){
#Override
public void onNext(User user) {
}
#Override
public void onError(Throwable t) {
mProgressDlg.dismiss();
alertDlg.showIt(mResources.getString(R.string.err_register),
t.getMessage(), "",
"", mParentActivity, JAlertDialog.POSITIVE,null);
}
#Override
public void onComplete() { }
}));

Categories

Resources