Search code examples
androidappcompatactivity

Parcel.readException for Android 6.0-7.1


Since December 12th, I've been having a ridiculous number of these errors. I don't believe I've changed anything significant, and I may attribute this to a potential update in AppCompat libraries. The following is one of the logs:

 java.lang.IllegalArgumentException: 
  at android.os.Parcel.readException (Parcel.java:1603)

  at android.os.Parcel.readException (Parcel.java:1552)

  at android.app.ActivityManagerProxy.isTopOfTask (ActivityManagerProxy.java:4986)

  at android.app.Activity.isTopOfTask (Activity.java:5731)

  at android.app.Activity.cancelInputsAndStartExitTransition (Activity.java:4049)

  at android.app.Activity.startActivityForResult (Activity.java:4026)

  at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult (BaseFragmentActivityApi16.java:54)

  at android.support.v4.app.FragmentActivity.startActivityForResult (FragmentActivity.java:67)

  at android.app.Activity.startActivity (Activity.java:4294)

  at android.support.v4.content.ContextCompat.startActivity (ContextCompat.java:143)

There have been a few other Stack Overflow questions with this issue, but they typically have an actual message from the exception. The most common result was an incompatibilty with AppCompatActivity calls and Activity calls.

Though all of my activities are based off of AppCompat, I have made sure to call things with startActivity, and to have animations from the ActivityOptions vs its compat counterpart.

Anyone have any ideas?

If source code is necessary, my project is completely open source. Anything not in there is in my other library.

I never ended up being able to replicate the error myself, but it seems like the issue occurs predominantly on Samsung and Motorola devices.


Relevant Code Snippets:

The crashes occur in my MainActivity and my LoginActivity, so it's the first activity transition for the user.

Base theme:

<style name="FrostThemeBase" parent="MaterialDrawerTheme.ActionBar">
    <item name="colorPrimary">@color/facebook_blue</item>
    <item name="colorPrimaryDark">@color/facebook_blue_dark</item>
    <item name="colorAccent">@android:color/white</item>
    <item name="android:windowSoftInputMode">adjustResize</item>
</style>

<style name="FrostTheme" parent="@style/FrostThemeBase">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

Where MaterialDrawer extends an AppCompat theme.

One difference I have from most applications is that I support dynamic and transparent themes:

fun Activity.setFrostTheme(forceTransparent: Boolean = false) {
    val isTransparent = (Color.alpha(Prefs.bgColor) != 255) || forceTransparent
    if (Prefs.bgColor.isColorDark)
        setTheme(if (isTransparent) R.style.FrostTheme_Transparent else R.style.FrostTheme)
    else
        setTheme(if (isTransparent) R.style.FrostTheme_Light_Transparent else R.style.FrostTheme_Light)
}

For starting activities, I have the following helper method:

inline fun <T : Activity> Context.startActivity(
        clazz: Class<T>,
        clearStack: Boolean = false,
        bundleBuilder: Bundle.() -> Unit = {},
        intentBuilder: Intent.() -> Unit = {}) {
    val intent = Intent(this, clazz)
    if (clearStack) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
    intent.intentBuilder()
    val bundle = Bundle()
    bundle.bundleBuilder()
    startActivity(intent, bundle)
    if (clearStack && this is Activity) finish()
}

In short, for Login, the stack will be cleared by setting the clear task and new task flags, and the activity will be finished. I realize now that I do pass an empty bundle by default, so that may potentially be an issue.

There are some other differences such as custom activity transitions for some activity, though I don't think that's an issue as there are activities without it that crash as well.


Solution

  • This has been quite a while, but I believe the error was that the bundleBuilder function was sometimes empty, resulting in an empty Bundle being passed. The solution is to take the bundle only if it is non empty, or use null otherwise.

    This problem seems like it was specific to certain Samsung devices.