• /**

  •      * 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.

  •      *

  •      *  Throws {@link PackageManager.NameNotFoundException} if there is no

  •      * application with the given package name.

  •      *

  •      *  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,就可以访问该软件包的资源,甚至可以执行其它软件包的代码。

使用:

- <span class="keyword">try</span> {

- Context c = createPackageContext(<span class="string">&#8220;com.dolphin.demo&#8221;</span>, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);

- } <span class="keyword">catch</span> (SecurityException e) {

- e.printStackTrace();

- } <span class="keyword">catch</span> (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来查找资源图片;

    **[java]** [view plain](http://blog.csdn.net/wangbole/article/details/22876179#)<span data-mod="popu_168"> [copy](http://blog.csdn.net/wangbole/article/details/22876179#)</span>
  

  
  <div>
    <embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="28" height="15" align="middle" name="ZeroClipboardMovie_3" data-mce-fragment="1">
    </embed>
  </div>
  
  

    <span data-mod="popu_169"> [print](http://blog.csdn.net/wangbole/article/details/22876179#)</span>[?](http://blog.csdn.net/wangbole/article/details/22876179#)<span class="tracking-ad" data-mod="popu_167">[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/272565)</span><span class="tracking-ad" data-mod="popu_170">[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/272565/fork)</span>
  

</div>
- Context context;

- <span class="keyword">try</span> {

- context = createPackageContext(<span class="string">&#8220;com.dolphin.demo&#8221;</span>, Context.CONTEXT_INCLUDE_CODE

- | Context.CONTEXT_IGNORE_SECURITY);

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

- } <span class="keyword">catch</span> (NameNotFoundException e) {

- e.printStackTrace();

- }

2.2)通过资源Name,反推出资源ID,然后查找对应的资源图片;

    **[java]** [view plain](http://blog.csdn.net/wangbole/article/details/22876179#)<span data-mod="popu_168"> [copy](http://blog.csdn.net/wangbole/article/details/22876179#)</span>
  

  
  <div>
    <embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="28" height="15" align="middle" name="ZeroClipboardMovie_4" data-mce-fragment="1">
    </embed>
  </div>
  
  

    <span data-mod="popu_169"> [print](http://blog.csdn.net/wangbole/article/details/22876179#)</span>[?](http://blog.csdn.net/wangbole/article/details/22876179#)<span class="tracking-ad" data-mod="popu_167">[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/272565)</span><span class="tracking-ad" data-mod="popu_170">[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/272565/fork)</span>
  

</div>
- <span class="comment">/***  </span>

- <span class="comment">    * @param clazz 目标资源的R.java  </span>

- <span class="comment">    * @param className R.java的内部类,如layout,string,drawable&#8230;  </span>

- <span class="comment">    * @param name 资源名称  </span>

- <span class="comment">    * @return  </span>

- <span class="comment">    */</span>

- <span class="keyword">private</span> <span class="keyword">int</span> getResourseIdByName(Class clazz, String className, String name) {

- <span class="keyword">int</span> id = <span class="number"></span>;

- <span class="keyword">try</span> {

- 
- Class[] classes = clazz.getClasses(); <span class="comment">// 获取R.java里的所有静态内部类  </span>

- Class desireClass = <span class="keyword">null</span>;

- 
- <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number"></span>; i < classes.length; i++) {

- <span class="keyword">if</span> (classes[i].getName().split(<span class="string">&#8220;\\$&#8221;</span>)[<span class="number">1</span>].equals(className)) {

- desireClass = classes[i];

- <span class="keyword">break</span>;

- }

- }

- <span class="keyword">if</span> (desireClass != <span class="keyword">null</span>)

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

- } <span class="keyword">catch</span> (IllegalArgumentException e) {

- e.printStackTrace();

- } <span class="keyword">catch</span> (SecurityException e) {

- e.printStackTrace();

- } <span class="keyword">catch</span> (IllegalAccessException e) {

- e.printStackTrace();

- } <span class="keyword">catch</span> (NoSuchFieldException e) {

- e.printStackTrace();

- }

- 
- <span class="keyword">return</span> id;

- }

- 
- 
- Context context;

- <span class="keyword">try</span> {

- context = createPackageContext(<span class="string">&#8220;com.dolphin.demo&#8221;</span>, Context.CONTEXT_INCLUDE_CODE

- | Context.CONTEXT_IGNORE_SECURITY);

- Class cls = context.getClassLoader().loadClass(<span class="string">&#8220;com.dolphin.demo.R&#8221;</span>); <span class="comment">// 获得目标apk的R类  </span>

- txvA.setText(context.getResources().getText(getResourseIdByName(cls, <span class="string">&#8220;string&#8221;</span>, <span class="string">&#8220;message&#8221;</span>)));

- } <span class="keyword">catch</span> (NameNotFoundException e) {

- e.printStackTrace();

- } <span class="keyword">catch</span> (ClassNotFoundException e) {

- e.printStackTrace();

- }

- 

💬 评论