CreatPackageContext

  1.  Override  
  2.     public Context createPackageContext(String packageName, int flags)  
  3.         throws PackageManager.NameNotFoundException {  
  4.         if (packageName.equals("system") || packageName.equals("android")) {  
  5.             final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());  
  6.             context.mBasePackageName = mBasePackageName;  
  7.             return context;  
  8.         }  
  9.   
  10.   
  11.         LoadedApk pi =  
  12.             mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);  
  13.         if (pi != null) {  
  14.             ContextImpl c = new ContextImpl();  
  15.             c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;  
  16.             c.init(pi, null, mMainThread, mResources, mBasePackageName);  
  17.             if (c.mResources != null) {  
  18.                 return c;  
  19.             }  
  20.         }  
  21.   
  22.   
  23.         // Should be a better exception.  
  24.         throw new PackageManager.NameNotFoundException(  
  25.             "Application package " + packageName + " not found");  
  26.     }   Override 
    28.    public Context createPackageContext(String packageName, int flags) 
    29.        throws PackageManager.NameNotFoundException { 
    30.        if (packageName.equals("system") || packageName.equals("android")) { 
    31.            final ContextImpl context = new ContextImpl(mMainThread.getSystemContext()); 
    32.            context.mBasePackageName = mBasePackageName; 
    33.            return context; 
    34.        } 
    35. 
    36. 
    37.        LoadedApk pi = 
    38.            mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags); 
    39.        if (pi != null) { 
    40.            ContextImpl c = new ContextImpl(); 
    41.            c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; 
    42.            c.init(pi, null, mMainThread, mResources, mBasePackageName); 
    43.            if (c.mResources != null) { 
    44.                return c; 
    45.            } 
    46.        } 
    47. 
    48. 
    49.        // Should be a better exception. 
    50.        throw new PackageManager.NameNotFoundException( 
    51.            "Application package " + packageName + " not found"); 
    52.    } 
  27. /**
         * Return a new Context object for the given application name.  This
         * Context is the same as what the named application gets when it is
         * launched, containing the same resources and class loader.  Each call to
         * this method returns a new instance of a Context object; Context objects
         * are not shared, however they share common state (Resources, ClassLoader,
         * etc) so the Context instance itself is fairly lightweight.
         *
         * <p>Throws {@link PackageManager.NameNotFoundException} if there is no
         * application with the given package name.
         *
         * <p>Throws {@link java.lang.SecurityException} if the Context requested
         * can not be loaded into the caller's process for security reasons (see
         * {@link #CONTEXT_INCLUDE_CODE} for more information}.
         *
         * @param packageName Name of the application's package.
         * @param flags Option flags, one of {@link #CONTEXT_INCLUDE_CODE}
         *              or {@link #CONTEXT_IGNORE_SECURITY}.
         *
         * @return A Context for the application.
         *
         * @throws java.lang.SecurityException
         * @throws PackageManager.NameNotFoundException if there is no application with
         * the given package name
         */
        
        Override
        public Context createPackageContext(String packageName, int flags)
            throws PackageManager.NameNotFoundException {
            if (packageName.equals("system") || packageName.equals("android")) {
                final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
                context.mBasePackageName = mBasePackageName;
                return context;
            }
    
    
            LoadedApk pi =
                mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
            if (pi != null) {
                ContextImpl c = new ContextImpl();
                c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
                c.init(pi, null, mMainThread, mResources, mBasePackageName);
                if (c.mResources != null) {
                    return c;
                }
            }
    
    
            // Should be a better exception.
            throw new PackageManager.NameNotFoundException(
                "Application package " + packageName + " not found");
        }

        主要作用是:创建其它程序的Context,通过创建的这个Context,就可以访问该软件包的资源,甚至可以执行其它软件包的代码。
        
        使用:
        

