动态加载APK原理分享(dexmaker)

插件化研究代之dexmaker动态生成Activity 文章首发:插件化研究代之dexmaker动态生成Activity|大利猫最近在研究Android应用的插件化开发, 插件化都是在解决以下几个问题: * 如何把插件apk中的代码和资源加载到当前虚拟机。 * 如何把插件apk中的四大组件注册到进程中。 * 如何防止插件apk中的资源和宿主apk中的资源引用冲突。我们已经解决了如何把apk中的代码和资源加载到当前应用的问题,上一篇文章中使用代理的 阅读详情

项目地址:https://github.com/houkx/android-pluginmgr/ 欢迎star and fork

(一) 综述

    随着智能手机硬件性能的逐步提升,移动应用也做的越来越复杂,android平台上应用的apk包体积也越来越大,然后同类产品开始比拼谁的体积小,实现方案呢,然后很容易想到"插件化",也就是说可以发布内核很小的产品,随着添加功能的需求而动态下载功能模块,促使插件化的另一个动机是App应用固有的问题,那就是很多组件需要注册,更新功能的话不能像Web应用那样可在用户无察觉的情况下通过升级服务器而方便升级,只能弹出个框让用户重新下载整个程序包,然后调取系统安装流程。
 
    被加载的apk称之为插件,因为机制类似于生物学的"寄生",加载了插件的应用也被称为宿主。
往往不是所有的apk都可作为插件被加载,往往需要遵循一定的"开发规范",还需要插件项目引入某种api类库,业界通常都是这么做的。
这里介绍一种无须规范限制的动态加载解决方案,插件不需要依赖任何API,这也是本人突发异想,灵感所致。


(二)功能介绍

      特点:
  •      插件为普通apk,无须依赖任何jar
  •     Activity生命周期由系统自己管理
  •     使用简单,只需要了解一个类PluginManager的两个方法
  •     启动Activity的效率高
  •     不修改插件,被加载的插件仍然可以独立安装。
     功能点:
  1. 可加载任意apk中的 Activity (包括子类 ActionBarActivity 、FragmentActivity)的派生类(不包括违反限制条件的Activity)
  2. 支持插件自定义Application
  3. 支持插件Apk中的Activity跳转到别的Activity(插件内部的或系统的,外部已安装apk的,甚至是别的插件中的),也没有任何限制
  4. 支持Activity设置主题(与系统的主题应用规则一样,如果Activity没指定Theme,但所在Application指定了Theme,则使用Application的Theme)
  5. 初步支持.so
  6. 支持插件使用 SharedPreference 或 SQLite数据库(尚未完善)

 

(ps:

第一个插件代码来自 https://github.com/viacheslavtitov/NDKBegining

作者是个老外,不过也比较粗心,要正常运行你需要在sd卡下创建目录:FFMPEG

第二个插件代码来自这篇博文:http://blog.youkuaiyun.com/caihanyuan/article/details/7367351

第三个插件代码来自大名鼎鼎的 PullToRefresh :

https://github.com/johannilsson/android-pulltorefresh

第6第7个插件代码是自测项目,分别测试ActionBarActivity和Activity基本加载和跳转
其他apk还没能正常加载,框架还在不断完善中,不过腾讯的开心消消乐可以帮助记录crashlog,这点真不错~

)


将要支持的特性:
        PackageManager service 等等,详情都列在开源项目android-pluginmgr
  https://github.com/houkx/android-pluginmgr/tree/experiment/android-pluginmgr下的TODO文件中

(ps:修正项目主页README描述的限制条件1,目前已经没有这个限制了,在插件中调用context.getPackageName()返回插件的清单文件中声明的包名)
限制条件(永不支持的):
  •   插件apk中不能假定自己已经安装,以及由此造成的影响,比如认为applicationInfo.dataDir==/data/data/packageName
  •           不能依赖清单文件中的进程声明,被加载的apk以及里面的任何组件目前都在同一个进程管理。
  •   插件中的权限,无法动态注册,插件中的权限都得在宿主中注册(暂无解决方案)

(三) 实现

    动态加载需要处理很多问题,虽然有很多问题,但是核心问题就是加载Activity,因为Activity是可见的,人们对可以看到的东西总是那么重视,视觉信息占人所处理信息的90%以上。
