您当前的位置: 首页 >  ar

暂无认证

  • 3浏览

    0关注

    97423博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

原来Android还可以这样通过反射,获取jar包属性及方法

发布时间:2016-08-03 16:01:13 ,浏览量:3

1、写一个java类,生成Jar包

2、初始Jar的转换

3、创建一个android工程

4、复制Jar包

5、反射获取属性和方法

5、完整Demo

6、补充

 

 

摘要:在Android中可以动态加载,但无法像Java中那样方便动态加载jar

原因:Android的虚拟机(Dalvik VM)是不认识Java打出jar的byte code,需要通过dx工具来优化转换成Dalvik byte code才行。这一点在咱们Android项目打包的apk中可以看出:引入其他Jar的内容都被打包进了classes.dex。所以无法像java对jar文件直接进行的反射。所以要用android sdk 自带的dx.bat (位于\adt-bundle-windows-x86-20131030\sdk\build-tools下)进行 jar-->dex-->jar的过程。

步骤说明:

  1. 1.写一个java类,生成Jar包

publicclass Hello{

publicstatic String Hello(Strings) {

         return s;

}

public String sayHello(){

         return"HelloWorld";

}

}

使用Fatjar工具进行对java类生成jar文件

  1. 2.初始Jar的转换

对于assets目录下一般存放的是大文件,它在随apk打包时,并不会被压缩。我们可以将我们要

转化后的jar(经历过jar-->dex-->jar)放在该目录下。

以我们的多屏互动jar包为例:下面是完成jar-->dex-->jar的过程

命令:dx --dex --output = utils-r1204.jar  utils.jar

Output输出为一个名叫“utils-r1204.jar”的文件,名字可以随便起,把这个输出jar文件放到工程的assets目录下。

  1. 3.创建一个android工程

在activity中的oncreate方法中执行如下操作:

    protectedvoid onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_reflect);

        copyFileToInternalStorage ("utils-r1204.jar");

        jarToReflect();

}

  1. 4.复制Jar包

对输出的utils-r1204.jar进入复制到internal storage(就是data/data/当前工程/files目录下)中去,主要是为了方便反射,就好像我们的db文件通常也要经过这种方式到internal storage中,(另外如果有SD卡,可以直接把utils-r1204.jar拷贝到SD卡,方法是一样的)

public void copyFileToInternalStorage(final String filename) {

        InputStream is = null;

        FileOutputStream fos = null;

File file = new File(getApplicationContext().getFilesDir(), filename);

//getFileDir()目录就是data/data/当前工程/files 目录

if (file.exists()) {

System.out.println("file is exist! cannot to copy again");

} else {

try {

is = getAssets().open(filename);

fos = new FileOutputStream(file);

                   int len = 0;

byte[] buffer = new byte[1024];

while ((len = is.read(buffer)) != -1) {

                        fos.write(buffer, 0, len);

                   }

} catch (Exception e) {

                   e.printStackTrace();

} finally {

try {

is.close();

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

  1. 5.反射获取属性和方法

@SuppressLint("NewApi")

publicvoid jarToReflect(){

         Stringspath=getFilesDir()+"/utils-r1204.jar";

         final File path = new File(spath);

          DexClassLoader dexloader = new DexClassLoader(

path.getAbsolutePath(),

getFilesDir().toString(),

null,

getClassLoader());

          Class libClazz = null;

         try {

              // Load the libraryclass from the class loader.

              libClazz= dexloader.loadClass("com.example.demo.Hello");

              Methodsm=libClazz.getMethod("startHello", new Class[]{String.class});

              Stringsinvoke = (String) sm.invoke(libClazz, new Object[]{"aaaa"});

              System.out.println("sinvoke ="+sinvoke);

              Constructor[]constructors = libClazz.getDeclaredConstructors();

              AccessibleObject.setAccessible(constructors,true);

              for (Constructor con :constructors) {

                   if (con.isAccessible()){

                       ObjectclassObject = con.newInstance();

                   Methodnsm = libClazz.getMethod("sayHello");

                       Stringresult = (String) nsm.invoke(classObject);

                       System.out.println("nsminvoke =" +result);

                   }

              }

              Method[]methods = libClazz.getMethods();         

for (int i = 0; i libClazz = "aaaa"});

关注
打赏
1655516835
查看更多评论
立即登录/注册

微信扫码登录

0.0538s