Multi-Window, and Multi-Instance, Like It or Not

Due to the way that multi-window modes in Android are implemented, third-party app developers can cause your app to behave in ways that you might not expect. In particular, third-party developers can:

Cause 2+ instances of your exported activities, like your launcher activity, to run simultaneously in multiple windows

Cause your non-resizeable exported activity to appear in a window, even though you are trying to avoid this by using android:resizeableActivity="false"

How do I know this? Because I did it myself, in response to seeing reports of this sort of thing hitting the Play Store.

In a couple of hours, I cobbled together Sidecar. The user can pick a supported launcher activity from apps on the device, then add a “Sidecar” tile to their notification shade. Tapping the tile will launch their chosen activity in a separate window (assuming that the device is already in split-screen mode). This works even if there is already an instance of one of your activities in another window, and this works even if you are trying to avoid multi-window mode via android:resizeableActivity="false" .

Sidecar has lots of usability warts. After all, I only spent a couple of hours on it. However, it illustrates the situation.

I have no idea if these capabilities are intentional. Outside of accessing one hidden field via reflection, my code uses stock API capabilities, and that reflection is helpful but not essential. Heck, Sidecar doesn’t even need any permissions, let alone scary ones. So, I don’t know if this sort of stuff was part of the plan, whether it is an accident of the APIs, or something else.

Ideally, your activities are fairly self-contained and make few assumptions about the world around them, such that if more than one instance winds up on-screen at once, the activities can survive without crashing. And, ideally, all of your activities are resizeable. This is not an ideal world, and so it will not be shocking if you decide that some of your activities fail on one or both of these counts. In fact, the big reason I wrote Sidecar is so people can understand a bit more how their apps behave when used this way.

Activities that cannot support these things may require some adjustments to block multi-instance and forced-resize scenarios. Having singleTask or singleInstance for android:launchMode on the <activity> breaks Sidecar, which is why I filter them out of the list of Sidecar-supported apps that users can choose from. There may be other ways that block these features as well.

The fact that some power users wind up with apps like Sidecar is not that big of a deal. Even if some popular home screen replacements and utility apps start offering this sort of capability, they still only affect a tiny percentage of the Android user base. What worries me is the possibility that device manufacturers might start offering these features. And even then, the “worry” is more about unexpected app behavior than security concerns.

In summary:

Consider testing your app where more than one instance of your activities are visible at a time, to see if that causes problems

If you get crash reports from the field with a seemingly-impossible scenario (“it’s like Activity X is in both State Y and State Z at the same time!”), Sidecar-style multi-instance behavior may be the source of the problem

Try really really hard to allow all of your activities to be resizeable, since they may be resizeable whether you like it or not

Hope that this all works out

Stuck on an Android problem? Subscribers have access to live office hours chats with Mark Murphy, to help you work through your challenges!

— Sep 12, 2016