Android的哪个部分负责选择正确的资源配置文件?

时间:2013-02-26 11:09:30

标签: android android-layout android-resources android-resolution

我有一个奇怪的问题。

在你想出我的想法之前,我正在研究一个定制的果冻豆。因此,“常用的好方法”可能在这里不起作用,必须进行肮脏的解决方法。

我有一个APK,其中包含资产中的以下内容:

layout
layout-mdpi
layout-land
layout-large-mdpi
layout-large-land-mdpi
layout-large-hdpi
layout-large-xhdpi

其他一些指标代码返回了这个:

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

因此,查看指标​​,为什么不加载layout-large-xhdpi

请告诉我在哪里可以查看。我真的需要找到一种方法来强制Layout / Resource / AssetManager加载特定的布局。

我知道这个问题最受欢迎的评论是“你不需要/为什么你有layout-xhdpi,你应该drawable-xhdpilayout-large”但是,请耐心等待我

我非常感谢关于在哪里观看以及寻找什么的小提示。到目前为止,AssetManager似乎是开始挖掘/记录的地方。

当我省略layout-mdpi时,应用程序崩溃了,资源缺失。该错误似乎是即使代码返回xhdpi,它也会在其他地方假设mdpi。我需要找到这个,并修复它,以便我的应用程序看起来像在ICS上一样好:)

我正在计算以简单方式加载哪个布局 - 所有根布局都有android:tag元素,当我setContentView(R.layout.main_layout)时,我抓取根元素上的标记并知道哪个文件夹已加载。除了视觉反馈,这最终必须与我的设备配置相匹配。

提前致谢。

3 个答案:

答案 0 :(得分:4)

市场上有很多被黑客攻击的设备,例如 Micromax Funbook,屏幕尺寸很大但使用mdpi资源信任我,我曾与他们合作过,这非常令人沮丧。

正如您所提到的,您的应用程序与其他所有设备都运行良好,它只是不能使用这种平板电脑,您可能需要实现此处发布的此类解决方案

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

您必须阅读此页面上的最后一段,这肯定会有所帮助。

总结一下,建议的方法是使用不同的资源创建一个具有不同名称的单独布局。

您正在推动资源拣选流程,而不是系统。这可能是耗时的,但肯定会有所帮助。

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);
        }
    }
}  

答案 1 :(得分:3)

有趣的问题。我看了一眼,但这一切都在兔子洞里走了一段路。没有答案,但也许我的分析会让你朝着正确的方向前进。

我看了setContentView前锋发生的事情。显然,在这一点上,您正在谈论密度不可知的布局参考(例如R.layout.main_layout),然后它将变成对APK中特定文件的引用。您的问题何时何地。

我使用了横向/纵向限定符,以便我可以在运行时更改质量,并且我使用了附带Android源的调试器。

这是一个流程,从某种方式开始。

  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)
  7. 让我们倒退。

    步骤6是本机(C)方法,它返回限定引用,例如, /res/layout-land/yourview.xml。然而,它的参数是一个索引,这会根据我们是横向还是纵向而改变。

    要查看它的来源,我们必须返回到步骤4.索引是TypedValue中的一个字段,但在传入此方法时,它最初没有正确设置。

    第4步调用另一个本机方法AssetManager.loadResourceValue(),它改变传入的TypedValue并适当地设置索引。

    也许你可以开始查看C,看看你是如何继续的。

答案 2 :(得分:1)

我不知道如果你做对了,你正在构建一个自定义的AndroidOS,你希望这个自定义的AndroidOS总是加载相同的布局资源,在你的情况下layout-large-xhdpi?

如果是这样,我认为您已自定义Configuration Class。如果你想要快速和肮脏,你可以覆盖第72行及以下的int-Constants。

具体,改变:

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

为:

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

其他方法可能是覆盖构造函数和setToDefaults() - 方法,因此它总是加载相同的screenlayout。

我没有尝试过,我不知道它是否有效,而且我没有可信和/或官方消息来源(排除官方Android代码),但我希望我可以帮助你。