I am talking about that feature (taken from desktop Os's) where you have several applications displayed on one screen.
Check out how these guys do it: http://www.onskreen.com/cornerstone (their solution was also supposed to be adopted by CyanogenMod a while ago).
I am sure there is still a lot of work ahead for the guys at Samsung etc. making their solution a little more user-friendly for mobile devices, but what I want to talk about is Google's own solution.
This new Android feature has been around for a while, but no one seems to care (you'll see why shortly). Somehow this newAPI seems to go unnoticed.
I only noticed it when I was comparing Kitkat's ActivityManagerService.java to JB's. I was wondering what these methods: createStack, resizeStackBoxand getStackswere all about so I started digging.
A full explanation about how Kitkat's ActivityManagerServiceand WindowsManagerServiceinteract is beyond the scope of this post.
I can only say two things:
I am only doing this for my own convenience. What the ActivityManagerService refers to as a stack is actually a different type of object.
I started with a clean emulator and launched the Email app followed by the People app.
# am stack boxes
Pay attention to the output. You will notice that there are actually 2 activity stacks. Unlike JB, where there was one ActivityStack, in Kitkat we have 2:
In order to split the screen, all I had to do was:
# am stack create 3 2 4 0.5
And this is the result:
This new Android feature has been around for a while, but no one seems to care (you'll see why shortly). Somehow this newAPI seems to go unnoticed.
I only noticed it when I was comparing Kitkat's ActivityManagerService.java to JB's. I was wondering what these methods: createStack, resizeStackBoxand getStackswere all about so I started digging.
A full explanation about how Kitkat's ActivityManagerServiceand WindowsManagerServiceinteract is beyond the scope of this post.
I can only say two things:
- Since 4.4, there is more interaction between these two services (the WindowManagerService became stack-aware).
- This interaction is still far from finished (i.e. this split screen solution is not working properly yet - but it is a small step in the right direction).
I am only doing this for my own convenience. What the ActivityManagerService refers to as a stack is actually a different type of object.
I started with a clean emulator and launched the Email app followed by the People app.
# am stack boxes
Pay attention to the output. You will notice that there are actually 2 activity stacks. Unlike JB, where there was one ActivityStack, in Kitkat we have 2:
- HOME stack: This is the stack with id = 0. This stack is used by the Launcher activities. When several users run Lanchers on one device, they will all belong to this stack. Other than that, systemui activities are also launched in it.
- Applications stack: The id for this stack could be any number. All activities that are neither Launcher apps or systemui activities are run here (for all users).
In order to split the screen, all I had to do was:
# am stack create 3 2 4 0.5
And this is the result:
Figure 1 - People and Email apps share one screen |
Syntax: am stack create <int1> <int2> <int3> <float1>
- <int1>: TASK_ID - the id for the existing task that you want a separate stack for.
- <int2>: RELATIVE_STACK_BOX_ID - an existing stack id. The postion of the new stack will be relative to this one.
- <int3>: POSITION - the relative position of the stack. Could be any one of these values:
- 0: before relative stack (depends on RTL/LTR configuration)
- 1: after relative stack (depends on RTL/LTR configuration)
- 2: to left of relative stack
- 3: to right of relative stack
- 4: above relative stack
- 5: below relative stack
- 6: displayed on a higher layer than the relative stack (unused)
- 7: displayed on a lower layer than the relative stack (unused)
- <float1>: WEIGHT - a number between 0.2 - 0.8 inclusive
If instead of 0.5 for weight, I used 0.7 as weight, this would be the result:
Figure 2- 70% of the screen is taken by Email app |
As you can see in Figure 2, the weight parameter controls the relative amount of space each stack box takes up on the screen.
Problems
I haven't described the entire user feature set (you can also resize a stack and change tasks order inside a stack). However, I will not describe this since, at this point, when you try it at home you are likely to be disappointed. Why?
- These features are a hidden API. Writing your own app to tweak these features requires reflection.
- Even worse, the permissions required for this are with a permissionLevel of type 'signature'. So unless you are building your own ROM, or you have your ROM's signature you can't do this with your own app.
- If you decide to use am on your device, then you must run it as a super-user. This means the device must be rooted (I described below another thing you should do if you choose this approach)
- Most importantly, it doesn't work that well. You will need to take several shots at this before it works right for you.
Figure 3 - This is what happened when I tried to split the Launcher stack (HOME stack) |
If anyone wants to try the am commands on a rooted device, he'd be surprised to find out that the am command does not print anything to the screen when it is run with 'su'.
So before yo try anything, run this command:
# setprop log.redirect-stdio true
this way you can see what am prints in the logcat.
# setprop log.redirect-stdio true
this way you can see what am prints in the logcat.