Is the thread in the onReceive method eligible for garbage collection before it ever completes?
@Override
public void onReceive(final Context context, Intent intent) {
final int alarmId = intent.getExtras().getInt(EXTRA_ALARM_ID);
Log.i(TAG, "/onReceive with an alarmVo.id of " + alarmId);
// RUN MY THREAD
new Thread(new Runnable() {
@Override
public void run() {
AlarmUtil.setNextAlarm(context, alarmId);
}
}).start();
}
From what I understand from here: http://developer.android.com/reference/android/content/BroadcastReceiver.html it is, but I'm not quite sure.
"anything that requires asynchronous operation is not available, because you will need to return from the function to handle the asynchronous operation, but at that point the BroadcastReceiver is no longer active and thus the system is free to kill its process before the asynchronous operation completes. "
If it gets garbage collected, then how do I work around this? What should be my approach?
Retrieve the current result extra data, as set by the previous receiver. This can be called by an application in onReceive(Context, Intent) to allow it to keep the broadcast active after returning from that function.
When a broadcast message arrives for the receiver, Android calls its onReceive() method and passes it the Intent object containing the message. The broadcast receiver is considered to be active only while it is executing this method. When onReceive() returns, it is inactive.
Receiving components of the broadcast intent will need to inherit from a Receiver class available in the Android SDK. These receiving components (broadcast receivers) then need to be registered in the manifest file as a receiver that is interested in the broadcast intent.
No. Any Thread object that has been started via the start() method that has not yet completed acts as a garbage-collection root... neither it nor anything it strongly references is eligible to be garbage collected until its run() method completes.
See also these answers:
EDIT:
Now that you've added additional context to your question things are a bit clearer. The problem is this case is something entirely different than garbage collection. In the case of a statically published BroadcastReceiver (defined in an application's manifest with the <receiver>
tag), Android is free to kill its process after onReceive(Context, Intent)
returns. Your async operation wouldn't stop due to a GC, it would stop due to Android killing the process that is hosting it.
As for your approach, it all depends on what you are trying to accomplish. If the code you want to execute in your BroadcastReceiver can be ran synchronously then that would be the easiest approach. I'm assuming that isn't possible though. In that case, this portion of the docs seems to apply (emphasis mine):
Once you return from onReceive(), the BroadcastReceiver is no longer active, and its hosting process is only as important as any other application components that are running in it. This is especially important because if that process was only hosting the BroadcastReceiver (a common case for applications that the user has never or not recently interacted with), then upon returning from onReceive() the system will consider its process to be empty and aggressively kill it so that resources are available for other more important processes.
This means that for longer-running operations you will often use a Service in conjunction with a BroadcastReceiver to keep the containing process active for the entire time of your operation.
So, either run your receiver code synchronously or use a Service to keep your asynchronous operation alive long enough to complete.
(Of course this all applies only if you are statically registering your receiver in an otherwise inactive app. If you are dynamically registering it from within some other active component (say, an Activity), then that component could manage your async operation. See this answer for more info on that.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With