Android: How to get context of calling activity in an IntentService?

13,399

Solution 1

how do I get access to MyActivity.this from inside the onHandleIntent method of the IntentService class

You don't.

Move createAd() into the activity. If time is an issue, use an AsyncTask rather than an IntentService.

An IntentService is mostly for cases where you want work to go on decoupled from any activity (e.g., a file download that should continue even if the user leaves your UI to go on to do something else).

Solution 2

It seems to me like you're trying to do bi-directional communication with your Activity and Service. Instead of sending an Intent to your service, consider binding to it instead.

EDIT: Responding to CommonsWare's comments:

Where is the problem with binding to an IntentService? I've shipped apps that work just fine that contain a bound IntentService. You've provided no evidence to back up your claim.

From here:

A service can be both started and have connections bound to it. In such a case, the system will keep the service running as long as either it is started or there are one or more connections to it with the Context.BIND_AUTO_CREATE flag. Once neither of these situations hold, the service's onDestroy() method is called and the service is effectively terminated. All cleanup (stopping threads, unregistering receivers) should be complete upon returning from onDestroy().

The docs clearly indicate that the system supports simultaneous binding and starting. Using an IntentService over a regular Service doesn't change this. Even if you explicitly stop the service after processing an Intent, Android leaves it running as long as something is still bound to it.

Besides, depending on what OP is trying to do, IntentService might no longer be necessary.

Share:
13,399
jamesc
Author by

jamesc

U.K. based developer working with Ruby on Rails, Ruby, Android SDK, Java and passionate about technology. Currently proud to be providing a UK based Ukrainian refugee support group with a rails CMS project Ukrainian refugee project

Updated on June 09, 2022

Comments

  • jamesc
    jamesc almost 2 years

    If I call

    Intent intent = new Intent(ReadingActivity.this, AdService.class);
    startService(intent);       
    

    from within the onCreate method of MyActivity class, how do I get access to MyActivity.this from inside the onHandleIntent() method of the IntentService class

    @Override
    protected void onHandleIntent(Intent arg0) {
        // TODO Auto-generated method stub
        ((BookLib) getApplication()).createAd(I need to pass the calling activities context here);
    }
    
  • CommonsWare
    CommonsWare almost 12 years
    Binding and IntentServices do not go together well. Binding to regular services is fine, and sending commands to IntentServices (via startService()) is fine.
  • jamesc
    jamesc almost 12 years
    Thank you. Guess I need to go research AsyncTask
  • CommonsWare
    CommonsWare almost 12 years
    "Where is the problem with binding to an IntentService?" -- at best, it will only work if you bind first, before calling startService(). Otherwise, you get race conditions where onHandleIntent() completes before the binding occurs, causing the first IntentService instance to be destroyed (via stopSelf()) and the binding to occur on the second one. IMHO, if you think you want to bind to an IntentService, you really should bind to a regular Service and just manage your own background thread.
  • Eric Platon
    Eric Platon about 8 years
    This answer is a good advice in this case---hammer and nail story. Yet, in case you need access the context (perhaps an instance of activity), getApplicationContext() is available. I think that even from an IntentService, there are cases where it makes sense. For example to get system services (e.g. context.getSystemService(Context.ALARM_SERVICE);).