0

I struggle resolving a crash which either comes from my own bad implementation due to missing knowledge or from AOSP code (less likely I think...). It seems to only occurs on Android 13 and I got it mainly on Samsung devices (Galaxy S23+/S22+/S22 Ultra/S21 FE 5G) I don't own (happened also 1 time on OPPO Reno5, Xiaomi 12 & Xiaomi 11T). Here is the stacktrace:

Non-fatal Exception: java.lang.NullPointerException
Attempt to invoke virtual method 'com.android.server.wm.ActivityRecord com.android.server.wm.WindowContainer.getActivity(java.util.function.Predicate)' on a null object reference
android.os.Parcel.createExceptionOrNull (Parcel.java:3029)
android.os.Parcel.createException (Parcel.java:3007)
android.os.Parcel.readException (Parcel.java:2990)
android.os.Parcel.readException (Parcel.java:2932)
android.app.IActivityTaskManager$Stub$Proxy.startActivities (IActivityTaskManager.java:2816)
android.app.Instrumentation.execStartActivitiesAsUser (Instrumentation.java:1876)
android.app.Instrumentation.execStartActivities (Instrumentation.java:1823)
android.app.Activity.startActivities (Activity.java:6096)
android.app.Activity.startActivities (Activity.java:6069)
.SplashActivity.startMain (SplashActivity.java:149)

I already searched in AOSP code to understand how the WindowContainer could be null in IActivityTaskManager.startActivities which implementation seems to be ActivityTaskManagerService.startActivities but it's hard to navigate deep into the AOSP code... Also I tried to search for WindowContainer.getActivity usage but cross-references does not seem to work for this file... I also cloned the repository through the repo cmd as per the doc but I did not find the files... So I'm stuck :/

I have implemented a SplashActivity handling main launcher intent and any background notification and deep link clicks launching the correct activity or stack. I got only the crash when I need to launch the list -> details stack.

Here is its minimal comprehensive code:

public final class SplashActivity {
    private boolean resumed;

    @Override
    protected void onStart() {
        super.onStart();

        fetchAsyncData(SplashActivity::onDataFetched())
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();

        resumed = true;
    }

    @Override
    protected void onPause() {
        super.onPause();

        resumed = false;
    }

    public void onDataFetched() {
        String res1, res2;
        // some code to parse either a deep link or background notification, ending in populated res1 & res2 or not
        // do not start any activity if not resumed (user goes back to home/other app/kills the app)
        if (resumed) {
            if (res1 != null && res2 != null) {
                Intent intent = getIntent();
                Bundle extras = intent.getExtras();

                Intent listIntent = new Intent(this, ListActivity.class);
                // forward extras/flags to new root intent
                listIntent.putExtras(extras != null ? extras : new Bundle());
                listIntent.addFlags(intent.getFlags());

                Intent detailsIntent = new Intent(this, DetailsActivity.class);
                detailsIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                detailsIntent.putExtra("res1", res1);
                detailsIntent.putExtra("res2", res2);

                startActivities(new Intent[]{listIntent, detailsIntent});
                finish();
            }
            else {
                // start other activities
            }
        }
    }
}

And here is how SplashActivity, ListActivity and DetailsActivity are declared in the AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <application>
        <activity
            android:name=".SplashActivity"
            android:launchMode="singleInstance"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter android:autoVerify="true" tools:targetApi="m">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data
                    android:scheme="https"
                    android:host="example.com"
                    android:pathPattern="/res1/.*/res2/.*" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ListActivity"
            android:exported="true"
            android:launchMode="singleTop" />
        <activity
            android:name=".DetailsActivity"
            android:launchMode="singleTop"
            android:exported="true"
            android:parentActivityName=".ListActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".ListActivity" />
        </activity>
    </application>
</manifest>
Doc_1faux
  • 141
  • 5
  • 15

0 Answers0