Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data change in IntentService

I'm using IntentService for handling my messages from push notification from FCM. It works perfectly as required when the message comes one by one but when the device is not connected to the network and after when device again connected FCM send the bulk of messages at a time and at this scenario service causes some ambiguous while handling intent data which causes unexpected behavior in calling web services.

My push-notification message handler Class :

public class PushMessageHandler extends FirebaseMessagingService {

private final static String TAG = "PushMessageHandler";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    if (remoteMessage.getData() != null){
        Log.d(TAG, String.valueOf(remoteMessage.getData()));
        Intent notificationService = new Intent(this, NotificationService.class);
        notificationService.putExtra(ResponseConstants.NOTIFICATION_FIELD,remoteMessage.getData().get(ResponseConstants.NOTIFICATION_FIELD));
        notificationService.putExtra(ResponseConstants.NOTIFICATION_DATA,remoteMessage.getData().get(ResponseConstants.NOTIFICATION_DATA));
        notificationService.putExtra(ResponseConstants.NOTIFICATION_TYPE,remoteMessage.getData().get(ResponseConstants.NOTIFICATION_TYPE));
        try {
            notificationService.putExtra(ResponseConstants.NOTIFICATION_IMAGE,remoteMessage.getData().get(ResponseConstants.NOTIFICATION_IMAGE));
            notificationService.putExtra(ResponseConstants.NOTIFICATION_TITLE, remoteMessage.getData().get(ResponseConstants.NOTIFICATION_TITLE));
        } catch (Exception e){
            Crashlytics.logException(e);
        }
        try {
            notificationService.putExtra(ResponseConstants.DATASETS,remoteMessage.getData().get(ResponseConstants.DATASETS));
        } catch (Exception e){
            Crashlytics.logException(e);
        }
        startService(notificationService);
    } else {
        Log.d(TAG, "Notification data is null");
    }
  }
}

And my notification handler service class :

public class NotificationService extends IntentService implements NotificationContract.View {

@Inject
public NotificationPresenter mNotificationPresenter;

private NotificationContract.Presenter mPresenter;
private static final String TAG = "NotificationService";
private Intent mIntent;


public NotificationService() {
    super("NotificationService");
}

@Override
protected void onHandleIntent(@Nullable Intent intent) {
    mIntent  = intent;
    DaggerNotificationPresenterComponent.builder()
            .notificationViewModule(new NotificationViewModule(this))
            .remoteDataSourceComponent(MyApplication.getInstance().providesRemoteDataSource())
            .localDataSourceComponent(MyApplication.getInstance().providesLocalDataSource())
            .build().inject(this);
 }

 @Override
 public synchronized void setPresenter(NotificationContract.Presenter presenter) {

this.mPresenter = presenter;

final String notificationField = mIntent.getStringExtra(ResponseConstants.NOTIFICATION_FIELD);
Log.d(TAG, notificationField);

Handler handler = new Handler(getMainLooper());
handler.post(new Runnable() {
    @Override
    public void run() {
        switch (notificationField.trim()){
            case Constants.NOTIFICATION_FIELD_CACHEHOMEFEEDS :
                mPresenter.prefetchData(Integer.parseInt(
                    mIntent.getStringExtra(ResponseConstants.NOTIFICATION_DATA)),
                    new JSONObject(mIntent.getStringExtra(ResponseConstants.DATASETS)));
                break;
            case Constants.NOTIFICATION_FIELD_UPDATEFEEDS :
                mPresenter.getPostDetailById(Integer.parseInt(
                    mIntent.getStringExtra(ResponseConstants.NOTIFICATION_DATA)),
                    new JSONObject(mIntent.getStringExtra(ResponseConstants.DATASETS)));
                break;
            case Constants.NOTIFICATION_FIELD_ARTICLES :
                mPresenter.getPostDetailsPostUrl(mIntent.getStringExtra(ResponseConstants.NOTIFICATION_DATA));
                break;
            case Constants.NOTIFICATION_FIELD_POSTDELETED :
                mPresenter.deleteFeed(Integer.parseInt(
                        mIntent.getStringExtra(ResponseConstants.NOTIFICATION_DATA)));
                break;
        }
    }
});
}

}

In the case of bulk push messages, I'm getting the interchangeable value of NOTIFICATION_DATA i.e the value that I'm expected when notification field is "NOTIFICATION_FIELD_CACHEHOMEFEEDS" is "post: 1234" and for field "NOTIFICATION_FIELD_ARTICLES" is "post: 'post-URL'" but I'm getting "post:1234" for filed "NOTIFICATION_FIELD_ARTICLES", the value is getting interchangeable in any sequence depends on message calling of push notification.

According to the documentation of IntentService handles the requests one by one in queue manner. Then why this happening. Is any method to handle this perfectly.

like image 904
baldraider Avatar asked Aug 28 '17 13:08

baldraider


1 Answers

IntentService -> onHandleIntent is executed on a background thread. If you have time consuming operation you should execute it there. If not - just use normal Service.

Now in onHandleIntent you are injecting presenter multiple times from background thread - i think you should move the injection to the constructor. Then in onHandleIntent call your presenter methods (mPresenter.prefetchData, mPresenter.getPostDetailById etc).

like image 99
yorgo333 Avatar answered Nov 03 '22 04:11

yorgo333