Question

I am loading an HTTP request in the background using loopj HTTP CLIENT and when it is done, I want to display a "success" notification (dialog, toast, etc.)

I have the code in a seperate (non-activity) class with a static method that executes the background request. In the end, the response is in a AsyncHttpResponseHandler under a onSuccess method. In this method, I can print out the response, confirm that the request went through, save data to the sd card/ Shared Preferences, but how do I access the UI thread to display a notification?

Thanks in advance.

Was it helpful?

Solution

you can do it using a Handler, or by calling Activity.runOnUiThread(). so you either pass a Handler, or an Activity object to your static method, then in your onSuccess() method, do,

activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
      // i'm on the UI thread!
    }
  }
);

or,

handler.post(new Runnable() {
    @Override
    public void run() {
      // i'm on the UI thread!
    }
  }
);

OTHER TIPS

I guess you mean a service as a background process. Service has many built in methods like onCreate, onStartCommand, onDestroy, etc. I suggest using a Notification, because notifications do not require a UI thread to do the job.

Create a method to generate a notification and call it after your HTML read is over.

private static void generateNotification(Context context, String message) {
    int icon = R.drawable.ic_stat_gcm;
    long when = System.currentTimeMillis();

    NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
    Notification notification = new Notification(icon, message, when);

    String title = context.getString(R.string.app_name);
    Intent notificationIntent = new Intent(context, MainActivity.class);
    // set intent so it does not start a new activity
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
    notification.setLatestEventInfo(context, title, message, intent);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;

    notificationManager.notify(0, notification);
}

You could fire a local broadcast with the message, and show a toast with a receiver.

Do this in the class doing the updates:

Intent intent = new Intent("ACTION_TOAST");
intent.putExtra("message", "Success!");
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

Then in any activity that might want to know about the update, do this:

BroadcastReceiver receiver = new BroadcastReceiver() {      
    @Override
    public void onReceive(Context context, Intent intent) {
        if ("ACTION_TOAST".equals(intent.getAction()) {
            Toast.makeText(MyActivity.this, intent.getStringExtra("message"), 
                    Toast.LENGTH_SHORT).show();
        }
    }
}

@Override
protected void onStart() {
    super.onStart();
    LocalBroadcastManager.getInstance(this).registerReceiver(
            receiver, new IntentFilter("ACTION_TOAST"));
}

@Override
protected void onStop() {
    LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}

You still need to pass a context into your static method, but this works even if that context is a Service or some other context that can't show Toasts / create UI.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top