I'm implementing an MVP architecture with Retrofit, and RxJava2 (with RxAndroid). I have the following setup
NetworkInterface.java
where retrofit calls lie
public interface NetworkInterface {
@GET("/input")
Single<List<InformationData>> getInfoData();
}
InformationDataDao.java
Data access layer for the information data
@Dao
public interface InformationDataDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
Completable createInfoData(List<InformationData> infoData);
}
MainPresenter.java
where the calls are being made public class MainPresenter {
public MainPresenter() {
}
// Method called to initialize the subscription
@Override
public void subscribe() {
this.collectInfoData();
}
private void collectInfoData() {
Single<List<InformationData>> singleInfoData = networkInterface.getInfoData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
singleInfoData.subscribe(informationDatas -> {
InformationDataDao informationDataDao = database.informationDataDao();
informationDataDao.createInfoData(informationDatas);
// What made me detect that this was being called twice
Log.d(Constant.LOG_TAG, "Info Data: " + informationDatas.size());
// Rest of the code here
}, Throwable::printStackTrace);
}
}
SplashActivity.java
The method that calls the presenter
public class SplashActivity extends AppCompatActivity {
// Helps in getting the location
private FusedLocationProviderClient locationClient;
private SplashPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_splash);
mPresenter = new SplashPresenter();
}
@Override
protected void onResume() {
super.onResume();
// These three lines ensure that you have the appropriate permissions to proceed. In the third line for instance, the user will be navigated out to the settings pane to turn on location.
// When he/she returns to the activity, the onResume is called so I'm assuming that's the best place to start the presenter
this.ensureHasPermissions();
boolean isGoogleServiceAvailable = this.ensureGoogleServiceAvailability();
boolean isLocationServiceAvailable = this.ensureLocationServiceAvailable();
if (isLocationServiceAvailable && isGoogleServiceAvailable) {
locationClient.getLastLocation()
.addOnSuccessListener(this, location -> {
// Set the closest location and subscribe
presenter.setClosestLocation(location);
presenter.subscribe();
})
.addOnFailureListener(this, Throwable::printStackTrace);
}
}
}
From the SplashPresenter.java
, the log is printed twice, indicating that the complete callback was called twice. Is there any idea why this may be so? I'm quite new to RxJava2 and will greatly appreciate the feedback.
Thanks.
collectInfoData()
also getting called twice. You can put a log in the ` subscribe()` method, and verify only once it callscollectInfoData
Log.d(Constant.LOG_TAG, "Info Data: " + informationDatas.size());
this log is getting called twice right?singleInfoData.subscribe
is getting called twice?subscribe()
might be getting called twice, as a result you are getting 2 calls tothis.collectInfoData();
which will end up in creating the entire Rx chain twice. You can verify that it once by butting a log atsubscribe()
method and how many times it is getting printed