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);
}
}
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;
}
}
Aggregations