android动态加载已安装和未安装的apk资源
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了android动态加载已安装和未安装的apk资源,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7620字,纯文字阅读大概需要11分钟。
内容图文
![android动态加载已安装和未安装的apk资源](/upload/InfoBanner/zyjiaocheng/1130/db6cb55f6a364b95a98ac8a6cc624726.jpg)
在android开发中动态加载已安装和未安装的apk资源,是很有用的,可以用来实现换肤功能等等。今天我们来学习。
首先新建一个工程plugpicinstall,我们需要往该工程的asset目录和drawable目录下拷贝一些呆会需要加载的图片。运行该工程,即安装。
我们先看看如何实现加载已经安装的apk中的资源:
我们需要先写两个方法,用来获取对应的已安装的apk的context对象和resource对应的id,如下:
/** * 该方法用来获取已经安装的apk对应的context对象 * @return * @throws NameNotFoundException */ private Context getInstalledContext() throws NameNotFoundException { return createPackageContext("com.example.plugpicinstall",Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE); } /** * 该方法用来获取已经安装的apk中对应的resource对象 * @param resources * @param resType * @param resName * @return */ private int getResourceId(Resources resources,String resType,String resName) { return resources.getIdentifier(resName, resType,"com.example.plugpicinstall"); }接下来是加载drawable文件加下图片和加载string.xml中的字符串的代码:
Resources installedResource = null; try { //得到已经安装的apk的resource对象 installedResource = getInstalledContext().getResources(); } catch (NameNotFoundException e) { e.printStackTrace(); } imageViewInstall.setImageDrawable(installedResource.getDrawable(getResourceId(installedResource,"drawable","three"))); String app_name = installedResource.getString(getResourceId(installedResource, "string","app_name")); String hello_world = installedResource.getString(getResourceId(installedResource, "string","hello_world")); Toast.makeText(MainActivity.this,"app_name is :"+app_name+"===hello_world is :"+hello_world,Toast.LENGTH_LONG).show();下面是加载已经安装的apk中的asset中的资源:
AssetManager assetManager = getInstalledContext().getResources().getAssets(); InputStream ins = assetManager.open("six.jpg"); Bitmap bitmap = BitmapFactory.decodeStream(ins); imageViewInstall.setImageBitmap(bitmap);这样就实现了加载已经安装好的apk中的资源文件。
接下来看看,加载没有安装的apk中对应的文件,首先将刚才的plugpicinstall工程从手机上卸载,然后将bin目录下生成的apk拷贝到手机sd卡相应的目录下:
同样,首先新建一个方法用来获取没有安装的apk对应的resource对象:
/** * 该方法用来获取未安装的apk的reosurces对象 * @return */ private Resources getUnInstalledResource() { // 反射出资源管理器 try { Class<?> assetManager_clazz = Class .forName("android.content.res.AssetManager"); //生成assetManager对象 Object assetObj = assetManager_clazz.newInstance(); //因为addAssetPath是隐藏的,所以只能通过反射来获取 Method addAssetMethod = assetManager_clazz.getDeclaredMethod("addAssetPath",String.class); addAssetMethod.invoke(assetObj,"/storage/sdcard0/183/plugpicinstall.apk"); Resources resources = getResources(); Constructor<?>resources_constructor = Resources.class.getConstructor(assetManager_clazz,resources.getDisplayMetrics().getClass(),resources.getConfiguration().getClass()); resources = (Resources) resources_constructor.newInstance(assetObj,resources.getDisplayMetrics(),resources.getConfiguration()); //返回/storage/sdcard0/183/plugpicinstall.apk的resources实例 return resources; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; }下面的代码实现加载未安装的apk中的资源:
String apkPath = "/storage/sdcard0/183/plugpicinstall.apk"; String dexPath = MainActivity.this.getDir("dex",Context.MODE_PRIVATE).getAbsolutePath(); DexClassLoader classLoader = new DexClassLoader(apkPath, dexPath, null, getClassLoader()); try { //反射得到R文件的内部类drawable Class<?> drawable_clazz = classLoader.loadClass("com.example.plugpicinstall.R$drawable"); //得到drawable类的所有属性 Field[]fields = drawable_clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); if (field.getName().equals("ten")) { <span style="white-space:pre"> </span>int id = field.getInt(new R.id()); imageViewInstall.setBackground(getUnInstalledResource().getDrawable(id)); } } //反射得到R文件的内部类string Class<?>string_clazz = classLoader.loadClass("com.example.plugpicinstall.R$string"); StringBuffer sb = new StringBuffer(); //得到string内部类的所有属性,这些属性就是我们在string.xml文件中生命的字符串资源 Field[]fields2 = string_clazz.getDeclaredFields(); int id = 0; for (Field field : fields2) { //得到对应的字符串资源的id值 id = field.getInt(new R.id()); sb.append(getUnInstalledResource().getString(id)); } Toast.makeText(MainActivity.this,sb.toString(),Toast.LENGTH_SHORT).show(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); }同样的,下面是获取未安装apk的asset资源的方法:
AssetManager assetManager = getUnInstalledResource().getAssets(); InputStream ins; try { ins = assetManager.open("five.jpg"); Bitmap bitmap = BitmapFactory.decodeStream(ins); imageViewInstall.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); }
到现在为止我们的动态加载资源就结束了。
复习一下动态加载,在plugpicinstall工程中新建一个类DynamicClass.java如下:
package com.example.plugpicinstall; import android.app.Activity; import android.widget.Toast; public class DynamicClass { private Activity mActivity = null; public void init(Activity activity) { this.mActivity = activity; } public void showHello(String name) { Toast.makeText(mActivity,"your name is :"+name, Toast.LENGTH_SHORT).show(); } public void showAddResult(int a,int b) { Toast.makeText(mActivity,"the result is :"+(a+b),Toast.LENGTH_SHORT).show(); } }这个类中定义的方法,就是等会需要加载运行的。
再次将该工程plugpicinstall打包成apk,将该apk放入到sdcard的某一个目录下。
下面是加载该类DynamicClass.java类中方法的代码:
运行showAddResult方法:
String apkPath = "/storage/sdcard0/183/plugpicinstall.apk"; String dexPath = MainActivity.this.getDir("dex",Context.MODE_PRIVATE).getAbsolutePath(); DexClassLoader classLoader = new DexClassLoader(apkPath, dexPath, null, getClassLoader()); try { Class<?> clazz = classLoader.loadClass("com.example.plugpicinstall.DynamicClass"); Object obj = clazz.newInstance(); Method initMeghod = clazz.getDeclaredMethod("init",Activity.class); initMeghod.invoke(obj,MainActivity.this); //利用反射运行showAddResult方法 Class[]params = new Class[2]; params[0] = Integer.TYPE; params[1] = Integer.TYPE; Method showAddMethod = clazz.getDeclaredMethod("showAddResult",params); showAddMethod.invoke(obj, 1,33); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }运行showHello方法:
//apk文件的存放路径 String apkPath = "/storage/sdcard0/183/plugpicinstall.apk"; //dex文件的路径 String dexPath = MainActivity.this.getDir("dex",Context.MODE_PRIVATE).getAbsolutePath(); DexClassLoader classLoader = new DexClassLoader(apkPath, dexPath, null, getClassLoader()); try { //加载需要的类 Class<?> clazz = classLoader.loadClass("com.example.plugpicinstall.DynamicClass"); Object obj = clazz.newInstance(); <span style="white-space:pre"> </span>//利用反射调用init方法,将context对象赋值 Method initMeghod = clazz.getDeclaredMethod("init",Activity.class); initMeghod.invoke(obj,MainActivity.this); //利用反射执行showHello方法,传入一个string参数 Method helloMethod = clazz.getDeclaredMethod("showHello",String.class); helloMethod.invoke(obj,"李磊"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }
好了,至此动态加载已安装和未安装的apk资源就实现了。
原文:http://blog.csdn.net/mockingbirds/article/details/44945865
内容总结
以上是互联网集市为您收集整理的android动态加载已安装和未安装的apk资源全部内容,希望文章能够帮你解决android动态加载已安装和未安装的apk资源所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。