三、在 AndroidManifest.xml 清单文件中配置组件
将 com.example.dex_demo.DexTest 组件类配置到 AndroidManifest.xml 清单文件中 ;
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.classloader_demo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.ClassLoader_Demo"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.dex_demo.MainActivity2"/> </application> </manifest>
四、启动 DEX 文件中的 Activity
初始化 DexClassLoader 类加载器 , 加载 com.example.dex_demo.MainActivity2 类 , 然后直接启动该组件 ;
代码示例 :
/** * 不修改类加载器的前提下 * @param context * @param dexFilePath */ private void startDexActivityWithoutClassLoader(Context context, String dexFilePath) { // 优化目录 File optFile = new File(getFilesDir(), "opt_dex"); // 依赖库目录 , 用于存放 so 文件 File libFile = new File(getFilesDir(), "lib_path"); // 初始化 DexClassLoader DexClassLoader dexClassLoader = new DexClassLoader( dexFilePath, // Dex 字节码文件路径 optFile.getAbsolutePath(), // 优化目录 libFile.getAbsolutePath(), // 依赖库目录 context.getClassLoader() // 父节点类加载器 ); // 加载 com.example.dex_demo.DexTest 类 // 该类中有可执行方法 test() Class<?> clazz = null; try { clazz = dexClassLoader.loadClass("com.example.dex_demo.MainActivity2"); } catch (ClassNotFoundException e) { e.printStackTrace(); } // 启动 com.example.dex_demo.MainActivity2 组件 if (clazz != null) { context.startActivity(new Intent(context, clazz)); } }
执行结果 :
2021-12-12 01:02:01.431 25158-25158/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.classloader_demo, PID: 25158 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.classloader_demo/com.example.dex_demo.MainActivity2}: java.lang.ClassNotFoundException: Didn't find class "com.example.dex_demo.MainActivity2" on path: DexPathList[[zip file "/data/app/com.example.classloader_demo-sAY0kit-c9kqTzgMRXYoBA==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.classloader_demo-sAY0kit-c9kqTzgMRXYoBA==/lib/arm64, /system/lib64]] at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2881) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3086) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6718) 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) Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.dex_demo.MainActivity2" on path: DexPathList[[zip file "/data/app/com.example.classloader_demo-sAY0kit-c9kqTzgMRXYoBA==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.classloader_demo-sAY0kit-c9kqTzgMRXYoBA==/lib/arm64, /system/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69) at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45) at android.app.Instrumentation.newActivity(Instrumentation.java:1215) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2869) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3086) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6718) 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)