Search code examples
javaandroidreflection

Java reflection - Android classes not found


I am trying to run reflection to check if some android class exists in Java ( such as Toast ). I am running it from my Command line using this code:

String [] packages = new String[] {"java.lang.",
    "android.widget.",
    "android.util.",
    "android.app.",
    "android.view.",
    "android.content."};
for (int i = 0; i < packages.length; i++){
    String package_name = packages[i];
    try {
        Class<?> clazz = Class.forName(package_name + "Toast");
        System.out.println("class Exists");
        return clazz;
    }
    catch (ClassNotFoundException e){
        System.out.println("class " + package_name + "Toast doesnt exists");
    }
}

However, I get the output: class android.widget.Toast doesn't exists ( but I know it does this is where the class is at) any ideas?


EDIT : I am trying to write a Java class that is not running from Android Studios, but compiles and runs using javac from cmd line.


Solution

  • Because you are executing this on the command line there is no reason the Android packages/classes should be available to the runtime unless it is explicitly included. The output of your program makes sense - unless you provide the correct Android libraries to the program then there is not going to be a match when you try to resolve a particular Android class such as Toast.

    The answer is essentially using Java's classpath effectively. By default, without stating an argument, it is the working directory '.'.

    Add to it using -classpath as an argument. Compile naively:

    javac YourReflectionTest.java
    

    as you know the program finds no matches.

    If you do this javac will also succeed

    javac -classpath ".;/opt/android-sdk/platforms/android-21/android.jar" YourReflectionTest.java
    

    If you run the program, and try

    java YourReflectionTest
    

    It will still produce the same result. Why? At run-time, there are still no Android classes loaded. You are by default only going to get the java system libraries included in your installation of JDK.

    But, if you provide an appropriate path at runtime, then suddenly all the magic happens:

    java -classpath ".;/opt/android-sdk/platforms/android-21/android.jar" YourReflectionTest
    

    Note, Android API level 21 is just an example here and any could be used depending on which features you're trying to test.