androidotto

Using Ottos bus for 'notification polling'


On all my views I have an icon that will have a red dot if the user has notifications, so I created a class to constantly (every few minutes) poll and see if they have notifications. Except the @Subscrtibe is never getting triggered. One thing that I thought would maybe be the cause is that I start the post before the HomeActivity is registered but with the timer I didn't think that would be a problem?

public class NotificationUtils {

    private static Timer timer;

    private static final int MINUTES = 1000 * 60;
    private static Context applicationContext;

    public static void startTask(Context context){
        checkNotifications();
        applicationContext = context;
        timer = new Timer();
        timer.schedule(task, 0L, MINUTES);
    }

    public static void killTask(){
        timer.cancel();
        timer.purge();
    }

    static TimerTask task = new TimerTask() {
        @Override
        public void run() {
            checkNotifications();
        }
    };

    private static void checkNotifications(){
        RestInterface service = RestService.getRequestInstance(applicationContext);
        Call<Boolean> call = service.hasNotificatrions(SessionUser.getInstance().getUser().getId());
        call.enqueue(new Callback<Boolean>() {
            @Override
            public void onResponse(Call<Boolean> call, Response<Boolean> response) {
                sendNotificationImage(response.body());
            }

            @Override
            public void onFailure(Call<Boolean> call, Throwable t) {
                Log.w("TimerTask", "Failed");
            }
        });
    }

    private static void sendNotificationImage(boolean hasUnreadNotifications){
        if(hasUnreadNotifications) {
            BusProvider.getInstance().post(R.drawable.notification_alert_icon); 
        } else { 
            BusProvider.getInstance().post(R.drawable.notification_icon);
        }
    }
}

When a user successfully logs in, I start the polling...

public class LoginActivity extends AppCompatActivity {
    ....
    successfulLogin(){
        ....
        NotificationUtils.startTask(getApplicationContext());
    }
}

Then my HomeActivity I register the class and subscribe..

public class HomeActivity extends AppCompatActivity {
    ....
    @Override
    protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_home);
         BusProvider.getInstance().register(this);
    }
    ....
    @Subscribe
    public void setNotification(int imageResource){
         notificationButton.setImageResource(imageResource); 
         Log.w("HomeActivity", "Setting resource"); 
    }
}

Edit.. Adding BusProvider class

public final class BusProvider {
    private static final Bus bus = new Bus();

    public static Bus getInstance(){
        return bus;
    }

    private BusProvider(){}
}

Solution

  • You should NOT use Java primitive types as event classes. You can use:

    public class DisplayNotification {
        private int resourceId
    
        public DisplayNotification(int resourceId){
            this.resourceId = resourceId;
        }
    
        public int getResourceId(){
            return this.resourceId;
        }
    }
    

    change your function signature to be

    @Subscribe
    public void setNotification(DisplayNotification event){...}
    

    and post it like this:

    BusProvider.getInstance().post(new DisplayNotification (R.drawable.notification_icon));