when android's isValidFragment() from PreferenceActivity gets called?

依然范特西╮ 提交于 2019-12-03 13:27:12

Seems to be a bug or a 4.4 security restriction. Workaraound is to use anything below 19 that is still compatible with PreferenceActivity, and bite the bullet for compiling with an older target.

I am using the headers "pattern" for the PreferenceActivity (overriding public void onBuildHeaders(List<Header> target)), and I assume the OP is too, most likely being the place where stuff happens and crashes.

In my case, I have narrowed this exception to <uses-sdk android:targetSdkVersion="19" />, and anything in [14-18] build targets will compile and run without issues.

Suggestion (for Eclipse): I never messed directly messed with such stuff, but I'm assuming if you compile your PreferenceActivity (and maybe fragments) on a different project, targeting 18 or under (pun not intended :O ), and then using that project as a library for your main project targeting KitKat (19), perhaps you can avoid the crash scenario at run-time while still using the features you need from the latest build (as long as those features aren't in the build-18-bound PreferenceActivity). If this does not succeed, try with that project in jar form (pre-compiled) instead of using project as library.

UPDATE: also take note of Camille Sévigny's answer. If the issue has anything to do with that other question (50% chance IMHO), all apps targeting API 18 are vulnerable to fragment injection attacks (see his linked question).

Camille Sévigny

The answer to your question is in this post. This is a duplicate question:

isValidFragment Android API 19

--Updated--

Here is what the solution is:

Basically, whichever Activity is using your fragment "com...$" in the error above, you must update it with the fix below. You should update all the Activities in your project with this fix for any Acitvity that uses a Fragment.

The documentation states:

protected boolean isValidFragment (String fragmentName)

Added in API level 19

Subclasses should override this method and verify that the given fragment is a 
valid type to be attached to this activity. The default implementation returns 
true for apps built for android:targetSdkVersion older than KITKAT. For later 
versions, it will throw an exception.

You can fix this error by overriding this method to the Activity/FragmentActivity:

@Override
protected boolean isValidFragment (String fragmentName) {
  return [YOUR_FRAGMENT_NAME_HERE].class.getName().equals(fragmentName);
}

If you are being lazy and just want to test out if this fix works before coding all your fragments into this method, you can simply return true without any checking:

@Override
protected boolean isValidFragment (String fragmentName) {
  return true;
}

I had the same issues when testing on the emulator and this was the solution.

Here you go!

Slap this in there, and you're good!

Collect all the inner classes found in this PreferenceActivity. I chose to put the list in a static field variable:

public class whatever extends PreferenceActivity {

    static final Class<?>[] INNER_CLASSES = 
                                     whatever.class.getDeclaredClasses();

Then, override the method, ValidFragment, and ensure the fragment about to be displayed is one the 'parent' activity is aware of:

 /**
 *  Google found a 'security vulnerability' and imposed this hack.
 *  Have to check this fragment was actually conceived by this activity.
 */
@Override
protected boolean isValidFragment(String fragmentName) {

    Boolean knownFrag = false;

    for (Class<?> cls : INNER_CLASSES) {

       if ( cls.getName().equals(fragmentName) ){

           knownFrag = true;

           break;
       }
    }           

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