-
PathClassLoader
Load class in the specified .apk.
private void loadClass(Context context, String targetPackageName, String className)
{
PackageManager pm;
ApplicationInfo info;
String apkPath;
PathClassLoader pathClassLoader;
if (null == context)
{
return;
}
do
{
pm = context.getPackageManager();
if (null == pm) break;
try
{
info = pm.getApplicationInfo(targetPackageName), 0);
}
catch (PackageManager.NameNotFoundException e)
{
break;
}
if (null == info) break;
apkPath= info.sourceDir;
if (null == apkPath) break;
pathClassLoader = new dalvik.system.PathClassLoader(apkPath,
ClassLoader.getSystemClassLoader());
try
{
mClass= Class.forName(className, true, pathClassLoader);
}
catch (ClassNotFoundException e)
{
break;
}
} while (false);
-
DexClassLoader
Load class from un-installed .apk (such as an .apk pushed to sdcard); or load class from .jar of dex (Dalvik Executable) format. To convert .jar to .dex, just execute the following command:
$ dx --dex --output=to.jar from.jar
If java classes depends on specific resources, you'd package those classes and resources into .apk; otherwise, it's better to build java classes into an .jar archive. The following code snip is illustrated how to load resources from un-installed .apk:
-
private void testRes()
-
{
-
String apkPath = "/sdcard/com.test.plugin.apk";
-
String pkgName = "com.example.demoapkloaderlib";
-
-
Resources res = loadRes(apkPath);
-
if (res != null)
-
{
-
System.out.println("##################### app_name a = " + res.getString(R.string.app_name));
-
System.out.println("##################### app_name b = " + res.getString(res.getIdentifier("app_name", "string", pkgName)));
-
}
-
else
-
{
-
System.out.println("##################### failed to load res");
-
}
-
}
-
-
-
private Resources loadRes(String apkPath)
-
{
-
try
-
{
-
AssetManager assetMgr = AssetManager.class.newInstance();
-
Method mtdAddAssetPath = AssetManager.class
-
.getDeclaredMethod("addAssetPath", String.class);
-
mtdAddAssetPath.invoke(assetMgr, apkPath);
-
-
Constructor<?> ctorResources = Resources.class
-
.getConstructor(AssetManager.class, DisplayMetrics.class,
-
Configuration.class);
-
-
Resources res = (Resources) ctorResources.newInstance(assetMgr,
-
mActivity.getResources().getDisplayMetrics(),
-
mActivity.getResources().getConfiguration());
-
-
return res;
-
}
-
catch (Throwable t)
-
{
-
t.printStackTrace();
-
}
-
-
return null;
-
}
-
Access classes in java library
for DexClassLoader, PathClassLoader, the last argument is parents class loade.
To make class in current package (apk, or jar) to be available in java library access via reflect, you can specify parent class loader to ClassInThisPackage.class.getClassLoader(), rather ClassLoader.getSystemClassLoader(); and then, export the package to .jar, and import the .jar into the library project.
-
x
阅读(2433) | 评论(0) | 转发(0) |