Issue
I have a weird problem.
Before you come to an idea to lash out on me, I am working on a custom Jelly Bean. Therefore the "usual nice approaches" might not work here, and dirty workarounds have to be made.
I have an APK which contains the following in assets:
layout
layout-mdpi
layout-land
layout-large-mdpi
layout-large-land-mdpi
layout-large-hdpi
layout-large-xhdpi
And some other metrics code returned this:
D/AppDemo( 2091): measured width: 1920 PE width: 1920 scaleFactor = 1.0
D/AppDemo( 2091): [ANDROID] measured width: 1920 measured height: 1080
D/AppDemo( 2091): [ANDROID] scale for resources: 2.0 xdpi: 320.0 ydpi: 320.0
D/AppDemo( 2091): [ANDROID] screen density: xhdpi
D/AppDemo( 2091): [ANDROID] screen size: large
D/AppDemo( 2091): [ANDROID] using layout: layout-mdpi
So, looking at the metrics, why isn't layout-large-xhdpi
being loaded?
Please, tell me where I can look this up. I really need to find a way to force the Layout/Resource/AssetManager
to load a specific layout.
I am aware the most popular comment on this issue is "you do not need / why do you have layout-xhdpi
, you should have drawable-xhdpi
and layout-large
" but, bear with me.
I would very appreciate even small hints as to where to look at, and what to look for. So far, AssetManager
seems like the place to start digging/logging.
When I omit layout-mdpi
, the application crashes on me, with missing resources. The bug seems to be that even though the code returns xhdpi
, it assumes mdpi
somewhere else. I need to find this, and fix it so my apps look as nice as they did on ICS :)
I am figuring out which layout is loaded in a simple manner - all root layouts have a android:tag
element, and when I setContentView(R.layout.main_layout)
I grab the tag on the root element and know which folder got loaded. Apart from the visual feedback, this will eventually have to match with my device configuration.
Thanks in advance.
Solution
Interesting problem. I had a look, but it all goes a bit down the rabbit hole. No answer as such, but maybe my analysis will set you in the right direction.
I looked at what happened from setContentView
forwards. Obviously at that point you are talking in terms of a density-agnostic layout reference (e.g. R.layout.main_layout
) and then later it will be turned into a reference to a specific file in the APK. When and where is your question.
I used landscape/portrait qualifiers so that I could change the quality at runtime, and I used a debugger with the Android source attached.
Here's a flow, starting some way into it.
- Resources.getLayout(int)
- Resources.loadXmlResourceParser(int, String)
- Resources.getValue(int, TypedValue, boolean)
- AssetManager.getResourceValue(int, int, TypedValue, boolean)
- StringBlock.get(int)
- StringBlock.nativeGetString(int,int)
Let's work backwards.
Step 6 is a native (C) method that returns the qualified reference, e.g. /res/layout-land/yourview.xml
. Its parameter is an index, however, and this changes based on whether we are in landscape or portrait.
To see where that came from we have to go back to step 4. The index is a field within the TypedValue, but it is not initially set correctly when it is passed in to this method.
Step 4 calls another native method, AssetManager.loadResourceValue()
, which alters the passed in TypedValue and sets the index appropriately.
Maybe you can start looking at the C for that and see how you get on.
Answered By - Rob Pridham
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.