安卓实现动态加载class

前两天与老师讨论到命令模式的使用,提到了类的动态加载,即从外部加载进class。动态加载在之前有看到过,但没有留意,于是今天特意写了个demo测试一下。首先介绍一下类加载器的概念,内容由百度而来。

类加载器的基本概念

  类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java )在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class )。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class 类的一个实例。每个这样的实例用来表示一个 Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。实际的情况可能更加复杂,比如 Java 字节代码可能是通过工具动态生成的,也可能是通过网络下载的。

类加载器的树状组织结构

  Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。系统提供的类加载器主要有下面三个:

  引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。

  扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。

  系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader() 来获取它。

  除了系统提供的类加载器以外,开发人员可以通过继承 java.lang.ClassLoader 类的方式实现自己的类加载器,以满足一些特殊的需求。

需要注意的是,安卓中开发人员可用的类加载只有DexClassLoader和PathClassLoader。并且后者只能加载已经安装了的apk中的class。今天我用到的是DexClassLoader,实现从SD卡中加载class。demo中还用到了反射,对反射不熟悉的朋友可以百度“java 反射”。

首先新建一个安卓工程,按照平时的步骤就可以了,package我设置为com.everlin.loadtest。然后在工程中新建一个包路径:com.everlin.loadtest.jar,在这个包中新建一个JarTest类:

package com.everlin.loadtest.jar;

import android.content.Context;
import android.widget.Toast;

public class JarTest {
	public static void show(Context context){
		Toast.makeText(context, "加载成功!", Toast.LENGTH_LONG).show();
	}
}
接着将该包导出为jar包:在项目浏览器主公点击选择包》File》Export》java》jar file》next》填写导出路径》finish。我导出的文件为test.jar

导出后要将jar包转换为dex:把刚才导出的jar文件复制到你安卓sdk安装路径下的"build-tools\版本\"文件夹下,我电脑的路径是“D:\Program Files\eclipse\android_sdk\build-tools\18.1.0”。

然后在该路径打开命令行窗口,输入“dx --dex --output=保存路径 源路径”。如我的是:“dx --dex --output=my.jar test.jar”。完成后会在这个路径下生成my.jar文件,这个就是处理后的dex。把他复制到模拟器的文件系统中,我放在了“sdcard\everlin\my.jar”。

接下来重新进入eclipse,把刚才那个包删了,目的是为了效果明显,避免读者认为我们待会载入的是apk中的包。然后修改刚才自动生成的MainActivity类:

</pre><p><pre name="code" class="java">package com.everlin.loadtest;

import java.io.File;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//文件系统根目录
		String rootPath = Environment.getExternalStorageDirectory().toString();
		//我放置dex文件的路径
		String dexPath = rootPath + File.separator + "everlin" + File.separator
				+ "my.jar";
		//实例一个DexClassLoader,参数1为文件路径,参数2为处理路径。
		//我试了用文件系统卡的路径,但报错说路径不属于当前用户。查了资料说是因为内置存储的原因。
		//于是改成apk的安装路径,就正常了。
		DexClassLoader cl = new DexClassLoader(dexPath, getDir("dex", 0)
				.getAbsolutePath(), null, getClassLoader());

		try {
			//加载类
			Class<?> test = cl.loadClass("com.everlin.loadtest.jar.JarTest");
			//利用反射,获取这个类的方法
			Method[] methods = test.getDeclaredMethods();
			//执行第一个方法,即JarTest.show()
			methods[0].invoke(null,getApplication());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


 
调试工程,模拟器运行结果如下: 



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
安卓开发中,需要对网络请求或是其他耗时操作进行提示,以提升用户体验。这时候就需要使用到Dialog加载框。 1.创建布局文件 首先在res/layout目录下创建自定义的布局文件dialog_layout.xml,用来定义加载框的内容。例如,可以使用ProgressBar来表示加载动画。 2.创建自定义Dialog 创建自定义的Dialog类,继承自Dialog,重写构造方法,将自定义的布局文件设置给Dialog。在自定义Dialog中,可以定义一些方法来方便在Activity中使用,例如show()和dismiss()方法。 public class LoadingDialog extends Dialog { private Context mContext; private ProgressBar mProgressBar; public LoadingDialog(Context context) { super(context); mContext = context; setContentView(R.layout.dialog_layout); mProgressBar = (ProgressBar) findViewById(R.id.progress_bar); } public void showDialog() { show(); mProgressBar.setVisibility(View.VISIBLE); } public void dismissDialog() { dismiss(); mProgressBar.setVisibility(View.GONE); } } 3.在Activity中调用 在需要使用加载框的Activity中,创建LoadingDialog实例,并调用其showDialog()方法显示加载框。网络请求或其他耗时操作完成后,调用其dismissDialog()方法关闭加载框。 LoadingDialog dialog = new LoadingDialog(this); dialog.showDialog(); //网络请求或其他耗时操作 dialog.dismissDialog(); 通过上述步骤,就可以实现一个简单的Dialog加载框。在实际开发中,可以对Dialog进行自定义,如设置背景、动画效果等,以达到更好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值