android 反射调用APK文件中类的方法

android 反射调用APK文件中类的方法,第1张

概述packagecom.byc.main;importandroid.content.Context;importandroid.util.Log;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;im
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文件中类的方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1115787.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存