Activity如何调起来?资源的加载等等已经有大牛的文章介绍汗牛充栋了,我本菜鸟,不再赘述。 
目前Activity的加载或许有很多处理方式,但是可以分为两种:一是自己new 二是系统new 。很多动态加载框架基于第一种方式。我这个方案基于第二种
,既然要系统new,就要系统自己可以找到相应的Activity. 由于Activity需要在清单文件注册了才能使用,所以要注册Activity,但是如何注册呢?
我在网上看到有人用极端的方式:插件里的所有Activiy都在宿主里注册,既然宿主总要修改升级,何必要插件呢,这已经违背了动态加载的初衷:不修改框架而动态扩展功能更多的是这么做,注册一个Activity基类,供插件中的Activity继承,在这个基类里做动态加载的核心逻辑,这就要求插件必须依赖某种API类库。
我的方案通俗的说是这样,依赖倒转,不让插件依赖框架API,而是反过来,自动生成一个Activity类依赖(继承)插件中的Activity,这个自动生成的类就叫PluginActivity
并且声明在框架的清单文件中,如下: 
<activity name="androidx.pluginmgr.PluginActivity" /> 
聪明的读者会想,等一下,插件里面Activity可不止一个,你就注册一个?
是的,就一个,自动生成的Activity类名都是androidx.pluginmgr.PluginActivity,不过放在不同的文件中,最简单的映射,原始Activity类名.dex文件中存储对应的子类:PluginActivity
其实也是偷梁换柱了,如果你想启动插件里的Activity,如com.test.MyPlugActivity, 我就把启动目标修改为androidx.pluginmgr.PluginActivity类,
然后从com.test.MyPlugActivity.dex文件中找到 public class androidx.pluginmgr.PluginActivity extends com.test.MyPlugActivity{....}
以启动SthActivity为例:



好了,核心思想已经表达清楚了,下面介绍如何让系统按你说的路径去找类文件,这涉及到类加载器。自定义类加载器比较简单,继承java.lang.ClassLoader即可.
在我的开源项目源码中对应的类是 FrameworkClassLoader, PluginManager初始化时就去修改Application的类加载器,替换为 FrameworkClassLoader.
FrameworkClassLoader 其实不干什么实际加载工作,只是分发任务:
            public Class loadClass(String className){
  if(当前上下文插件不为空) {
      if( className 是 PluginActivity){
          找到当前实际要加载的原始 Activity
         return  使用插件对应的 ActivityClassLoader 从 (自动生成的)原始Activity类名.dex 文件 加载PluginActivity
      }else{
         return  使用对应的 PluginClassLoader 加载普通类
      }  
   }else{
         return super.loadClass()//即委派给宿主Application的原始类加载器加载
   }   
}
  其中, PluginClassLoader 是一个DexClassLoader, parent 指向 FrameworkClassLoader,
  ActivityClassLoader 也是一个DexClassLoader, parent 指向 PluginClassLoader
  

  插图2(类加载器结构图):


  
