When my app is in the process of resuming, it crashes inside Android framework code . I am unable to reproduce the crash and am only aware of it through crash reporting. Furthermore, the crash occurs on Android 7, 8, 9 and is spread among many manufacturers.
Here is the stacktrace for the android.os.RemoteException
which causes the crash:
com.android.server.am.ActivityManagerService.isTopOfTask(ActivityManagerService.java:14764) at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2417) at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3346) at android.os.Binder.execTransact(Binder.java:731)
The above exception was triggered by my Activity
's super.onResume()
call which then raised an IllegalArgumentException
at
android.os.Parcel.createException + 1970 (Parcel.java:1970)
androidx.fragment.app.FragmentActivity.onResume + 514 (FragmentActivity.java:514)
Finally, the above exception was caught as a RuntimeException
since the system was unable to start the app. Here's the last stacktrace:
android.app.ActivityThread.performResumeActivity + 4015 (ActivityThread.java:4015)
com.android.internal.os.ZygoteInit.main + 965 (ZygoteInit.java:965)
No code is ran inside my onResume
functions besides a call to super
.
I tried backgrounding/foregrounding the app in the offending Activity
while limiting background processes and "Don't keep Activities" turned on, but I could not reproduce the crash.
Does anyone have suggestions for reproducing the crash?
Here is code showing how the Service
is started:
@Singleton
class ExoplayerManager @Inject constructor(
@Application private val context: Context,
...
) : CastManager.CastEventListener {
private fun startService() {
lecture?.let {
val intent = ExoplayerService.createIntent(context, it.generateCompositeIdObject())
logd { "[ExoplayerService] startForegroundService called" }
ContextCompat.startForegroundService(context, intent)
}
}
}
Here is code shutting down the Service
public class ExoplayerService extends Service {
public static Intent createIntent(Context context, LectureCompositeId id) {
Intent intent = new Intent(context, ExoplayerService.class);
intent.putExtra(EXTRA_LECTURE_COMPOSITE_ID, (Parcelable) id);
return intent;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String action = null;
LectureCompositeId lectureCompositeId = null;
if (intent != null) {
action = intent.getAction();
lectureCompositeId = intent.getParcelableExtra(EXTRA_LECTURE_COMPOSITE_ID);
}
L.leaveBreadcrumb(TAG, "onStartCommand >> startId: " + startId + " flags: " + flags +
" intent: " + intent + "action: " + action + " lectureCompositeId: " + lectureCompositeId);
// Actions are send by Notification and lock screen controls as intent params
if (intent != null) {
if (ACTION_SHUTDOWN.equals(action) || ACTION_SHUTDOWN_TASK.equals(action)) {
boolean fromNotification = intent.getBooleanExtra(EXTRA_SOURCE_NOTIFICATION, false);
attemptShutdown(startId, fromNotification, ACTION_SHUTDOWN_TASK.equals(action));
} else if (StringUtils.isNotBlank(action)) {
exoplayerManager.ensureLecture(lectureCompositeId);
handleNotificationMediaButtonAction(action);
} else {
initPlayerService();
}
}
return START_STICKY;
}
/**
* Queue a shutdown of the service. Ensures requests that need a notification have a chance to process.
*/
private void queueShutdown(boolean taskRemoved) {
Intent shutdown = new Intent(this, ExoplayerService.class);
if (taskRemoved) {
shutdown.setAction(ACTION_SHUTDOWN_TASK);
} else {
shutdown.setAction(ACTION_SHUTDOWN);
}
startService(shutdown);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
// other methods
}