try {    

     Context c = createPackageContext("com.dolphin.demo", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);    

 } catch (SecurityException e) {    

     e.printStackTrace();    

 } catch (Exception e) {    

     e.printStackTrace();    

 }  

   try {  
        Context c = createPackageContext("com.dolphin.demo", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);  
    } catch (SecurityException e) {  
        e.printStackTrace();  
    } catch (Exception e) {  
        e.printStackTrace();  
    }

    通常一个软件是不能创建其它程序的Context的,除非它们拥有相同的用户ID与签名。用户ID是一个字符串标识,在程序的AndroidManifest.xml文件的manifest标签中指定,格式为android:shareUserId="**"。安装在设备中的每一个apk程序,Android系统会给其分配一个单独的用户空间,其中android:shareUserId就是对应一个Linux用户ID,并且为它创建一个沙箱,以防止与其它应用程序产生影响。用户ID 在应用程序被安装到设备中时分配。通过SharedUserid,拥有同一个Userid的多个APK可以配置成运行在同一个进程中,所以默认就是可以互相访问任意数据,也可以配置成运行在不同的进程中, 同时可以访问其APK的数据目录下的资源(图片,数据库和文件),就像访问本程序的数据一样。

    
   经常的用途:
   如经常一些应用提供的换皮肤功能,实现方法大致有两种:
   1)把需要替换的资源图片打包好之后,放在客户端指定的目录下面,切换皮肤,查找相应的资源时,直接切换资源查找的路径到该打包文件中对应的资源路径即可。
   2)把需要替换的资源,放在一个空的android 应用程序的drawable-**目录下面即可,编译,运行该apk,查找资源时,就需要用到createPackageContext获取对应包名的Context实例,然后通过context来查找对应的资源。查找时,也有两种方式:
   2.1)通过ID来查找资源图片;
       

Context context;    

       try {    

           context = createPackageContext("com.dolphin.demo", Context.CONTEXT_INCLUDE_CODE    

                   | Context.CONTEXT_IGNORE_SECURITY);    

           txvA.setText(context.getResources().getText(R.string.message));    

       } catch (NameNotFoundException e) {    

           e.printStackTrace();    

      }   

 Context context;  
        try {  
            context = createPackageContext("com.dolphin.demo", Context.CONTEXT_INCLUDE_CODE  
                    | Context.CONTEXT_IGNORE_SECURITY);  
            txvA.setText(context.getResources().getText(R.string.message));  
        } catch (NameNotFoundException e) {  
            e.printStackTrace();  
        } 
        
   2.2)通过资源Name,反推出资源ID,然后查找对应的资源图片;
   

/***   

    * @param clazz 目标资源的R.java   

    * @param className R.java的内部类,如layout,string,drawable...   

    * @param name 资源名称   

    * @return   

    */    

   private int getResourseIdByName(Class clazz, String className, String name) {    

       int id = 0;    

       try {    

   

           Class[] classes = clazz.getClasses(); // 获取R.java里的所有静态内部类    

           Class desireClass = null;    

   

           for (int i = 0; i < classes.length; i++) {    

               if (classes[i].getName().split("\\$")[1].equals(className)) {  

                   desireClass = classes[i];    

                   break;    

               }    

           }    

           if (desireClass != null)    

               id = desireClass.getField(name).getInt(desireClass);  

       } catch (IllegalArgumentException e) {    

           e.printStackTrace();    

       } catch (SecurityException e) {    

           e.printStackTrace();    

       } catch (IllegalAccessException e) {    

           e.printStackTrace();    

       } catch (NoSuchFieldException e) {    

           e.printStackTrace();    

       }    

   

       return id;    

   }    

    

    

   Context context;    

   try {    

       context = createPackageContext("com.dolphin.demo", Context.CONTEXT_INCLUDE_CODE    

               | Context.CONTEXT_IGNORE_SECURITY);    

       Class cls = context.getClassLoader().loadClass("com.dolphin.demo.R"); // 获得目标apk的R类    

       txvA.setText(context.getResources().getText(getResourseIdByName(cls, "string""message")));    

   } catch (NameNotFoundException e) {    

       e.printStackTrace();    

   } catch (ClassNotFoundException e) {    

       e.printStackTrace();    

   }    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值