andorid动态加载jar

最近研究了下android动态加载jar,下面总结下。

这里使用的eclipse开发测试。

网上介绍原理的很多,请自行百度.

首先需要创建两个工程,一个是生成需要的jar的工程,一个是实际测试用的工程

接口类工程中建两个包如下图:


IDynamic.java内容如下:

package com.dynamic.interfaces;  
import android.app.Activity;  

public interface IDynamic {  
	public int cal(int a,int b);
	public String test();
} 
Dynamic.java内容如下:
package com.dynamic.impl;

import android.app.Activity;
import android.util.Log;
import android.widget.Toast;

import com.dynamic.interfaces.IDynamic;

public class Dynamic implements IDynamic{
	@Override
	public int cal(int a, int b) {
		// TODO Auto-generated method stub
		return (a * b);
	}

	@Override
	public String test() {
		// TODO Auto-generated method stub
		return "this is Dynamic test1";
	}
}
然后分别导出这两个文件为jar
选中IDynamic.java右键点击导出JAR FILE,导出文件名为jarint.jar
注意导出的时候只需要选这一个文件
同样选中Dynamic.java右键点击导出JAR FILE,导出文件名为jartest.jar
注意导出的时候只需要选这一个文件
将jartest.jar拷贝到sdk目录中的build-tools中的对应的api目录中,例如我的是
build-tools\22.0.1
然后在命令行进行这个目录:

执行dx --dex --out dex.jar jartest.jar如下图(注意:中间的--为两个"-")

然后将生成的dex.jar push到系统/sdcard目录下(,我的这个sdcard目录为内部存储挂载路径,我测试的是有root权限的所以可以这么整,没权限的还是通过TF卡)
这两个jar过会需要使用
实际测试应用内容如下:

需要将上面导出的jarint.jar放在这个工程的libs目录下
Main.java内容如下:

package com.example.jartest;

import java.io.File;
import java.util.List;

import com.dynamic.interfaces.IDynamic;

import android.app.Activity;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import dalvik.system.DexClassLoader;
import dalvik.system.PathClassLoader;

public class Main extends Activity {
	public final static String TAG = "jartest";
	final private String BasePath = "/sdcard";//"/storage/sdcard1";
	private IDynamic lib;  
	String jarpath = BasePath + "/dex.jar";
	String packname = "com.dynamic.impl";
	private Button mytest;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mytest = (Button)findViewById(R.id.mytest);
		
		Log.d(TAG, "jarpath: " + jarpath);
		File jar = new File(jarpath);
		if(!jar.exists()) {
			Log.d(TAG, "++jar file not found");
			return;
		}
		
		mytest.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				DexLoader();
				//PathLoader();
			}
		});
	}
	
	private void PathLoader() {
		Intent intent = new Intent(packname, null); 
		PackageManager pm = getPackageManager();    
		List<ResolveInfo> resolveinfoes =  pm.queryIntentActivities(intent, 0);    
		Log.d(TAG, "list: " + resolveinfoes.size());
		ActivityInfo actInfo = resolveinfoes.get(0).activityInfo;    
		String apkPath = actInfo.applicationInfo.sourceDir;    
		String libPath = actInfo.applicationInfo.nativeLibraryDir;    
		Log.d(TAG, "apkPath: " + apkPath);
		Log.d(TAG, "libPath: " + libPath);
        PathClassLoader pcl = new PathClassLoader(apkPath,libPath,this.getClassLoader()); 
        try {
			Class libProviderClazz = pcl.loadClass("com.dynamic.impl.Dynamic");
			lib = (IDynamic)libProviderClazz.newInstance();
            if(lib != null){  
            	Log.d(TAG, "---:" + lib.test());
            	Log.d(TAG, "---cal :" + lib.cal(1,2));
            }  else
            	Log.d(TAG, "++lib is null");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			Log.d(TAG, e.getMessage());
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			Log.d(TAG, e.getMessage());
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			Log.d(TAG, e.getMessage());
			e.printStackTrace();
		}
	}
	
	private void DexLoader() {
		File dexOutputDir = this.getDir("dex", 0);
		String tmpPath = dexOutputDir.getAbsolutePath();
		Log.d(TAG," tmpPath: " + tmpPath);
		DexClassLoader cl = new DexClassLoader(jarpath,tmpPath,null,this.getClassLoader());
		try {
			Class libProviderClazz = cl.loadClass("com.dynamic.impl.Dynamic");
			lib = (IDynamic)libProviderClazz.newInstance();  
            if(lib != null){  
            	Log.d(TAG, "---:" + lib.test());
            	Log.d(TAG, "---cal :" + lib.cal(1,2));
            }  else
            	Log.d(TAG, "++lib is null");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			Log.d(TAG, e.getMessage());
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			Log.d(TAG, e.getMessage());
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			Log.d(TAG, e.getMessage());
			e.printStackTrace();
		}
	}
}
注意:使用DexLoader即使用DexClassLoader类加载,如果dex.jar是放在内部存储路径或者外部存储中,需要加相应的权限:
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
如果使用PathLoader即使用PathClassLoader加载,需要在接口类我的为JarInterface的AndroidManifest.xml中增加对应的包名:

<action android:name="com.dynamic.impl"/>
修改后如下:
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
				<action android:name="com.dynamic.impl"/>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

不然调用不会成功


相关源码下载地址:http://download.csdn.net/download/hclydao/9928304

本来没准备要下载分的,但是没看到0分的选项,最少只有1分.
参考文章: http://blog.csdn.net/jiangwei0910410003/article/details/17679823

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值