0

I am trying to build an app which allows users to install additional plugins for the app. I am building plugin modules as apk and trying to load those classes at run time using DexClassLoader.

When i call a non activity class it works fine. When i try to launch an activity it gives me error saying Activity not found. Did you declare the activity in AndroidManifest.xml?

Is there a way i can also included resources from my plugin apk to work fine?

public class MainActivity extends AppCompatActivity {
    private DexClassLoader mDexClassLoader;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        loadApk();

        Button launchBtn = (Button) findViewById(R.id.launch_btn);
        launchBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mDexClassLoader != null) {
                    try {
                        //Works Fine
                        Class<?> clazz = mDexClassLoader.loadClass("com.dexplugintest.ToastTest");
                        Object object = clazz.newInstance();
                        Method toastMethod = clazz.getMethod("showToast", Context.class, String.class);
                        toastMethod.invoke(object, MainActivity.this, "Hello from test app!");

                        //Gives Error
                        Class calledClass = mDexClassLoader.loadClass("com.dexplugintest.PluginLaunchActivity");
                        Intent intent = new Intent(MainActivity.this, calledClass);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    } catch (Exception exception) {
                        // Handle exception gracefully here.
                        exception.printStackTrace();
                    }
                }
            }
        });
    }

    private void loadApk() {
        File file = DexUtil.copyFileToInternal(this, "app-debug.apk");

        if (file != null) {
            File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);
            mDexClassLoader = new DexClassLoader(file.getAbsolutePath(),
                    optimizedDexOutputPath.getAbsolutePath(),
                    null,
                    getClassLoader());
        }
    }
}
  • Where were you planning on distributing this app? The Play Store has [banned this sort of dynamic code](https://play.google.com/about/privacy-security/malicious-behavior/). – CommonsWare May 22 '17 at 23:59
  • @CommonsWare i was planning to use in an app distributed through play store. Is this something new? There are some libraries that provide this approach but they are few years old. I couldn't get it working with those libraries. – Krishna Kapil May 23 '17 at 00:06
  • Is there a better approach to implement plugin style architecture for Android apps? – Krishna Kapil May 23 '17 at 00:08
  • "Is this something new?" -- that particular restriction in the terms and conditions is new. "Is there a better approach to implement plugin style architecture for Android apps?" -- standard IPC. The plugin exposes activities, services, providers, and/or receivers, and the plugin host communicates with the plugin via those components. – CommonsWare May 23 '17 at 10:40
  • Will look into it. Thank you for the information @CommonsWare – Krishna Kapil May 23 '17 at 18:03

0 Answers0