Search in sources :

Example 1 with NClassLoader

use of android.taobao.atlas.startup.NClassLoader in project atlas by alibaba.

the class KernalBundle method patchKernalDex.

public void patchKernalDex(Application application) throws Exception {
    DexFile[] dexFile = archive.getOdexFile();
    if ((dexFile != null && dexFile.length > 0) || archive.getLibraryDirectory().exists()) {
        boolean needReplaceClassLoader = needReplaceClassLoader(application);
        boolean dexPatch = dexFile[dexFile.length - 1].getName().contains(KernalBundleArchive.DEXPATCH_DIR);
        int newFrameworkPropertiesDexIndex;
        if (dexPatch) {
            newFrameworkPropertiesDexIndex = 0;
        } else {
            newFrameworkPropertiesDexIndex = dexFile.length - 1;
        }
        // 临时处理方案,需要替换为dexopt时传入classsLoader以兼容8.0
        patchWithApk = dexPatch && (TextUtils.isEmpty(KernalVersionManager.instance().currentVersionName()) || KernalVersionManager.instance().currentVersionName().equals(KernalConstants.INSTALLED_VERSIONNAME));
        if (!needReplaceClassLoader) {
            Log.e("KernalBundle", "no need replace Classloader!");
            FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass("android.taobao.atlas.framework.FrameworkProperties", application.getClassLoader());
        } else if (patchWithApk) {
            Log.e("KernalBundle", "need replace Classloader && patchWithApk!");
            replaceClassLoader = new NClassLoader(".", KernalBundle.class.getClassLoader().getParent());
            if (needReplaceClassLoader) {
                try {
                    NClassLoader.replacePathClassLoader(KernalConstants.baseContext, KernalBundle.class.getClassLoader(), replaceClassLoader);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass("android.taobao.atlas.framework.FrameworkProperties", replaceClassLoader);
        } else {
            Log.e("KernalBundle", "need replace Classloader && load FrameworkPropertiesClazz to NclassLoader!");
            replaceClassLoader = new NClassLoader(".", KernalBundle.class.getClassLoader().getParent());
            if (needReplaceClassLoader) {
                try {
                    NClassLoader.replacePathClassLoader(KernalConstants.baseContext, KernalBundle.class.getClassLoader(), replaceClassLoader);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            FrameworkPropertiesClazz = archive.getOdexFile()[newFrameworkPropertiesDexIndex].loadClass("android.taobao.atlas.framework.FrameworkProperties", replaceClassLoader);
        }
        // for mini sdk 21
        if (FrameworkPropertiesClazz == null) {
            Log.e("KernalBundle", "FrameworkPropertiesClazz is null, load from source apk");
            FrameworkPropertiesClazz = Class.forName("android.taobao.atlas.framework.FrameworkProperties");
        }
        if (FrameworkPropertiesClazz == null && isDeubgMode()) {
            Log.e("KernalBundle", "main dex is not match, library awo test?");
            return;
        }
        Field versionField = FrameworkPropertiesClazz.getDeclaredField("version");
        versionField.setAccessible(true);
        String version = (String) versionField.get(FrameworkPropertiesClazz.newInstance());
        if (!KernalVersionManager.instance().currentVersionName().equals(version)) {
            if (isDeubgMode()) {
                Log.e("KernalBundle", "main dex is not match, awo test?");
            } else {
                throw new RuntimeException(String.format("maindex version is not mismatch %s vs %s!", KernalVersionManager.instance().currentVersionName(), version));
            }
        }
        installKernalBundle(KernalConstants.baseContext.getClassLoader(), archive.getArchiveFile(), archive.getOdexFile(), archive.getLibraryDirectory());
        prepareRuntimeVariables(application);
        prepareKernalConstant(application);
    }
}
Also used : Field(java.lang.reflect.Field) DexFile(dalvik.system.DexFile) IOException(java.io.IOException) NClassLoader(android.taobao.atlas.startup.NClassLoader)

Example 2 with NClassLoader

use of android.taobao.atlas.startup.NClassLoader in project atlas by alibaba.

the class KernalBundle method checkLoadKernalDebugPatch.

public static boolean checkLoadKernalDebugPatch(Application application) {
    if (Build.VERSION.SDK_INT < 21) {
        // 暂时只支持art设备的debug调试
        return false;
    }
    boolean loadKernalPatch = false;
    try {
        ApplicationInfo app_info = application.getApplicationInfo();
        boolean debug = (app_info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        if (debug) {
            File debugBundleDir = new File(KernalConstants.baseContext.getExternalFilesDir("debug_storage"), KERNAL_BUNDLE_NAME);
            File patchFile = new File(debugBundleDir, "patch.zip");
            if (patchFile.exists()) {
                loadKernalPatch = true;
                KernalBundle bundle = new KernalBundle();
                // DexFile dexFile = (DexFile) KernalConstants.dexBooster.loadDex(KernalConstants.baseContext, KernalConstants.baseContext.getApplicationInfo().sourceDir,
                // new File(patchFile.getParent(), "base.dex").getAbsolutePath(), 0, true);
                File internalDebugBundleDir = new File(new File(application.getFilesDir(), "debug_storage"), KERNAL_BUNDLE_NAME);
                internalDebugBundleDir.mkdirs();
                DexFile patchDexFile = (DexFile) DexFile.loadDex(patchFile.getAbsolutePath(), new File(internalDebugBundleDir, "patch.dex").getAbsolutePath(), 0);
                if (bundle.needReplaceClassLoader(application)) {
                    NClassLoader loader = new NClassLoader(".", KernalBundle.class.getClassLoader().getParent());
                    try {
                        NClassLoader.replacePathClassLoader(KernalConstants.baseContext, KernalBundle.class.getClassLoader(), loader);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
                bundle.installKernalBundle(KernalConstants.baseContext.getClassLoader(), patchFile, new DexFile[] { patchDexFile /*, dexFile*/
                }, null, true);
                bundle.prepareRuntimeVariables(application);
                Class DelegateResourcesClazz = application.getClassLoader().loadClass("android.taobao.atlas.runtime.DelegateResources");
                DelegateResourcesClazz.getDeclaredMethod("addApkpatchResources", String.class).invoke(DelegateResourcesClazz, patchFile.getAbsolutePath());
                Toast.makeText(KernalConstants.baseContext, "当前处于DEBUG调试状态,不支持动态更新,清除数据可恢复", Toast.LENGTH_LONG).show();
            }
        }
    } finally {
        return loadKernalPatch;
    }
}
Also used : ApplicationInfo(android.content.pm.ApplicationInfo) ZipFile(java.util.zip.ZipFile) DexFile(dalvik.system.DexFile) File(java.io.File) DexFile(dalvik.system.DexFile) IOException(java.io.IOException) NClassLoader(android.taobao.atlas.startup.NClassLoader)

Aggregations

NClassLoader (android.taobao.atlas.startup.NClassLoader)2 DexFile (dalvik.system.DexFile)2 IOException (java.io.IOException)2 ApplicationInfo (android.content.pm.ApplicationInfo)1 File (java.io.File)1 Field (java.lang.reflect.Field)1 ZipFile (java.util.zip.ZipFile)1