Android动态加载jar/dex

逆向开发使用dx.jar、d8.jar、baksmali.jar将jar转dex文件,解决requires --min-sdk-version >= 26 (currently 13)问题 逆向开发使用dx.jar、d8.jar、baksmali.jar将jar转dex文件,解决requires --min-sdk-version >= 26 (currently 13)问题 阅读详情


转载:http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html


前言

   在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势。本文对网上Android动态加载jar的资料进行梳理和实践在这里与大家一起分享,试图改善频繁升级这一弊病。

 

声明

  欢迎转载,但请保留文章原始出处:) 

    博客园:http://www.cnblogs.com

    农民伯伯: http://over140.cnblogs.com  

    Android中文翻译组:http://androidbox.sinaapp.com/

 

正文

  一、 基本概念和注意点

    1.1  首先需要了解一点:在Android中可以动态加载,但无法像Java中那样方便动态加载jar

      原因:Android的虚拟机(Dalvik VM)是不认识Java打出jar的byte code,需要通过dx工具来优化转换成Dalvik byte code才行。这一点在咱们Android项目打包的apk中可以看出:引入其他Jar的内容都被打包进了classes.dex。

      所以这条路不通,请大家注意。

 

    1.2  当前哪些API可用于动态加载

      1.2.1  DexClassLoader

        这个可以加载jar/apk/dex,也可以从SD卡中加载,也是本文的重点。

      1.2.3  PathClassLoader  

        只能加载已经安装到Android系统中的apk文件。

 

  二、 准备

    本文主要参考"四、参考文章"中第一篇文章,补充细节和实践过程。

    2.1  下载开源项目

      http://code.google.com/p/goodev-demo

      将项目导入工程,工程报错的话应该是少了gen文件夹,手动添加即可。注意这个例子是从网上下载优化好的jar(已经优化成dex然后再打包成的jar)到本地文件系统,然后再从本地文件系统加载并调用的。本文则直接改成从SD卡加载。

 

  三、实践 

    3.1  编写接口和实现

      3.1.1  接口IDynamic

package com.dynamic;

public  interface IDynamic {
     public String helloWorld();
}

       3.1.2  实现类DynamicTest

复制代码
package com.dynamic;

public  class DynamicTest  implements IDynamic {

    @Override
     public String helloWorld() {
         return "Hello World!";
    }
}
复制代码

 

    3.2  打包并转成dex

      3.2.1  选中工程,常规流程导出即可,如图:

      注意:在实践中发现,自己新建一个Java工程然后导出jar是无法使用的,这一点大家可以根据文章一来了解相关原因,也是本文的重点之一。这里打包导出为dynamic.jar

      (后期修复:打包请不要把接口文件打进来,参见文章末尾后续维护!)

      3.2.2  将打包好的jar拷贝到SDK安装目录android-sdk-windows\platform-tools下,DOS进入这个目录,执行命名:

dx --dex --output=test.jar dynamic.jar

 

    3.3  修改调用例子

      修改MainActivity,如下:

复制代码
    @Override
     public  void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mToastButton = (Button) findViewById(R.id.toast_button);
        
         //  Before the secondary dex file can be processed by the DexClassLoader,
        
