Android类装载器DexClassLoader的简单使用-----制作android插件的前奏
声明:此篇文章借鉴《android内核剖析》整理得来。
一、装载器简介
“类装载器”(ClassLoader),顾名思义,就是用来动态装载class文件的。标准的Java SDK中有个ClassLoader类,借助此类可以装载需要的class文件,前提是
ClassLoader类初始化必须制定class文件的路径。
import关键字引用的类文件和ClassLoader动态加载类的区别:
import引用类的两个特点:1、必须存在于本地,当程序运行该类时,内部类装载器会自动装载该类。
2、编译时必须在现场,否则编译过程会因找不到引用文件而不能正常编译。
classLoader的特点正好于import相反,而且更自由灵活。
每一个ClassLoader必须有一个父ClassLoader,在装载Class文件时,子ClassLoader会先请求其父ClassLoader加载该文件,只有当其父ClassLoader找不到该文件时,子ClassLoader才会继承装载该类。这是一种安全机制。对于Android而言,最终的apk文件包含的是dex类型的文件,dex文件是将class文件重新打包,打包的规则又不是简单地压缩,而是完全对class文件内部的各种函数表,变量表进行优化,产生一个新的文件,即dex文件。因此加载这种特殊的Class文件就需要特殊的类加载器DexClassLoader。
二、DexClassLoader的方法的实用
假设有两个apk,第一个叫做Host,第二个叫Plugin。Plugin中第一个一个类Plugin,该类中定义了一个addition函数。
package com.david.plugin;
import android.util.Log;
public class Plugin {
private static final String TAG=Plugin.class.getSimpleName();
public Plugin(){
Log.i(TAG, "PluginClass is initialized");
}
public int addition(int a,int b){
return a+b;
}
}
plugin的apk中AndroidManifest文件中,activity必须声明一个action。
<activity
android:name="com.david.plugin.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="com.david.plugin.client"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
将plugin.apk装载进Android设备中。Host.apk中主activity调用的代码如下:
package com.david.host; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List; import dalvik.system.DexClassLoader;
import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; public class MainActivity extends ActionBarActivity implements OnClickListener{ private static final String plugin_package = "com.david.plugin.client";
private PackageManager pm;
private ResolveInfo resolveInfo;
private Button btn_classLoader; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// useDexClassLoader();
btn_classLoader=(Button) findViewById(R.id.btn_classLoader);
btn_classLoader.setOnClickListener(this);
} @SuppressLint("NewApi")
public void useDexClassLoader() {
Intent classIntent = new Intent(plugin_package, null);
pm = getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(classIntent, 0);
resolveInfo = activities.get(0);
ActivityInfo activityInfo = resolveInfo.activityInfo; String div = System.getProperty("path.separator");
String packageName = activityInfo.packageName;
String sourceDir = activityInfo.applicationInfo.sourceDir;
System.out.println(sourceDir);
String outDir = getApplicationInfo().dataDir;
System.out.println(outDir);
String libraryDir = activityInfo.applicationInfo.nativeLibraryDir;
System.out.println(libraryDir); DexClassLoader dexcl = new DexClassLoader(sourceDir, outDir,
libraryDir, this.getClass().getClassLoader());
try {
Class<?> loadClass = dexcl.loadClass(packageName+".Plugin");
Object instance = loadClass.newInstance();
Class[] params = new Class[2];
params[0]=Integer.TYPE;
params[1]=Integer.TYPE;
Method method = loadClass.getMethod("addition", params);
Integer result = (Integer) method.invoke(instance, 12,32);
System.out.println(result);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } @Override
public void onClick(View v) {
useDexClassLoader();
}
}
运行后得到的结果是:

