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 <methods.length; i++) {

methods[i].setAccessible(true);//if the method is private,it must be use setAccessible

System.out.println(methods[i].getName());

}

Field[] fields = libClazz.getFields();

for (int i = 0; i < fields.length; i++) {

fields[i].setAccessible(true);//if the field is private,it must be use setAccessible

System.out.println(fields[i].getName());

}

} catch (Exception e) {

e.printStackTrace();

}

}

执行结果如图:

6.完整Demo

package com.example.test.voice.bat;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;

import android.os.Bundle;

import android.annotation.SuppressLint;

import android.app.Activity;

publicclass ReflectActivity extends Activity {

@Override

protectedvoid onCreate(BundlesavedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_reflect);

copyFileToInternalStorage("utils-r1204.jar");

jarToReflect();

}

publicvoidcopyFileToInternalStorage(final String filename) {

InputStreamis = null;

FileOutputStreamfos = null;

Filefile = newFile(getApplicationContext().getFilesDir(), filename);

if (file.exists()) {

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

}else {

try {

is= getAssets().open(filename);

fos= newFileOutputStream(file);

int len = 0;

byte[] buffer = newbyte[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();

}

}

}

}

publicvoid jarToReflect(){

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

//if use SD

// final File path = newFile(Environment.getExternalStorageDirectory().toString()+"/test.jar");

final File path = new File(spath);

DexClassLoader dexloader = new DexClassLoader(

path.getAbsolutePath(),

getFilesDir().toString(),

null,

getClassLoader());

Class<?> libClazz = null;

try {

// Load the library class 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 <methods.length; i++) {

methods[i].setAccessible(true);//if the method is private,it must be use setAccessible

System.out.println(methods[i].getName());

}

Field[] fields = libClazz.getFields();

for (int i = 0; i <fields.length; i++) {

fields[i].setAccessible(true);//if the field is private,it must be use setAccessible

System.out.println(fields[i].getName());

}

}catch (Exception e) {

e.printStackTrace();

}

}

}

7.补充:

1.不需要在本工程里面导出jar,自己新建一个Java工程导出来也行。

如果你觉得好,可以分享此公众号给你更多的人,原创不易。

------------华丽分割线--------------

长按二维码,关注公众号

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

  1. 使用反射获得jar包中的类、方法、参数、返回值类型,然后动态加载jar包运行方法

    其实我的需求是在系统中 测试用户导入的jar包,所有网上找了很多解决方案,踩过很多坑,再加上以前搞c++的,对java不是很熟, 这里特意记录下,算是基本满足需求了 使用反射获得jar包中的类.方法. ...

  2. 【Android 插件化】Hook 插件化框架 ( 通过反射获取 “插件包“ 中的 Element[] dexElements )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  3. 在swt中获取jar包中的文件 uri is not hierarchical

    uri is not hierarchical 学习了:http://blog.csdn.net/zdsdiablo/article/details/1519719 在swt中获取jar包中的文件: ...

  4. 获取jar包内部的资源文件

    通常获取一个资源文件很简单,问题是对于jar包内的资源文件,可能会发生意外.假如这里有一个文件操作的类: public class FileLoader {public boolean exists( ...

  5. android jar 加入图片,Android动态加载外部jar包及jar包中图片等资源文件

    Android动态加载外部jar包及jar包中图片等资源文件 Android应用程序由Java开发,因此Java中许多实用的特性,在Android中也有体现.动态加载Class,也就是外部jar包,在 ...

  6. 关于如何正确地在android项目中添加第三方jar包

                  在android项目中添加第三方jar包虽然不是一个很复杂的问题,但是确实给很多开发者带来了不小的困扰.我自己就曾经碰到过calss not found exception ...

  7. 获取jar包中的文件,及遍历jar包中的文件

    获取jar包中的文件 ClassPathResource resource1 = new ClassPathResource("文件夹" + File.separator + &q ...

  8. Android利用Java反射获取用户手机的rom定制系统及版本,EMUI,MIUI,ColorOS,FunthouchOS等

    Android利用Java反射获取用户手机的rom定制系统版本及版本号,EMUI,MIUI,ColorOS,FunthouchOS等 前言 正文 结语 前言 现在手机厂商都推出了自己的基于Androi ...

  9. java获取jar包中的文件资源

    java获取jar包中的文件资源 一.问题示例 1.1 项目开发时 1.2 打包成jar后 二.解决方案 2.1 解决方法 2.2 实现 问题描述:   我们常常在代码中读取一些资源文件(比如图片,音 ...

  10. Java 覆盖 jar 包内的方法

    背景 有时候在 java 开发过程中会遇到这样的场景,比如说我们需要用 jar 包里的方法,但是 jar 包里的方法又不能满足当前的业务逻辑需要,而想直接下载 jar 包源码修改的话又会很麻烦,这个时 ...

最新文章

  1. 知识点2-对二进制的运用
  2. 如何在SQL Server 2005中使用作业实现备份和特定删除
  3. Halcon资料:image,region,xld三者如何转化和保存
  4. on java 8 学习笔记 2022.2.16
  5. Courses hdu 1083(匹配)
  6. ocp linux 基础要点
  7. 15个著名的设计心理学原理以及在设计中的应用
  8. 15万个监控摄像头被黑,医院、学校、监狱都被看得一清二楚
  9. Xcode里-ObjC, -all_load, -force_load
  10. 网页版本的飞行日志分析平台是_一个轻便的实时日志收集平台wslog
  11. LeetCode Online Judge 题目C# 练习 - Search in Rotated Sorted Array II
  12. 如何更换清华源_树莓派中国软件源
  13. Qt 未找到文件:NMAKE
  14. js如何获取IP地址?教你4种方法
  15. 胡润:马云捐1000亿仍是中国首富,中国10亿美元俱乐部比美国多400人
  16. html实心向右三角形,css 如何在html页面上输出一个左三角形或右三角形呢?
  17. Population and carrying capacity 的第四个阶段:Negative feedback with delay. Overshoot and oscillation
  18. 【山无遮,海无拦】LeetCode题集 线性枚举之最值算法
  19. 几款有意思的html游戏推荐(在线云玩+源码)
  20. 编写程序,用户输入日期,计算该日期是这一年的第几天

热门文章

  1. php httputils,Android 自定义网络加载工具类 HttpURLConnectionUtils
  2. AI_机器学习与深度学习有什么区别?
  3. catkin_make和cmake
  4. 【转】HEIF图片存储格式探秘
  5. (3)《Head First HTML与CSS》学习笔记---CSS入门
  6. Spring WebSocket入门(一) 转载
  7. Linux中vi、vim命令大全
  8. Android 4 编程入门经典
  9. nginx+php简单配置环境
  10. Python自动关机GUI程序