isValidFragment Android API 19

crb*_*in1 49 android android-fragments android-4.4-kitkat

当我使用Android KitKat尝试我的应用程序时,我在PreferenceActivity中出错.

PreferenceActivity的子类必须覆盖isValidFragment(String)以验证Fragment类是否有效!com.crbin1.labeltodo.ActivityPreference尚未检查片段com.crbin1.labeltodo.StockPreferenceFragment是否有效

在文档中,我找到以下解释

protected boolean isValidFragment(String fragmentName)

在API级别19中添加

子类应覆盖此方法并验证给定片段是否要附加到此活动的有效类型.对于为Android构建的应用程序,默认实现返回true:比KITKAT更早的targetSdkVersion.对于更高版本,它将抛出异常.

我找不到任何解决问题的例子.

use*_*324 65

试试这个......这就是我们检查片段有效性的方法.

protected boolean isValidFragment(String fragmentName) {
  return StockPreferenceFragment.class.getName().equals(fragmentName);
}
Run Code Online (Sandbox Code Playgroud)

  • 是否必须为每个碎片做?或者它是足够的优惠一个?! (4认同)
  • 所以在PreferenceActivity中我重写了这个方法并返回**true**...这似乎是一个非常愚蠢的事情**,呃? (2认同)
  • @Tobor为什么愚蠢?这是一个简单的安全检查,以确保当时调用的片段是授权片段(您认可的片段).如果你只是在没有任何逻辑的情况下"返回真实",这是毫无意义的.它会像白宫一样授权任何人和所有人走在街道的公共门口,但如果他们"只返回那些在那里工作的人",那就更正了. (2认同)
  • 非常蹩脚的是,您通过Android Studio添加PreferenceActivity时获得的默认实现此问题尚未解决. (2认同)

dav*_*ino 24

出于纯粹的好奇心,您也可以这样做:

@Override
protected boolean isValidFragment(String fragmentName) {
    return MyPreferenceFragmentA.class.getName().equals(fragmentName)
            || MyPreferenceFragmentB.class.getName().equals(fragmentName)
            || // ... Finish with your last fragment.

;}
Run Code Online (Sandbox Code Playgroud)


lan*_*ane 19

我发现我可以在加载时从头文件资源中获取我的片段名称的副本:

public class MyActivity extends PreferenceActivity
{
    private static List<String> fragments = new ArrayList<String>();

    @Override
    public void onBuildHeaders(List<Header> target)
    {
        loadHeadersFromResource(R.xml.headers,target);
        fragments.clear();
        for (Header header : target) {
            fragments.add(header.fragment);
        }
    }
...
    @Override
    protected boolean isValidFragment(String fragmentName)
    {
        return fragments.contains(fragmentName);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,如果我想更新它们,我不需要记住更新埋在代码中的片段列表.

我曾希望直接使用getHeaders()和现有的标题列表,但似乎活动onBuildHeaders()isValidFragment()被调用之后被销毁并重新创建.

这可能是因为我正在测试的Nexus 7实际上并没有进行双窗格偏好活动.因此也需要静态列表成员.


小智 18

由于新发现的漏洞,此API已添加.请参阅http://ibm.co/1bAA8kFhttp://ibm.co/IDm2Es

2013年12月10日 "我们最近披露了一个针对Android安全团队的新漏洞.[...]为了更准确,任何使用导出活动扩展PreferenceActivity类的应用程序都会自动受到攻击.在Android中提供了一个补丁KitKat.如果你想知道为什么你的代码现在坏了,那是因为Android KitKat补丁需要应用程序覆盖新方法PreferenceActivity.isValidFragment,它已被添加到Android Framework中. - 从上面的第一个链接

  • 您好@RoeeHay,请您详细说明链接的文章?将文章链接为答案通常被认为是一个错误的答案.您能否指出漏洞中的重点?我看到文章本身是由你自己编写的并且解释了很多,关于*为什么*它被引入.我很乐意提出这个答案,因为它到目前为止解释了为什么而不是如何解决这个问题. (8认同)