Android插件化开发之DexClassLoader动态加载dex、jar小Demo

一、温故动态加载ClassLoader机制

如果对Android的ClassLoader加载机制不熟悉,猛戳Android插件化开发动态加载基础之ClassLoader工作机制 http://blog.csdn.net/u011068702/article/details/53248960

二、介绍

         我们知道在Android中可以跟java一样实现动态加载jar,但是Android使用德海Dalvik VM,不能直接加载java打包jar的byte code,需要通过dx工具来优化Dalvik bytecode。
         Android在API中给出可动态加载的有:DexClassLoader 和 PathClassLoader(上面连接已经详细介绍)
         DexClassLoader:可加载jar、apk和dex,可以从SD卡中加载(这篇博客采用这种方式)

 

         PathClassLoader:只能加载已经安装搭配Android系统中的apk文件

 

三、曝Demo照片,不要怕,不多,很简单

四、编写接口文件

package com.example.testclassloader;public interface ShowString {public String sayChenyu();
}


五、编写接口实现文件

package com.example.testclassloader;import android.util.Log;public class ShowStringClass implements ShowString{public static final String TAG = "ShowStringClass";@Overridepublic String sayChenyu() {String chenyu = "chenyu";Log.i(TAG, chenyu);return chenyu;}}
 

六、打包成jar文件编译成dex

我们把ShowStringClass.java文件打包生成showStringClass.jar文件,然后把文件放到sdk目录下的build-tools下的23.0.1目录下,我用的是ubuntu,所以会看到dex文件,如果是window会在这个目录下看到dex.bat文件,然后用下面命令把showStringClass.jar生成showStringClass_imle.jar的dex文件
dx --dex --output=showStringClass_impl.jar showStringClass.jar
然后再把showStringClass_impl.jar文件放到手机目录里面去用这个命令
adb push showStringClass_impl.jar  /sdcard/
具体操作图片如下

 

七、然后编写MainActivity.java文件

package com.example.testclassloader;import java.io.File;import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.TextView;
import dalvik.system.DexClassLoader;public class MainActivity extends ActionBarActivity {public static final String TAG = "MainActivityClassLoader";public static final String SHOWSTRINGCLASS = "showStringClass_impl.jar";public static final String SHOWSTRINGCLASS_PATH= "com.example.testclassloader.ShowStringClass";public static final String DEX = "dex";public ShowStringClass mShowStringClass = null;public TextView mTv =  null;public int i = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mTv = (TextView)findViewById(R.id.hello);DexClassLoader(this);}/*** 使用DexClassLoader方式加载类*/public void  DexClassLoader(Context context) {// dex压缩文件的路径(可以是apk,jar,zip格式)String dexPath = Environment.getExternalStorageDirectory().toString() + File.separator + SHOWSTRINGCLASS;// dex解压释放后的目录String dexOutputDirs = Environment.getExternalStorageDirectory().toString();//指定dexoutputpath为APP自己的缓存目录File dexOutputDir = context.getDir(DEX, 0);// 定义DexClassLoader// 第一个参数:是dex压缩文件的路径// 第二个参数:是dex解压缩后存放的目录// 第三个参数:是C/C++依赖的本地库文件目录,可以为null// 第四个参数:是上一级的类加载器//DexClassLoader dexClassLoader = new DexClassLoader(dexPath,dexOutputDirs,null,getClassLoader());DexClassLoader dexClassLoader = new DexClassLoader(dexPath,dexOutputDir.getAbsolutePath(),null,getClassLoader());Class libProvierClazz = null;// 使用DexClassLoader加载类try {libProvierClazz = dexClassLoader.loadClass(SHOWSTRINGCLASS_PATH);// 创建dynamic实例mShowStringClass = (ShowStringClass) libProvierClazz.newInstance();if (mShowStringClass != null) {final String chenyu = mShowStringClass.sayChenyu();if (chenyu != null) {mTv.post(new Runnable() {@Overridepublic void run() {mTv.setText(chenyu);}});}} else {Log.d(TAG, "mShowStringClass is null");}} catch (Exception e) {e.printStackTrace();}}/*** 打印系统的classLoader*/public void showClassLoader() {ClassLoader classLoader = getClassLoader();if (classLoader != null){Log.i(TAG, "[onCreate] classLoader " + i + " : " + classLoader.toString());while (classLoader.getParent()!=null){classLoader = classLoader.getParent();Log.i(TAG,"[onCreate] classLoader " + i + " : " + classLoader.toString());i++;}}}
}
	@Overridepublic void run() {mTv.setText(chenyu);}});}} else {Log.d(TAG, "mShowStringClass is null");}} catch (Exception e) {e.printStackTrace();}}/*** 打印系统的classLoader*/public void showClassLoader() {ClassLoader classLoader = getClassLoader();if (classLoader != null){Log.i(TAG, "[onCreate] classLoader " + i + " : " + classLoader.toString());while (classLoader.getParent()!=null){classLoader = classLoader.getParent();Log.i(TAG,"[onCreate] classLoader " + i + " : " + classLoader.toString());i++;}}}
}
 

