Search code examples
androidandroid-sourcehorizontalscrollview

Rebuilding Android HorizontalScrollView source


I would like to build my own version of HorizontalScrollView - mainly to try and debug a problem I have but ultimately create a variant of HorizontalScrollView.

Below is a project I have uploaded which uses API 19:

https://www.mediafire.com/?o0qh7k3ayiz27og

I have basically taken a copy of HorizontalScrollView.java and copied and renamed it as MyHorizontalScrollView (.java). I have imported android.widget.* and even android.widget.ScrollView but for some reason Eclipse will not resolve simple ScrollView members such as ScrollView.ANIMATED_SCROLL_GAP which I can clearly see is defined within ScrollView.java.

This is only one example - there are many other members which cannot be resolved. Is this because MyHorizontalScrollView does not belong to the android.widget package?

How can I create my own (My)HorizontalScrollView? Is the only way to manually define the missing members myself? The problem with doing this is that ultimately I will have to import android.internal.R (I think) and I have no idea how to get around that problem.

Why am I even bothering trying to make my own HorizontalScrollView? Its all because I have problems with that class on one particular tablet that I own. I've already posted 2 questions on StackOverflow but no answers have helped. I can't override enough methods in HorizontalScrollView hence my dilemma.


Solution

  • I assume you're using the Android SDK?

    It's not because your class doesn't belong to android.widget. There's nothing preventing you from putting a class in android.widget and accessing package private members of other android.widget classes, that's part of Java.

    What you're trying to do is access members of ScrollView which are not part of its public API. This is obviously not supported, but hey, might let you do some convenient hacks. Thing is, not only are these members not part of the public API, they're not even in android.jar (which is the JAR file you reference in Eclipse which provides definitions for the SDK)

    You can verify this by analyzing the bytecode on SDK classes. Run:

    javap -classpath {ANDROID SDK FOLDER}/platforms/android-19/android.jar -private android.widget.ScrollView
    

    What you see is what you get. The fact that you see these members in the sources for ScrollView doesn't mean they're in the SDK. Devices use a totally different JAR for actually running the code.

    If you can't accomplish what you need by extending the class, you're trying to do something the Android engineers don't want app developers doing. That means, yes, you're kinda stuck with the currently proposed solution. And you can't really import android.internal.R because, well, it's internal. It's not accessible to applications. The change you're trying to make can only be made framework-side, not app-side. To run such a change you'd need to build a custom Android framework. This framework would exist on no devices and would do you no good.

    If it's a bug in the ScrollView, it should be submitted to the Android team. In the meantime, you'd need to figure out a different work-around.

    Edit:

    As for the work-around, the following blog post explaining how to access Android internal APIs may or may not help: Using internal (com.android.internal) and hidden (@hide) APIs. It's a bit outdated.