类加载器在应用中还是用到比较多,还可以基于它设计一种“插件”架构。
Android类装载器DexClassLoader的简单使用-----制作android插件的前奏的更多相关文章
- Android中SharedPerforences的简单使用示例 --Android基础
SharedPreferences是Android平台上一个轻量级的存储类,用来保存应用的一些常用配置,比如Activity状态,Activity暂停时,将此activity的状态保存到SharedP ...
- Android系列:res之shape制作
大家好,pls call me francis. nice to me you. 本文将介绍使用在Android中使用shape标签绘制drawable资源图片. 下面的代码是shap标签的基本使用情 ...
- 基于Android平台的图书管理系统的制作(1)
在学习了郭神的第一行代码前半段之后,想通过一次实践来完成对已学知识的巩固.于是码下了这个图书管理系统客户端. IDE Android studio,语言 JAVA.XML: 在刚开始设计的时候对于这个 ...
- Xamarin.Android之Spinner的简单探讨
一.前言 今天用了一下Spinner这个控件,主要是结合官网的例子来用的,不过官网的是把数据写在Strings.xml中的, 某种程度上,不是很符合我们需要的,比较多的应该都是从数据库读出来,绑定上去 ...
- Xamarin.Android之封装个简单的网络请求类
一.前言 回忆到上篇 <Xamarin.Android再体验之简单的登录Demo> 做登录时,用的是GET的请求,还用的是同步, 于是现在将其简单的改写,做了个简单的封装,包含基于Http ...
- [电子书] 《Android编程入门很简单》
<Android编程入门很简单>是一本与众不同的Android学习读物,是一本化繁为简,把抽象问题具体化,把复杂问题简单化的书.本书避免出现云山雾罩.晦涩难懂的讲解,代之以轻松活泼.由浅入 ...
- android复习第一天-----简单的android常识
前言:要去面试了,这些天花一些事件把android中简单的知识点来串联的复习一下 1,android中的工程结构 src文件夹:存储android文件的源代码 gen文件夹:有工具自动生成,不要去修改 ...
- GitHub 上排名前 100 的 Android 开源库进行简单的介绍
若有任何疑问可通过邮件或微博联系我 项目名称 项目简介 1. react-native 这个是 Facebook 在 React.js Conf 2015 大会上推出的基于 JavaScript 的开 ...
- [原创]Android中LocationManager的简单使用,获取当前位置
Android中LocationManager的提供了一系列方法来地理位置相关的问题,包括查询上一个已知位置:注册/注销来自某个 LocationProvider的周期性的位置更新:以及注册/注销接近 ...
随机推荐
- pyplot-常用图表
pyplot-常用图表 介绍最常用的:折线图.散点图.柱状图.直方图.饼图 的绘制 需要学习的不只是如何绘图,更是什么样的数据用什么图表显示效果最好 折线图 折线图用于显示随时间或有序类别的变化趋势 ...
- SpringBoot整合Shiro (二)
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.相比较Spring Security,shiro有小巧.简单.易上手等的优点.所以很多框架都在使用sh ...
- python mysql connector
install pip install mysql-connector-python-rf 报错 从https://dev.mysql.com/downloads/connector/python ...
- vs2010下载Microsoft Visual Studio 2010 Express(vs2010中文版下载)速成官方合集正式版
http://www.xiazaiba.com/html/1832.html VB.NET 2010 Express: 2KQT8-HV27P-GTTV9-2WBVV-M7X96VC++ 2010 E ...
- 早停法(Early Stopping)
一.早停法简介(Early Stopping)当我们训练深度学习神经网络的时候通常希望能获得最好的泛化性能(generalization performance,即可以很好地拟合数据).但是所有的标准 ...
- discuz回贴通知插件实现-获取邮件内容
//自定义钩子函数,命名:模块_函数名_output()或模块_函数名() //一个是模块执行完,模板输出前执行.一个是模块执行前 //post_reply_output函数会在所有post操作中都会 ...
- vc通过webbrowser操作ie元素
1>需要引用 webbrowser2.h,mshtml.h //m_web绑定的webbrowser的变量 CComQIPtr<IHTMLDocument2,&IID_IHTMLD ...
- 【D3D】Direct3D中LPRECT(上左右底)和LPoint(x,y)之前转换
D3DSprite.cpp void CD3DSprite::DrawText(CD3DFont *pFont, char *szString, RECT &DesRect, D3DCOLOR ...
- ThinkPHP5路由图解
- PAT 1083 是否存在相等的差(20)(代码+思路)
1083 是否存在相等的差(20 分) 给定 N 张卡片,正面分别写上 1.2.--.N,然后全部翻面,洗牌,在背面分别写上 1.2.--.N.将每张牌的正反两面数字相减(大减小),得到 N 个非负差 ...