Which part of Android is in charge of picking a correct resource profile?

我怕爱的太早我们不能终老 提交于 2019-12-01 03:49:19

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.

  1. Resources.getLayout(int)
  2. Resources.loadXmlResourceParser(int, String)
  3. Resources.getValue(int, TypedValue, boolean)
  4. AssetManager.getResourceValue(int, int, TypedValue, boolean)
  5. StringBlock.get(int)
  6. 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.

There are so many hacked devices in the market like Micromax Funbook which have a screen size large but uses the mdpi resources trust me I have worked with them and it was very frustrating.

As you mentioned your app is working great with every other device it's just not working with this praticular tablet you may need to implement such kinda solution posted here

http://android-developers.blogspot.in/2011/07/new-tools-for-managing-screen-sizes.html

You must read the last segment on this page it will surely help.

to summarize it here the suggested approach is to create a seperate layout with the different name using the different resources altogether.

You are driving the resource picking process here not the system. which may be time consuming but will surely help.

public class MyActivity extends Activity {
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate();

        Configuration config = getResources().getConfiguration();
        if (config.smallestScreenWidthDp >= 600) {
            setContentView(R.layout.main_activity_tablet);
        } else {
            setContentView(R.layout.main_activity);
        }
    }
}  

I don't know if i get you right, you are building a custom AndroidOS and you want this custom AndroidOS to always load the same layout resource, in your case layout-large-xhdpi?

If so, i think you have customize the Configuration Class. If you want it quick and dirty, you could maybe override the int-Constants on line 72 and below.

Concrete, change:

....
100     public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
108     public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;

to:

....
100     public static final int SCREENLAYOUT_SIZE_LARGE = 0x04;
108     public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;

Other way could be to override the Constructor and the setToDefaults()-Method so it always loads the same screenlayout.

I didn't tried it out, I do not know if it is working, and I have no credible and/or official sources (Excluded offical Android Code), but i hope i could help you.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!