八、运行Demo的结果爆照

ubuntu终端打印结果如下
手机上面照片如下
说明加载外部的文件加载成功了
如果把上面那行代码改成这个
DexClassLoader dexClassLoader = new DexClassLoader(dexPath,dexOutputDirs,null,getClassLoader());
会报下面的错误
需要加上缓存Dex文件的目录
      //指定dexoutputpath为APP自己的缓存目录File dexOutputDir = context.getDir(DEX, 0);

九、总结

1、加深动态加载的理解
2、如何实现项目加载外部的Dex文件有了更好的理解
3、对DexClassLoader 、dexClassLoader.load(package.class)、 class.newInstance() 有了更好的理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292481.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js监听多个事件_JavaScript中的事件与异常捕获解析

这篇文章主要给大家介绍了关于JavaScript中事件与异常捕获的相关资料,文中通过示例代码介绍的非常详细,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。事件处理…

GDUFE ACM-1045

题目:http://acm.gdufe.edu.cn/Problem/read/id/1045 Elevator Time Limit: 2000/1000ms (Java/Others) Problem Description: The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote a…

mongodb的IO测试工具 mongoperf

之前没发现mongoperf这个工具&#xff0c;测试IO的状态用的是iostat来进行观察。 mongoperf < myjsonconfigfile echo "{nThreads:2,fileSizeMB:20,w:true,r:true}" | mongoperf参数示列如下&#xff1a; {nThreads:<n>, fileSizeMB:<n>, sleepMicros…

C#多线程开发-使用并发集合

前言大家好&#xff0c;我是阿辉。在C#语言中当需要处理并发的场景时&#xff0c;就需要程序员使用最合理的数据结构。那么哪些数据结构是支持和可以在并行计算中被使用的呢。首先这些数据结构具备可伸缩性&#xff0c;尽可能地避免锁(会造成多个线程的等待&#xff0c;防止资源…

Android之用sharedUserId来实现不同应用(APK)数据共享

android:sharedUserId 当APK安装的时候&#xff0c;userid这个标志就会产生。APK在设备上的整个生命周期中&#xff0c;这个ID不再改变。不同设备上同一个应用包可能有不同的userid&#xff0c;重要的是在给定的设备上&#xff0c;每个应用包有自己独立的userid。 userid的特点…

windows 下安装wamp环境

一直以来都是学习在Linux下安装lanmp环境&#xff0c;在Windows下都是用的集成工具比如appserv现在来安装Windows版本的lamp都是从官网下载的资源在Windows下以后还会编辑更多的东西。我的文章都会以后都有更新&#xff0c;因为有时候有点想法&#xff0c;如果不实践的话会忘记…

python编程发展_编程的发展史及Python简介

一.编程语言演变史编程语言分为三类&#xff0c;分别是机器语言&#xff0c;汇编语言和高级程序语言。1.机器语言&#xff1a;用0和1表示二进制跟计算机进行直接的沟通交流&#xff0c;对硬件进行直接操作。2.汇编语言&#xff1a;用简单的英文标签来表示二进制数&#xff0c;对…

iOS ShareSDK 使用