[java]  view plain  copy
  1. package androidx.pluginmgr;  
  2.   
  3.   
  4. import android.util.Log;  
  5.   
  6.   
  7. /** 
  8.  * 框架类加载器(Application 的 classLoder被替换成此类的实例) 
  9.  *  
  10.  * 
  11.  */  
  12. class FrameworkClassLoader extends ClassLoader {  
  13.     private String[] plugIdAndActname;//代表插件上下文  
  14.   
  15.   
  16.     public FrameworkClassLoader(ClassLoader parent) {  
  17.         super(parent);  
  18.     }  
  19.     //在外部或插件内部的 startActivity 时调用这个方法设置插件上下文  
  20.     String newActivityClassName(String plugId, String actName) {  
  21.         plugIdAndActname = new String[] { plugId, actName };  
  22.         return ActivityOverider.targetClassName;//targetClassName即宿主manifest配置的androidx.pluginmgr.PluginActivity  
  23.     }  
  24.   
  25.   
  26.     protected Class<?> loadClass(String className, boolean resolv)  
  27.             throws ClassNotFoundException {  
  28.         Log.i("cl", "loadClass: " + className);  
  29.         String[] plugIdAndActname = this.plugIdAndActname;  
  30.         Log.i("cl", "plugIdAndActname = " + java.util.Arrays.toString(plugIdAndActname));  
  31.         if (plugIdAndActname != null) {  
  32.             String pluginId = plugIdAndActname[0];  
  33.               
  34.             PlugInfo plugin = PluginManager.getInstance().getPluginById(  
  35.                     pluginId);  
  36.             Log.i("cl", "plugin = " + plugin);  
  37.             if (plugin != null) {  
  38.                 try {  
  39.                     if (className.equals(ActivityOverider.targetClassName)) {  
  40.                         String actClassName = plugIdAndActname[1];//被(继承)代理的Activity类名  
  41.                         return plugin.getClassLoader().loadActivityClass(  
  42.                                 actClassName);// 加载动态生成的Activity类  
  43.                     }else{  
  44.                         return plugin.getClassLoader().loadClass(className);//加载普通类  
  45.                     }  
  46.                 } catch (ClassNotFoundException e) {  
  47.                     e.printStackTrace();  
  48.                 }  
  49.             }  
  50.         }  
  51.           
  52.         return super.loadClass(className, resolv);  
  53.     }  
  54. }  


到此为止,一个动态加载框架的核心雏形已经有了,但是还有许多细节待完善。

------------------------------------------------------------------------------------------------------------------------

附加:另外,关于动态生成类,对于davikvm环境,我所知道的工具有asmdex和dexmaker,我在项目中选用的是dexmaker

用什么不是重点,看生成的代码吧:(ActivityOverider 类负责与自动生成的Activity类交互)

[java]  view plain  copy
  1. package androidx.pluginmgr;  
  2.   
  3. import android.content.ComponentName;  
  4. import android.content.Intent;  
  5. import android.content.ServiceConnection;  
  6. import android.content.res.AssetManager;  
  7. import android.content.res.Resources;  
  8. import android.os.Bundle;  
  9. import androidplugdemo.SthActivity;  
  10.   
  11. public final class PluginActivity  
  12.   extends SthActivity  
  13. {  
  14.   private static final String _pluginId = "activityTest_v1";  
  15.   private AssetManager mAssertManager;  
  16.   private Resources mResources;  
  17.     
  18.   public boolean bindService(Intent paramIntent, ServiceConnection paramServiceConnection, int paramInt)  
  19.   {  
  20.     return ActivityOverider.overrideBindService(this, _pluginId, paramIntent, paramServiceConnection, paramInt);  
  21.   }  
  22.     
  23.   public AssetManager getAssets()  
  24.   {  
  25.     AssetManager localAssetManager = this.mAssertManager;  
  26.     if (localAssetManager == null) {  
  27.       localAssetManager = super.getAssets();  
  28.     }  
  29.     return localAssetManager;  
  30.   }  
  31.     
  32.   public Resources getResources()  
  33.   {  
  34.     Resources localResources = this.mResources;  
  35.     if (localResources == null) {  
  36.       localResources = super.getResources();  
  37.     }  
  38.     return localResources;  
  39.   }  
  40.     
  41.   public void onBackPressed()  
  42.   {  
  43.     if (ActivityOverider.overrideOnbackPressed(this, _pluginId)) {  
  44.       super.onBackPressed();  
  45.     }  
  46.   }  
  47.     
  48.   protected void onCreate(Bundle paramBundle)  
  49.   {  
  50.     String str = _pluginId;  
  51.     AssetManager localAssetManager = ActivityOverider.getAssetManager(str, this);  
  52.     this.mAssertManager = localAssetManager;  
  53.     Resources localResources = super.getResources();  
  54.     this.mResources = new Resources(localAssetManager, localResources.getDisplayMetrics(), localResources.getConfiguration());  
  55.     ActivityOverider.callback_onCreate(str, this);  
  56.     super.onCreate(paramBundle);  
  57.   }  
  58.     
  59.   protected void onDestroy()  
  60.   {  
  61.     String str = _pluginId;  
  62.     super.onDestroy();  
  63.     ActivityOverider.callback_onDestroy(str, this);  
  64.   }  
  65.     
  66.   protected void onPause()  
  67.   {  
  68.     String str = _pluginId;  
  69.     super.onPause();  
  70.     ActivityOverider.callback_onPause(str, this);  
  71.   }  
  72.     
  73.   protected void onRestart()  
  74.   {  
  75.     String str = _pluginId;  
  76.     super.onRestart();  
  77.     ActivityOverider.callback_onRestart(str, this);  
  78.   }  
  79.     
  80.   protected void onResume()  
  81.   {  
  82.     String str = _pluginId;  
  83.     super.onResume();  
  84.     ActivityOverider.callback_onResume(str, this);  
  85.   }  
  86.     
  87.   protected void onStart()  
  88.   {  
  89.     String str = _pluginId;  
  90.     super.onStart();  
  91.     ActivityOverider.callback_onStart(str, this);  
  92.   }  
  93.     
  94.   protected void onStop()  
  95.   {  
  96.     String str = _pluginId;  
  97.     super.onStop();  
  98.     ActivityOverider.callback_onStop(str, this);  
  99.   }  
  100.     
  101.   public void startActivityForResult(Intent paramIntent, int paramInt, Bundle paramBundle)  
  102.   {  
  103.     super.startActivityForResult(ActivityOverider.overrideStartActivityForResult(this, _pluginId, paramIntent, paramInt, paramBundle), paramInt, paramBundle);  
  104.   }  
  105.     
  106.   public ComponentName startService(Intent paramIntent)  
  107.   {  
  108.     return ActivityOverider.overrideStartService(this, _pluginId, paramIntent);  
  109.   }  
  110.     
  111.   public boolean stopService(Intent paramIntent)  
  112.   {  
  113.     return ActivityOverider.overrideStopService(this, _pluginId, paramIntent);  
  114.   }  
  115.     
  116.   public void unbindService(ServiceConnection paramServiceConnection)  
  117.   {  
  118.     ActivityOverider.overrideUnbindService(this, _pluginId, paramServiceConnection);  
  119.   }  
  120. }  