//  it has to be first copied from asset resource to a storage location.
//         final File dexInternalStoragePath = new File(getDir("dex", Context.MODE_PRIVATE),SECONDARY_DEX_NAME);
//         if (!dexInternalStoragePath.exists()) {
//             mProgressDialog = ProgressDialog.show(this,
//                     getResources().getString(R.string.diag_title), 
//                     getResources().getString(R.string.diag_message), true, false);
//              //  Perform the file copying in an AsyncTask.
//              //  从网络下载需要的dex文件
//             (new PrepareDexTask()).execute(dexInternalStoragePath);
//         } else {
//             mToastButton.setEnabled(true);
//         }
        
        mToastButton.setOnClickListener( new View.OnClickListener() {
             public  void onClick(View view) {
                 //  Internal storage where the DexClassLoader writes the optimized dex file to.
                
// final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);
                 final File optimizedDexOutputPath =  new File(Environment.getExternalStorageDirectory().toString()
                    + File.separator + "test.jar");
                 //  Initialize the class loader with the secondary dex file.
//                 DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
//                         optimizedDexOutputPath.getAbsolutePath(),
//                         null,
//                         getClassLoader());
                DexClassLoader cl =  new DexClassLoader(optimizedDexOutputPath.getAbsolutePath(),
                    Environment.getExternalStorageDirectory().toString(),  null, getClassLoader());
                Class libProviderClazz =  null;
                
                 try {
                     //  Load the library class from the class loader.
                    
//  载入从网络上下载的类
//                     libProviderClazz = cl.loadClass("com.example.dex.lib.LibraryProvider");
                    libProviderClazz = cl.loadClass("com.dynamic.DynamicTest");
                    
                     //  Cast the return object to the library interface so that the
                    
//  caller can directly invoke methods in the interface.
                    
//  Alternatively, the caller can invoke methods through reflection,
                    
//  which is more verbose and slow.
                    
// LibraryInterface lib = (LibraryInterface) libProviderClazz.newInstance();
                    IDynamic lib = (IDynamic)libProviderClazz.newInstance();
                    
                     //  Display the toast!
                    
// lib.showAwesomeToast(view.getContext(), "hello 世界!");
                    Toast.makeText(MainActivity. this, lib.helloWorld(), Toast.LENGTH_SHORT).show();
                }  catch (Exception exception) {
                     //  Handle exception gracefully here.
                    exception.printStackTrace();
                }
            }
        });
    }
复制代码

 

    3.4  执行结果

     

 

  四、参考文章

    [推荐]在Android中动态载入自定义类

    Android app中加载jar插件

    关于Android的ClassLoader探索

    Android App 如何动态加载类

 

  五、补充

    大家可以看看DexClassLoader的API文档,里面不提倡从SD卡加载,不安全。此外,我也正在组织翻译组尽快把这个命名空间下的几个类都翻译出来,以供大家参考。

    工程下载:这里,Dex文件下载:这里。大家可以直接把Dex文件拷贝到SD卡,然后运行例子。

 

  六、后期维护

    6.1  2011-12-1  修复本文错误

      感谢网友ppp250和liuzhaocn的反馈,基本按照评论2来修改:

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

      6.1.2  导出jar时不能带接口文件,否则会报以下错:

         java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation

      6.1.3  将jar优化时应该重新成jar(jar->dex->jar),如果如下命令:

      dx --dex --output=test.jar dynamic.jar

 

    6.2  2012-3-29  本文升级版:

      Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类

      请大家参照最新的文章来做动态加载!

 

结束 

  除了翻译组的工作和自己本职的工作以外,很难抽时间出来分享一些开发心得,但正所谓挤挤总是有的,欢迎交流!

分类:  Android
dx.jar部分类的用法——以检测https劫持漏洞为例 在ADT的build-tools的目录下,有一个叫做dx.jar的包,这个包可以解析dex文件(目前用到的就是这么多),但是在网上一搜都没看到什么相关接口的资料,只能自己慢慢看(老大给了我很多帮助),算是稍微会了一些相应的接口调用,总结总结,也给需要的朋友一些帮助。 阅读详情

相关推荐

好用的dx.jar 亲测有效

Unable to build: the file dx.jar was not loaded from the SDK folder!

android 动态加载jar包

android 动态加载jar 技术

天燹的博客 2744

安卓dx.jar包

安卓dx开发jar包,安卓启动eclipse报错,提示dx加载错误

Android动态dex下发,Android动态加载jar/dex

前言在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势。本文对网上Android动态加载jar的资料进行梳理和实践在这里与大家一起分享,试图改善频繁升级这一弊病。声明欢迎转载,但请保留文章原始出处:)博客园:http://www.cnblogs.com ...

