Dynamically load a class based on string in Android

Method to get loaded class. The method will return null if class is not loaded successfully.

public Object getDeviceClass(Context context, String packageName, String className){
  try {
            // Load the dex files for loading the dynamic class
            PackageManager pm = context.getPackageManager();
            File dexOutputDir = context.getDir("dex", Context.MODE_PRIVATE);
            ApplicationInfo ai = pm.getApplicationInfo(context.getPackageName(), 0);
            String sourceApk = ai.publicSourceDir;
            DexClassLoader dexLoader = new DexClassLoader(sourceApk,
                    dexOutputDir.getAbsolutePath(),
                    null,
                    context.getClassLoader());

            // Now load the corresponding class based on the class name
            Class<?> targetClass = Class.forName(packageName + "." + className, true, dexLoader);

            return targetClass.getConstructor().newInstance();

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

return null
}

If success, you can easily cast it to your corresponding class. The loaded class object needs to extend the parent class.

       Object loadedClass = getDeviceClass(context,packagename,classname);
       ParentClass yourParentClass = (ParentClass)loadedClass;
       yourParentClass.publicMethod();