项目地址: https://github.com/houkx/android-pluginmgr/ 欢迎 star and  fork
dexmaker:一个实用程序,用于针对Android的Dalvik VM进行编译或运行时代码生成 敏捷制作人 Java语言API,用于针对Dalvik VM进行编译时或运行时代码生成。 与或不同,此库创建Dalvik .dex文件而不是Java .class文件。 它具有一个接近金属的小型API。 该API反映了使您可以严格控制所发出的字节码。 代码是逐条指令生成的; 如果需要,您可以带上自己的抽象语法树。 由于它使用Dalvik的dx工具作为后端,因此您可以免费有效地进行寄存器分配和常规/宽范围的指令选择。 它有什么作用? Mockito嘲弄 Dexmaker通过生成Dalvik字节码类代理,使您可以在Android项目中使用库。 只需在dexmaker-mockito上添加androidTestImplementation依赖项,即可在Android Instrumentation测试中使用Mockito。 Dexmaker定位的Mockito版本可以在dexmaker-mo 立即下载

相关推荐

通过Android字节码插桩插件实现Android端无埋点(或自动埋点),并且支持根据配置文件实现业务数据的自动采集。.zip

数据采集相关工具、源码、数据集等资源

Android动态类生成预加载-dexmaker使用

一、dexmaker简单介绍 dexmaker是运行在Android Dalvik VM上,利用Java编写,来动态生成DEX字节码的API。如果读者了解AOP编程的话,应该听说过cgliborASM,但这两个工具生成都是Java字节码,而Dalvik加载的必须是DEX字节码。所以,想要在Android上进行AOP编程,dexmaker可以说是一个很好的选择。项目地址:https...

weixin_30904593的博客 1790

八路抢答器____一个作品的制作思路

学习了解到一个产品制作完全由一个人去采购,设计,仿真,画PCB。不光是需求的分析还有实现功能时如何搭建电路,和给出一个简单高效的设计方法也是至关重要的。

weixin_73690807的博客 1522

Dexmaker:Android开发者的代码生成利器

