I am trying to load dynamically a dex file that contains android activities classes using DexClassLoader class using the following code.
try {
File file = File.createTempFile("input",".dex");
InputStream reader = getResources().openRawResource(R.raw.classes);
OutputStream writer = new FileOutputStream(file.getAbsolutePath());
while(true){ int x = reader.read(); if(x == -1) break; writer.write(x);}
DexClassLoader loader = new DexClassLoader(file.getAbsolutePath(),null,null,MainActivity.this.getClassLoader());
Class<?> c = loader.loadClass("com.example.myapplication2.MainActivity");
Intent intent = new Intent(MainActivity.this.getApplicationContext(),c);
startActivity(intent);
}
catch(Exception e){
e.printStackTrace();
}
However, After execution of the previous code, The application crash with the following exception
android.content.ActivityNotFoundException: Unable to find explicit activity class{com.example.myapplication/com.example.myapplication2.MainActivity}; have you declared this activity in your AndroidManifest.xml?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2005)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1673)
at android.app.Activity.startActivityForResult(Activity.java:4586)
at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:728)
at android.app.Activity.startActivityForResult(Activity.java:4544)
at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:709)
at android.app.Activity.startActivity(Activity.java:4905)
at android.app.Activity.startActivity(Activity.java:4873)
at com.example.myapplication.MainActivity$1.onClick(MainActivity.java:82)
at android.view.View.performClick(View.java:6597)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Also, I noticed that most of examples the dex file contain normal java classes not activity classes so I wonder if what I am trying to do is applicable or not and the reason beyond the exception
The following solution worked for me and it's inspired from the blog post
Now the class loader of current context can see the loaded dex.