一、 基本概念和注意点

    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

packagecom.dynamic;publicinterfaceIDynamic{publicStringhelloWorld();}

3.1.2  实现类DynamicTest

packagecom.dynamic;publicclassDynamicTestimplementsIDynamic{@OverridepublicStringhelloWorld(){return"HelloWorld!";}}

 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.jardynamic.jar

  3.3  修改调用例子

      修改MainActivity,如下:

@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);mToastButton=(Button)findViewById(R.id.toast_button);//BeforethesecondarydexfilecanbeprocessedbytheDexClassLoader,//ithastobefirstcopiedfromassetresourcetoastoragelocation.//finalFiledexInternalStoragePath=newFile(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);////PerformthefilecopyinginanAsyncTask.////从网络下载需要的dex文件//(newPrepareDexTask()).execute(dexInternalStoragePath);//}else{//mToastButton.setEnabled(true);//}mToastButton.setOnClickListener(newView.OnClickListener(){publicvoidonClick(Viewview){//InternalstoragewheretheDexClassLoaderwritestheoptimizeddexfileto.//finalFileoptimizedDexOutputPath=getDir("outdex",Context.MODE_PRIVATE);finalFileoptimizedDexOutputPath=newFile(Environment.getExternalStorageDirectory().toString()+File.separator+"test.jar");//Initializetheclassloaderwiththesecondarydexfile.//DexClassLoadercl=newDexClassLoader(dexInternalStoragePath.getAbsolutePath(),//optimizedDexOutputPath.getAbsolutePath(),//null,//getClassLoader());DexClassLoadercl=newDexClassLoader(optimizedDexOutputPath.getAbsolutePath(),Environment.getExternalStorageDirectory().toString(),null,getClassLoader());ClasslibProviderClazz=null;try{//Loadthelibraryclassfromtheclassloader.//载入从网络上下载的类//libProviderClazz=cl.loadClass("com.example.dex.lib.LibraryProvider");libProviderClazz=cl.loadClass("com.dynamic.DynamicTest");//LibraryInterfacelib=(LibraryInterface)libProviderClazz.newInstance();IDynamiclib=(IDynamic)libProviderClazz.newInstance();//Displaythetoast!//lib.showAwesomeToast(view.getContext(),"hello世界!");Toast.makeText(MainActivity.this,lib.helloWorld(),Toast.LENGTH_SHORT).show();}catch(Exceptionexception){//Handleexceptiongracefullyhere.exception.printStackTrace();}}});}



更多相关文章

  1. NPM 和webpack 的基础使用
  2. Android(安卓)studio3.x 多渠道打包apk
  3. Android(安卓)P SystemUI之StatusBar UI布局status_bar.xml解析
  4. Android--SoLoader,android动态加载so库
  5. Android(安卓)命令行编译、打包生成apk文件
  6. AIR Native Extension的使用(Android)一 : 打包ane
  7. Ionic 运行报错No resource identifier found for attribute 'ap
  8. Android(安卓)Studio & ADT 快捷键配置文件所在目录,自定义后可导
  9. Android异步加载图像小结 (含线程池,缓存方法)

随机推荐

  1. 第5章 Android常见XML属性解析-更新中
  2. android:Button添加图片
  3. Android系统启动——8 附录2:相关守护进程
  4. Android(安卓)屏幕自适应方向尺寸与分辨
  5. Android(安卓)SDK Android(安卓)NDK Andr
  6. Android使用两个Activity页面切换…
  7. Android(安卓)mainfest文件 android属性
  8. Android(安卓)背景图片平铺
  9. Activity XML 属性详解
  10. travis-ci如何配置android