**Dexmaker** 是一个针对Dalvik虚拟机的Java语言API,支持在编译时或运行时生成代码。与传统的[cglib](http://cglib.sourceforge.net/)或[ASM](http://asm.ow2.org/)不同,Dexmaker生成的不是Java `.class` 文件,而是Dalvik `.dex` 文件。这使得Dexmaker成为Android开发者进行代...

gitblog_01107的博客 611

【八股】JUC并发编程篇

👉抽象队列同步器,就是一种锁,内部维护的是一个先进先出的双向队列,队列中存储的是排队的线程,用state来标识是否有线程获得锁【0是无锁状态】👉流程:当一个线程拿到锁后会修改state = 1,这时如果有其他线程访问则会进入队列进行排序,直到state变成0后,队头线程才会拿到锁。在对state进行修改时,用的是CAS操作,所以可以保证原子性。👉它可以实现公平锁或非公平锁【默认】,上述是一个公平锁。如果新线程和队头线程抢锁资源就是非公平锁。

qq_44768318的博客 552

【四足机器人项目实战】cheetah 3/mini运动控制工程解读(附C++代码)

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、主程序入口1.代码流程2.终端设置信息提示二、用MiniCheetahHardwareBridge类构造一个hw的对象并初初始化1.2.3.4.三、运行硬件桥驱动【MiniCheetahHardwareBridge】1.2.3.4.四、1.2.3.4.总结参考资料 前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对cheetah3/m

qq_35635374的博客 2615

动态加载APK原理分享

项目地址:https://github.com/houkx/android-pluginmgr/ 欢迎star and fork (一) 综述     随着智能手机硬件性能的逐步提升,移动应用也做的越来越复杂,android平台上应用的apk包体积也越来越大,然后同类产品开始比拼谁的体积小,实现方案呢,然后很容易想到"插件化",也就是说可以发布内核很小的产品,随着添加功能的需求而动态下载功

wwzuizz的博客 273

CentOS-7-x86_64经典版本的含义

这个版本的ISO文件包含了所有的软件包,所以文件比较大,但在安装过程中不需要下载软件包。如果你有一个稳定的网络连接,并且希望安装时能够选择最新的软件包,或者只安装特定的软件包,那么可以选择NetInstall版本。在这里,它可能是指这个ISO文件发布于2207年2月,但是这似乎是一个错误,因为截止到现在(2022年)的时间,都没有到达2207年。另外,还有一个DVD版本,这个版本的ISO文件包含了大部分常用的软件包,安装时可能需要网络连接,但比NetInstall版本少一些。

舒一笑的博客 3535

Android组件化方案最佳实践

舞动着键盘和鼠标,我誓言要把这个世界写的明明白白 本文出自门心叼龙的博客,属于原创类容,转载请注明出处。https://blog.youkuaiyun.com/geduo_83/article/details/86604852 github组件化框架下载地址:https://github.com/geduo83/FlyTour 欢迎点赞加星,评论打call、加群:810970432 目录 1.前言...

门心叼龙的专栏 1万+

CRMEB开源电商系统 /api/products SQL注入漏洞复现(CVE-2024-36837)

2024年6月,CRMEB开源电商系统发布了新补丁,修复了一处SQL注入漏洞(CVE-2024-36837)。经分析,该漏洞可以通过请求api的路径接口来进行SQL注入,进而可能导致敏感信息泄露,该注入可暴露后台web绝对路径,深入利用可获取服务器权限,该漏洞无前置条件且利用简单,建议受影响的用户尽快修复漏洞。

0xSec 2882

(5)ModalAI VOXL2

Ardupilot官网关于《Non-GPS navigation》的翻译 —《(5) ModalAI VOXL2》。

无人机开发(开源Ardupilot) 1万+

深入理解Darner的日志结构化存储:LevelDB如何提升持久化性能

Darner作为一款轻量级消息队列,其核心优势在于高效的持久化机制。本文将深入解析Darner如何通过LevelDB实现日志结构化存储,以及这种设计如何显著提升消息队列的持久化性能和可靠性。 ## 消息队列持久化的核心挑战 在分布式系统中,消息队列的持久化需要平衡三个关键指标:写入性能、存储空间利用率和数据可靠性。传统的文件追加方式虽然简单,但面临着数据检索效率低和存储空间碎片化的问题。Dar

gitblog_00100的博客 749

让 ABAP Screen Variant 安稳上车:SHD0 与 SHD0_MANDT 的 Transport 全攻略

摘要: SAP项目常需优化交易码界面,通过SHD0的Transaction Variant和Screen Variant可实现字段精简、默认值预设及权限控制,避免修改标准代码。但跨系统迁移时易出现变式丢失或版本兼容问题。核心概念包括: Screen Variant:针对单个屏幕的字段属性配置(跨Client); Transaction Variant:串联多屏幕变式(分跨Client和Client-specific); 版本差异:4.70/6.x后需区分SHD0(跨Client)与SHD0_MANDT(Cl

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 226

使用Javassist 在android运行时生成类

最近在写框架,有一个需求就是动态的生成一个类,然后查阅了相关文献,发现在android中动态生成一个类还挺麻烦。因次把一些内容分享出来,帮助大家少走弯路。

SOLO的博客 1628

【Verilog基础】CDC跨时钟域方法,典型异步电路设计之脉冲同步器(上)

【Verilog基础】CDC跨时钟域方法,典型异步电路设计之脉冲同步器(上):慢时钟域到快时钟域!

悟已往之不谏 知来者之可追 1545

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

插件化之APK动态加载

插件化相关概念: 根据组件化与插件化的区别来了解一下概念 组件化和插件化的区别 组件化:是将一个APP分成多个模块,每个模块都是一个组件(module),开发的过程中我们可以让这些组件相互依赖或者单独调试部分组件,但是最终发布的时候将这些组件合并成一个统一的APK。 插件化:是将整个APP拆分成很多模块,每个模块都是一个APK(组件化的每个模块是一个lib),最终打包的时候将宿主APK和插件APK分开打包,插件APK通过动态下发到宿主APK。 插件化的优点 减小安装APK的体积,按需下载模块

u013773608的博客 2050

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【亲测免费】 Dexmaker 项目教程

Dexmaker 是一个用于在 Android 平台上进行编译时或运行时代码生成的 Java API。与 cglib 或 ASM 等库不同,Dexmaker 生成的是 Dalvik 字节码(dex 文件)而不是 Java 字节码(class 文件)。它提供了一个小巧且接近底层的 API,允许开发者精确控制生成的字节码。Dexmaker 广泛应用于 Android 开发中的 AOP(面向切面编程)和...

gitblog_00304的博客 1095

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

了解一下,Android 10中的ART虚拟机(I)

缘起从今天开始,对Android 10中的ART进行“了解一下”之旅。我本来以为一篇就能拿下,但谁想谷歌从8.0开始对ART进行了更细致和难度更高的改进。粗看了几遍代码,我觉得谷歌不管怎...

Innost的专栏 1万+

Android插件化动态加载apk

插件化动态加载apk

qq_27938211的博客 3429

Android dex动态加载(Kotlin版)

语言–KotlinJDK11SDK33AndroidStudio版本libaray项目打包成jarjar通过dx命令行工具转为dex.jardex.jar放到assets目录下App启动读取assets中的dex.jar复制到App可访问的文件夹中(建议内部存储的沙盒中,不受权限限制)实例化DexClassLoader加载dex获取ClassLoader对象通过ClassLoader.loadClass方法,获取想要执行的类。

DeMonnnnnn 4216

Dexmaker实战指南:Android动态代码生成的终极武器

Dexmaker是一个专为Android平台设计的Java语言API,用于在编译时或运行时生成针对Dalvik虚拟机的代码。与cglib或ASM等传统代码生成库不同,Dexmaker直接创建Dalvik的.dex文件而非Java的.class文件,这在Android开发领域具有独特价值。 ## 核心功能深度解析 ### 动态字节码生成能力 Dexmaker提供了接近底层的API,这些API镜像

gitblog_00185的博客 812

Dexmaker 开源项目教程

Dexmaker 是一个用于在 Android 上进行单元测试的 Mockito 扩展库。以下是其主要目录结构和介绍: - **dexmaker/**: 核心库代码,包含 Dexmaker 的主要实现。 - **src/**: 源代码目录。 - **main/**: 主代码目录。 - **java/**: Java 源代码。 - **com/linkedi...

gitblog_00494的博客 708
上一篇: Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
下一篇: android-plugmgr原理
阿里安
博客等级 码龄13年 79粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值