流量精灵软件中&#xff0c;也在大部分地方使用到了shareSDK 这个三方开源库。具体的有两种需求 a、弹出所有分享模块 b、只弹出指定的平台&#xff1a;如微信朋友圈和QQ 。 配置方法&#xff0c;三方库中也很详细&#xff0c;这里我只有写出自出自己代码实现的部分 这里只写自…

应用环境下的TIME_WAIT和CLOSE_WAIT

转载自&#xff1a;http://blog.csdn.net/shootyou/article/details/6622226 昨天解决了一个HttpClient调用错误导致的服务器异常&#xff0c;具体过程如下&#xff1a;http://blog.csdn.net/shootyou/article/details/6615051里头的分析过程有提到&#xff0c;通过查看服务器网…

当社恐和社恐相亲时,场面会有多尴尬?

1 俄国人真实在&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 alone和lonely的区别&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 她可能怕她男朋友伤害到别人&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 真正的笋到家了&#xff08;…

FlexPod上安装vSphere 5.5配置中的排错(1)

delxu原创文档&#xff0c;转发请一定要标记本文出处和原文URL。 这些日子在进行FlexPod上的vSphere 5.5的安装和配置&#xff0c;过程中遇到一些故障、困难&#xff0c;都一一解决了。觉得有必要和大家分享一下。可能会有好多篇&#xff0c;也可能和以前一样&#xff0c;虎头蛇…

Android插件化开发之动态加载三个关键问题详解

本文摘选自任玉刚著《Android开发艺术探索》&#xff0c;介绍了Android插件化技术的原理和三个关键问题&#xff0c;并给出了作者自己发起的开源插件化框架。 动态加载技术&#xff08;也叫插件化技术&#xff09;在技术驱动型的公司中扮演着相当重要的角色&#xff0c;当项目越…

python正十三边形_一起学python-opencv十三(直方图反向投影和模板匹配)

2D直方图https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_histograms/py_2d_histogram/py_2d_histogram.html#twod-histogram为什么只考虑h,s就够了呢&#xff1f;因为其实亮度是很容易受外界影响的&#xff0c;我们认为一个颜色的本质特…

Laravel 学习笔记之 Query Builder 源码解析(下)

说明&#xff1a;本文主要学习下Query Builder编译Fluent Api为SQL的细节和执行SQL的过程。实际上&#xff0c;上一篇聊到了\Illuminate\Database\Query\Builder这个非常重要的类&#xff0c;这个类含有三个主要的武器&#xff1a;MySqlConnection, MySqlGrammar, MySqlProcess…

退出Activity(转)

退出Activity如何退出Activity&#xff1f;如何安全退出已调用多个Activity的Application&#xff1f; 退出activity 直接调用 finish () 方法 . //用户点击back键 就是退出一个activity 退出activity 会执行 onDestroy()方法 . 1、抛异常强制退出&#xff1a; 该方法通过抛异…

更方便地模拟 Http 响应

更方便地 Mock Http ResponseIntro在我们的业务代码中往往会有很多调用内部其他 team 或者是第三方的一些服务&#xff0c;在编写单元测试代码时&#xff0c;往往需要 Mock Http Response 来模拟更好可能的返回结果&#xff0c;我封装了一个简单的 Http Handler 来简化 Mock 过…

xmanager远程桌面控制linux

更多博文请关注&#xff1a;没有伞的孩子必须努力奔跑(www.xuchanggang.cn)一、在linux端配置1.默认&#xff0c;你安装好系统gdm已经安装&#xff0c;不做解释2.配置gdm(1).修改 /etc/gdm/custom.conf 文件&#xff0c;替换为下面内容[daemon] RemoteGreeter/usr/libexec/gdmg…

男人的快乐可以多简单?

1 说不出哪里像但是非常像&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 质量不错&#xff0c;就是风大不建议穿&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 谈恋爱的要求&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 当给狗狗看了捕…

Android插件化开发之用DexClassLoader加载未安装的APK资源文件来实现app切换背景皮肤

第一步、先制做一个有我们需要的图片资源的APK 如下图&#xff0c;这里有个about_log.png,我们需要生成apk文件。生成的apk文件如果你不到项目的文件夹里面去取apk&#xff0c;想通过命令放到手机里面去可以快速用下面命令 1&#xff09;、在手机里面通过包名找到apk路径&…