package com.byc.main;import androID.content.Context;import androID.util.Log;import java.io.file;import java.io.fileinputStream;import java.io.fileOutputStream;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import dalvik.system.DexClassLoader;/** *反射调用APK中类的方法 * 1.需要声明权限: * <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE"/> * <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE"/> * 2.targetSdkVersion >21时需要动态申请存储权限; * author:byc6352 create time:2019-07-19 */public class Apk { private static Apk apk; Context mContext;//主app环境; private DexClassLoader dexClassLoader;//apk装载器; private Class<?> clazz;//反射类; private Method method;//反射方法; /** * * @param context:主app上下文环境; */ private Apk(Context context){ this.mContext=context; } public static Apk getApk(Context context){ if (apk==null){ apk=new Apk(context); } return apk; } /** * 装载apk文件 * 注意:必须把apk复制到app应用内存储路径才能调用里面的方法!这里是复制到CacheDir * @param apkPath:apk的外部存储路径; * @return:装载成功与否; */ public boolean loadApk(String apkPath){ String newfilePath= mContext.getCacheDir() + file.separator + "app.apk"; if (!copyfile(apkPath,newfilePath))return false;//app只能调用本app路径内的文件; String dexOutput = mContext.getCacheDir() + file.separator + "DEX";// 优化后的dex存放路径 file file = new file(dexOutput); if (!file.exists()) file.mkdirs(); dexClassLoader = new DexClassLoader(newfilePath, dexOutput, null, mContext.getClassLoader()); return true; } /** * * @param classFullname:类的全路径(必须包括包名)如:如:private static final String APK_HELLO_CLASS_PATH="com.byc.apkresource.HelloWorld"; * @return 装载成功与否; */ public boolean loadClass(String classFullname){ if (dexClassLoader==null)return false; try { clazz = dexClassLoader.loadClass(classFullname);// 从优化后的dex文件中加载APK_HELLO_CLASS_PATH类 return true; } catch (ClassNotFoundException e) { e.printstacktrace(); return false; } } /** * * @param methodname 方法名称; * @param parameterTypes 方法的参数类型;如:String.class,int.class * @return 返回装载成功否; */ public boolean loadMethod(String methodname,Class... parameterTypes){ if (clazz==null)return false; try { //Object object = clazz.newInstance(); // 创建类实例 method = clazz.getmethod(methodname,parameterTypes); // return true; } catch (NoSuchMethodException e) { e.printstacktrace(); return false; } catch (SecurityException e) { e.printstacktrace(); return false; } } /** * 反射调用方法 * @param isstatic 是否是静态方法; * @param var2 方法参数; * @return Object */ public Object invoke(boolean isstatic,Object... var2){ if (method==null)return null; Object object=null; if (!isstatic){ try{ object = clazz.newInstance(); // 创建类实例 }catch (illegalaccessexception e) { e.printstacktrace(); return null; }catch (InstantiationException e) { e.printstacktrace(); return null; } } try{ return method.invoke(object, var2); // 调用 }catch (illegalaccessexception e) { e.printstacktrace(); return null; }catch (IllegalArgumentException e) { e.printstacktrace(); return null; }catch (InvocationTargetException e) { e.printstacktrace(); return null; } } /** * 复制单个文件 * * @param oldpath$name String 原文件路径+文件名 如:data/user/0/com.test/files/abc.txt * @param newPath$name String 复制后路径+文件名 如:data/user/0/com.test/cache/abc.txt * @return <code>true</code> if and only if the file was copIEd; * <code>false</code> otherwise */ public boolean copyfile(String oldpath$name, String newPath$name) { try { file oldfile = new file(oldpath$name); if (!oldfile.exists()) { Log.e("--Method--", "copyfile: oldfile not exist."); return false; } else if (!oldfile.isfile()) { Log.e("--Method--", "copyfile: oldfile not file."); return false; } else if (!oldfile.canRead()) { Log.e("--Method--", "copyfile: oldfile cannot read."); return false; } file newfile = new file(newPath$name); if (newfile.exists()) newfile.delete(); /* 如果不需要打log,可以使用下面的语句 if (!oldfile.exists() || !oldfile.isfile() || !oldfile.canRead()) { return false; } */ fileinputStream fileinputStream = new fileinputStream(oldpath$name); fileOutputStream fileOutputStream = new fileOutputStream(newPath$name); byte[] buffer = new byte[1024]; int byteRead; while (-1 != (byteRead = fileinputStream.read(buffer))) { fileOutputStream.write(buffer, 0, byteRead); } fileinputStream.close(); fileOutputStream.flush(); fileOutputStream.close(); return true; } catch (Exception e) { e.printstacktrace(); return false; } }}/** 使用方法: String apkPath= Environment.getExternalStorageDirectory() + file.separator + "app.apk"; String classname="com.byc.apkresource.HelloWorld"; String methodname="factorial"; Apk apk=Apk.getApk(MainActivity.this); if(apk.loadApk(apkPath)) if(apk.loadClass(classname)) if (apk.loadMethod(methodname,int.class)) { int i= (int) apk.invoke(false,6); tvShow.setText(String.valueOf(i)); // 将结果设置到text上 } */
总结
以上是内存溢出为你收集整理的android 反射调用APK文件中类的方法全部内容,希望文章能够帮你解决android 反射调用APK文件中类的方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)