Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8747281
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T12:19:51+00:00 2026-06-13T12:19:51+00:00

In order to support different Api Levels, I am using the technique described here:

  • 0

In order to support different Api Levels, I am using the technique described here: http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html

Here is the example from the article:

public static VersionedGestureDetector newInstance(Context context,
        OnGestureListener listener) {
    final int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
    VersionedGestureDetector detector = null;
    if (sdkVersion < Build.VERSION_CODES.ECLAIR) {
        detector = new CupcakeDetector();
    } else if (sdkVersion < Build.VERSION_CODES.FROYO) {
        detector = new EclairDetector();
    } else {
        detector = new FroyoDetector(context);
    }

    detector.mListener = listener;

    return detector;
}

This approach “takes advantage of the laziness of ClassLoaders.” For devices with the newer API level (in the example’s case, Froyo), it can use the Froyo class which accesses APIs in the newer version. For older devices, they receive a class that only uses the older APIs.

This works perfectly.

However, if you make FroyoDetector implement an interface, that only exists in a newer api level, when newInstance() is called, even before it runs any of the code within that method, it tries to load the interface class that FroyoDetector implements and puts an error into the logs saying that the FroyoDetector class could not be loaded.

So my question is, why does this happen? I was under the impression that with this technique that the newer class wouldn’t be loaded until it was directly referenced for the first time. However if you add an interface to it, it seems to try to load it even without calling the detector = new FroyoDetector(context); line.

Here is some code to reproduce the issue:

This is in an app targeting sdk 16 with a min of 8. Running this on a 2.3 device reproduces the issue.

Here are three classes:

public class VersionedLoader {

    public static VersionedLoader newInstance() {
        if (Build.VERSION.SDK_INT < 12) {
            return new OldVersionLoader();
        } else {
            return new NewVersionLoader();
        }
    }

}

–

public class OldVersionLoader extends VersionedLoader {

}

–

@TargetApi(11)
public class NewVersionLoader extends VersionedLoader implements AnimatorListener {

    @Override
    public void onAnimationStart(Animator animation) {}

    @Override
    public void onAnimationEnd(Animator animation) {}

    @Override
    public void onAnimationCancel(Animator animation) {}

    @Override
    public void onAnimationRepeat(Animator animation) {}

}

AnimatorListener is only available from 3.1 onwards.

Now if you run: Object obj = VersionedLoader.newInstance();

This error will appear in the logs:

10-27 13:51:14.437: I/dalvikvm(7673): Failed resolving Lyour/package/name/NewVersionLoader; interface 7 'Landroid/animation/Animator$AnimatorListener;'
10-27 13:51:14.437: W/dalvikvm(7673): Link of class 'Lyour/package/name/NewVersionLoader;' failed
10-27 13:51:14.445: E/dalvikvm(7673): Could not find class 'your.package.name.NewVersionLoader', referenced from method your.package.name.VersionedLoader.newInstance
10-27 13:51:14.445: W/dalvikvm(7673): VFY: unable to resolve new-instance 1327 (Lyour/package/name/NewVersionLoader;) in Lyour/package/name/VersionedLoader;
10-27 13:51:14.445: D/dalvikvm(7673): VFY: replacing opcode 0x22 at 0x000c
10-27 13:51:14.445: D/dalvikvm(7673): VFY: dead code 0x000e-0011 in Lyour/package/name/VersionedLoader;.newInstance ()Lyour/package/name/VersionedLoader;

It won’t crash, and it will actually go on to work correctly.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T12:19:52+00:00Added an answer on June 13, 2026 at 12:19 pm

    Yes, I can reproduce the problem. Kinda surprising, though, as you note, the fact that it does not crash means that this is more a case of Dalvik being perhaps a bit too chatty in LogCat than anything that should cause harm to an app.

    One workaround is to move the interface to an inner class. In your example, instead of NewVersionLoader implementing AnimatorListener, an inner class in NewVersionLoader would implement AnimationListener:

    @TargetApi(11)
    public class NewVersionLoader extends VersionedLoader {
        private class Foo implements AnimatorListener {
            @Override
            public void onAnimationStart(Animator animation) {}
    
            @Override
            public void onAnimationEnd(Animator animation) {}
    
            @Override
            public void onAnimationCancel(Animator animation) {}
    
            @Override
            public void onAnimationRepeat(Animator animation) {}
    
        }
    }
    

    Admittedly, this may not be ideal depending on your intended use of VersionedLoader. However, since VersionedLoader itself does not implement AnimationListener, users of VersionedLoader will not be calling AnimationListener methods, so the fact that your logic is on an inner class rather than the actual class should not be a huge issue AFAIK.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In order to support UIDocumentController options on different file types, I thought that perhaps
I am going to create an Android application that supports multiple API levels. I
I heard on Windows x64 architecture, in order to support to run both x86
My idea is to use camel to decouple modules. In order to support scalability
I would like to use ORDER BY FIELD() (MySQL) in Django. Does Django support
Consider this jsfiddle: http://fiddle.jshell.net/maple/JbEJN/show/ (this is the result window, in order for replaceState to
I'm wondering how many different formats for each video would I need in order
I am trying to support two Icon_Picker intents: org.adw.launcher.icons.ACTION_PICK_ICON and com.betterandroid.launcher2.icons.PICK_ICON_ACTION Unfortunately ADW, Go
Android allows us to define hdpi/mdpi/ldpi for the drawable folder in order to account
I need to persist a object. Unfortunately sqlite in android does not support ORM.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.