weixin_42393829的博客 679

Android 中动态加载.jar的实现步骤

首先第一个是 jar 文件的制作,Java 里面直接把 .class 文件打包到 .jar 文件里面就可以了,但是 Android 的 Dalvik VM 是不认 Java 的 byte code 的,所以不能直接这么打包,而要用 dx 工具转成 Dalvik byte code 才可以。当然,dx 工具转了之后,jar 包里面就不 是 .class 文件了,而是 .dex 文件。第二个是,Android 里面虽然也提供了 URLClassLoader 的实现,但是并不能用。要动态加载其它类,可以用的 Class Loader 有: DexClassLoader,PathClassLoader

dx.jar和d8.jar工具

android sdk 的dx.jar和d8.jar工具

android动态加载Jar/dex--原创

背景:开发课题需要对应不同手机,为防止每次更换手机对系统重新开发时间上的浪费。决定把通用的一些功能拿出来,扫描,蓝牙,照相,摄像之类的这些技能,同意开发一个jar动态调用。参考了诸多前辈的网站之后,自己动手写了一下。 相关扫盲: 1. 浅谈Android虚拟机的动态加载技术  2. android动态加载Jar/dex-农民伯伯 3.http://blog.youkuaiyun.com/qq591...

chujingwei的专栏 259

Mac和VScode配置fortran

macOS系统 vscode fortran gfortran 终端

weixin_43047707的博客 2409

android 动态加载jar/dex文件

最近一直在搞android动态加载这一块内容,感觉还是学会到了很多新的东西,下面就分享给大家。    熟悉java的朋友,肯定知道ClassLoader这个东西,我们可以使用ClassLoader去灵活的加载某个类,但是在android中大家有可能会很陌生;大家都知道,android有自己的虚拟机(Dalvik虚拟机),这和Java的JVM还是有区别的,这里我就不做详细的介绍了,不懂得朋友可以在

qiaobusiwolaile的专栏 1019

ERDAS 2022与ArcGIS共存安装教程:如何避免端口冲突(详细配置步骤)

本文提供了一份详细的ERDAS 2022与ArcGIS共存安装教程,核心在于解决两者因FlexNet许可证服务器导致的端口冲突问题。通过分步指导,包括检查现有端口占用、修改ERDAS许可证文件端口号、配置防火墙及客户端设置,确保两款专业GIS与遥感软件能在同一系统上稳定运行。

weixin_29279047的博客 253

Open5GS实战指南:Ubuntu 22.04环境下的5G核心网快速部署

本文提供Open5GS在Ubuntu 22.04环境下部署5G核心网的实战指南,涵盖环境准备、MongoDB配置、核心组件安装、WebUI部署及网络调优等关键步骤。通过详细的安装教程和常见问题解决方案,帮助开发者快速搭建开源5G核心网测试环境。

weixin_29202213的博客 537

android 动态切换aar_Android动态加载jar/dex

前言在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势。本文对网上Android动态加载jar的资料进行梳理和实践在这里与大家一起分享,试图改善频繁升级这一弊病。声明欢迎转载,但请保留文章原始出处:)博客园:http://www.cnblogs.com ...

weixin_39628384的博客 1291

MATLAB新手必看:SVPWM七段式算法仿真全流程解析(附完整代码)

本文为MATLAB新手和电机控制初学者提供了SVPWM七段式算法的完整仿真与代码实现指南。文章详细解析了从扇区判断、矢量作用时间计算到PWM波形生成的全流程,并附带了可直接运行的MATLAB代码,帮助读者在理解FOC控制核心算法的基础上,快速掌握工程仿真与调试技巧。

weixin_29074295的博客 281
上一篇: Android WebView不调用默认的 Browser
下一篇: C语言插件机制(上)
panfengsoftware
博客等级 码龄20年 38粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值