[Android] Reflect: ClassLoader, PathClassLoader

2501阅读 0评论2011-12-01 web_surf
分类:嵌入式

  1. 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);
  2. 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:

    点击(此处)折叠或打开

    1.     private void testRes()
    2.     {
    3.         String apkPath = "/sdcard/com.test.plugin.apk";
    4.         String pkgName = "com.example.demoapkloaderlib";
    5.         
    6.         Resources res = loadRes(apkPath);
    7.         if (res != null)
    8.         {
    9.             System.out.println("##################### app_name a = " + res.getString(R.string.app_name));
    10.             System.out.println("##################### app_name b = " + res.getString(res.getIdentifier("app_name", "string", pkgName)));
    11.         }
    12.         else
    13.         {
    14.             System.out.println("##################### failed to load res");
    15.         }
    16.     }
    17.     
    18.     
    19.     private Resources loadRes(String apkPath)
    20.     {
    21.         try
    22.         {
    23.             AssetManager assetMgr = AssetManager.class.newInstance();
    24.             Method mtdAddAssetPath = AssetManager.class
    25.                     .getDeclaredMethod("addAssetPath", String.class);
    26.             mtdAddAssetPath.invoke(assetMgr, apkPath);
    27.             
    28.             Constructor<?> ctorResources = Resources.class
    29.                     .getConstructor(AssetManager.class, DisplayMetrics.class,
    30.                             Configuration.class);
    31.             
    32.             Resources res = (Resources) ctorResources.newInstance(assetMgr,
    33.                     mActivity.getResources().getDisplayMetrics(),
    34.                     mActivity.getResources().getConfiguration());
    35.             
    36.             return res;
    37.         }
    38.         catch (Throwable t)
    39.         {
    40.             t.printStackTrace();
    41.         }
    42.         
    43.         return null;
    44.     }


  3. 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.
  4. x
上一篇:[Android] Widgets: RemoteViews
下一篇:[Design] Buffer design