Android 组件化之路 路由设计

Android组件化实战六:路由架构设计 前言 结合前面的模块之间的交互,主要分析了类加载、全局Map记录(跳转目标Class)两种交互方式,以及APT和JavaPoet技术生成类文件,本文分析组件化的路由架构,我们到底需要通过APT和JavaPoet生成什么样的类文件呢? 组件化路由架构设计 先来看这样一幅架构设计图,组文件记录是一对一的即一个子模块对应一个组文件记录,而一个组文件记录对应多个路径文件记录,第二点比较好理解,因为各个子模块有多个Activity,对应多个路径信息。对应第一点,为什么要生成一对一的组(名)文件记录呢?试想一下,如果 阅读详情

基于公司业务发展,公司的APP需求不断增加,应用也略显“臃肿”。想着趁现在不那么“糟糕”,时间也比较宽裕,把项目结构整整,因而走上了组件化之路。

模块化 VS 组件化

模块化: 将一个程序按照其功能做拆分,分成相互独立的模块,以便于每个模块只包含与其功能相关的内容。

组件化: 基于可重用的目的,将一个大的软件系统按照分离关注点的形式,拆分成多个独立的组件。

区别:
模块化和组件化本质思想是一样的,都是“大化小”,两者的目的都是为了重用和解耦,只是叫法不一样。如果非要说区别,那么可以认为模块化粒度更小,更侧重于重用;而组件化粒度稍大于模块,更侧重于业务解耦。

为什么需要路由

路由主要的功能是实现模块化之间界面(Activity,网页)的跳转,那为什么不直接调显式跳转呢?

据我总结,主要有以下3点原因:

  • 减少模块之间的依赖。因为显式跳转需要引用其他模块。

  • 跳转时,参数不明确,沟通需要时间。因为显式调用时,需要知道目标Activity需要哪些参数,如果参数改了,如果沟通不到位或者文档没有及时更新,会出现错误等问题。

  • 简化H5页面与应用页面之间的跳转。

虽然网上有很多库,如阿里的ARouter。我不是有轮子不用,只是想着能学习多点组件化的知识,出于这个目的,决定自定义路由。

跳转页面的方式

Activity之间的跳转有2种方式:显式和隐式,显式显然不行,我们来看看隐式(如果不知道,请参考Android开发艺术探索笔记(2)- Activity的启动模式)。

隐式跳转的条件是Intent要么匹配action,要么匹配data。我这里选择匹配data方式,理由是匹配data方式是利用URL Scheme页面跳转协议,可以非常方便跳转app中的各个页面,也可以通过H5页面跳转页面等。

什么是URL Scheme

Android中的scheme是一种页面内跳转协议,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面;通过scheme协议,服务器可以定制化告诉App跳转那个页面,可以通过通知栏消息定制化跳转页面,可以通过H5页面跳转页面等。

URL Scheme格式

URL Scheme和Http的Uri很像,包括scheme,host,port,path,query。
例子:

app://user:8888/login?username=xiaoming
  • app:代表scheme,协议的名称
  • user:代表host,地址域
  • 8888:代表port,端口号
  • login:代表path,路径
  • username:代表query,传递的参数
使用URL Scheme

manifest声明activity:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.johan.demo">
    <application
        <activity android:name=".SecondActivity">
            <intent-filter>
                <data android:scheme="app" android:host="user" android:port="8888" android:path="/login" />
                <!-- 一下几行必须设置 -->
                <action android:name="android.intent.action.VIEW" /> <!-- 隐式调用必须声明 -->
                <category android:name="android.intent.category.DEFAULT" /> <!-- 隐式调用必须声明 -->
                <category android:name="android.intent.category.BROWSABLE" /> <!-- BROWSABLE的意思就是浏览器在特定条件下可以打开你的Activity -->
            </intent-filter>
        </activity>
        ...
    </application>
</manifest>    

activity跳转:

Intent intent = new Intent();
Uri uri = Uri.parse("app://user:8888/login?username=xiaoming");
intent.setData(uri);
startActivity(intent);

这种方式跳转Activity有个致命的缺点,如果找不到对应的Uri,程序就会Crash,所以在跳转之前要判断一下Uri是否存在:

PackageManager packageManager = getPackageManager();
Intent intent = new Intent();
Uri uri = Uri.parse("app://user:8888/login?username=xiaoming");
intent.setData(uri);
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
boolean isValid = !activities.isEmpty();
if (isValid) {
    startActivity(intent);
}

设计路由

既然跳转方式选定了,但是还存在问题,就是参数不明确问题。如果能像retrofit那样,方法决定参数,这样就不用担心参数不明确问题了。

稍微看过retrofit源码都知道,retrofit运用的动态代理模式,so我们模仿一下,Like This,代码如下:(dome,仅供参考)

public class SimpleRouter {

    // ApplicationContext
    private static Context routerContext;

    /**
     * 初始化
     * @param context
     */
    public static void init(Context context, int cacheSize) {
        routerContext = context.getApplicationContext();
    }

    @SuppressWarnings("unchecked")
    public static <T> T create(final Class<T> iRouter) {
        return (T) Proxy.newProxyInstance(iRouter.getClassLoader(), new Class[]{iRouter}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 开始解析
                // 域名,可以不写
                String domain = null;
                if (iRouter.isAnnotationPresent(RouterDomain.class)) {
                    RouterDomain routerDomain = iRouter.getAnnotation(RouterDomain.class);
                    domain = routerDomain.value();
                }
                // 路径,必须有,否则报错
                if (!method.isAnnotationPresent(RouterPath.class)) {
                    throw new RuntimeException(iRouter.getName() + " " + method.getName() + " should has RouterPath Annotation");
                }
                RouterPath uriPath = method.getAnnotation(RouterPath.class);
                String path = uriPath.value();
                StringBuilder urlBuilder = new StringBuilder();
                if (domain != null) urlBuilder.append(domain);
                urlBuilder.append(path);
                // 参数
                Annotation[][] paramAnnotations = method.getParameterAnnotations();
                for (int index = 0; index < paramAnnotations.length; index++) {
                    Annotation[] paramAnnotation = paramAnnotations[0];
                    if (paramAnnotation == null || paramAnnotation.length == 0) {
                        continue;
                    }
                    if (paramAnnotation[0] instanceof RouterParam) {
                        RouterParam uriParam = (RouterParam) paramAnnotation[0];
                        String param = uriParam.value();
                        String connector = index == 0 ? "?" : "&";
                        urlBuilder.append(connector).append(param).append("=").append(args[index]);
                    }
                }
                // 打开Activity
                openActivity(urlBuilder.toString());
                return null;
            }
        });
    }

    /**
     * 打开Activity
     * @param url
     * @return
     */
    private static boolean openActivity(String url) {
        PackageManager packageManager = routerContext.getPackageManager();
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
        boolean isValid = !activities.isEmpty();
        if (isValid) {
            routerContext.startActivity(intent);
        }
        return isValid;
    }

}

应用动态代理模式,由接口生成代理类,调用接口方法时,就会执行代理类的invoke方法,打开对应的Activity!

使用方法:比如我们有2个module,app和user-module。

先在user-module的manifest文件声明activity:

<activity android:name=".UserLoginActivity">
    <intent-filter>
        <data android:scheme="app" android:host="user" android:path="/login" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

然后在app跳转到user-module的界面:

// 我在Application初始化SimpleRouter,也可以在Activity中初始化
public class MainApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        SimpleRouter.init(this);
    }
}
// UserRouter接口
@RouterDomain("app://user")
public interface UserRouter {
    @RouterPath("/login")
    void goLogin();
}
// MainActivity跳转
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void goToUserLogin(View view) {
        // 跳转
        SimpleRouter.create(UserRouter.class).goLogin();
    }
}

使用就这么简单!!!

当然,目前只是一个实现页面跳转的路由,以后慢慢改善!!

代码我已经上传到我的github中,代码地址:https://github.com/JohanMan/simplerouter,有兴趣的可以看一下!!

参考资料

Android 开发:由模块化到组件化(一)
Android业务组件化之URL Scheme使用
Android业务组件化之子模块SubModule的拆分以及它们之间的路由Router实现

滴滴资深Android面经:组件化实践、热修复方案、路由框架设计、监控体系搭建 【摘要】本文分享滴滴资深Android面试核心考点,涵盖组件化架构、热修复方案、路由框架、监控体系等8大主题。重点解析了组件化分层设计(基础层-业务组件-壳工程)、热修复技术选型(Sophix/Tinker/Robust对比)、ARouter路由实现原理、线上监控体系搭建等关键技术,并探讨了滴滴多业务线架构演进过程。文章指出资深岗需具备大型项目架构能力,建议结合实际项目经验阐述架构设计思路,特别强调组件化、路由框架和业务线隔离等高频考点。 阅读详情

相关推荐

Android代码-Android组件化最佳路由,为简单而生。

最新版本 模块 auto-api auto-complier auto-annotation auto-inject 最新版本 > Android组件化超级路由,为简单而生。 Github 源码: ARetrofit demo demo apk 下载 一 介绍 从命名来看,做Android开发的小伙伴们感觉是不是似曾相识…是的,Retrofit,一款优秀的网络框架,目前正在被大量使用,相信大家对它的用法已经非常熟悉吧。 ARetrofit一款优秀的Android组件化框架(皮一下^_^开心),可以轻松实现跨module通信。这里之所以使用Retrofit作为后缀命名主要是为了尊重retrofit大神的架构思路,其目的降低开发者的学习和使用成本。 如果你正在对项目进行组件化,ARetrofit将是不二选择。 二 功能介绍 新增ActivityCallback,通过配置一个参数实现Activity回调,且可以回传任意参数,告别onActivityResult繁琐写法,使用更灵活 支持直接解析标准URL进行跳转 支持跨module通信 支持添加多个拦截器,自定义

Android 组件化与路由跳转实现

路由是在 Android 组件化开发中必不可少的组件,两个独立的模块不能有直接引用,界面的跳转都经过路由中转实现。在讲路由之前,我们需要理解一个概念:什么是路由?路由本来是网络的概念,而放在 Android 开发中,我们可以将项目的每个 module 看成不同的网络,路由就是连接各个 module 的中转站,这个中转站可以对页面跳转的参数等统一处理后再进行转发。或许你会有这样的疑惑:隐式跳转也能实现跨 module,也可以实现相应的功能;还有也可以用反射来实现,为什么要用路由?

Vincent的博客 1979

告别ZotFile!Zotero 7+百度网盘文献同步全攻略(含软链接避坑指南)

本文针对Zotero 7用户,提供了告别ZotFile插件后,利用百度网盘实现文献附件同步的完整解决方案。详细讲解了如何通过设置Zotero链接目录与创建软链接,将附件库迁移至云盘,并附有详细的避坑指南,确保数据安全与多设备同步的稳定性。

mmm90的博客 586

【Android 组件化】使用 ARoute 实现组件化 ( 完整组件化项目框架 )

一、ARoute 引入、 1、配置 build.gradle、 二、3 个模块的界面跳转、 三、组件化配置、 1、全局配置、 2、工程下的 build.gradle 配置、 3、app 模块下的 build.gradle 配置、 四、Module 模块的组件化配置、 1、创建组件模式下使用的类和清单文件、 2、动态切换 集成模式 / 组件模式、 五、博客资源、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 3977

wpf入门第五篇 WPF with ECharts

前言 本文是wpf入门系列第五篇,面向有winform或者web前端基础的、并且也有C#基础的同学。 ECharts是百度团队开发的开源免费的js图表控件库,非常强大,文档齐全。WPF中使用图表,除了可以选择devexpress或者oxyplot之类的专为wpf开发的图表控件之外,还可以考虑使用 WebBrowser+ECharts 来完成复杂的图表展示,其展示效果不亚于前者。 本文介绍了 WP...

wf824284257的博客 1万+

Ubuntu使用cmake出现Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed

解决 Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed

qq_44225529的博客 1万+

Android 组件化基础(二)—— 仿 ARouter 实现一个路由框架

本篇文章还是从理解 ARouter 的架构思想和实现细节的角度出发,仿照 ARouter 实现一个简单的路由框架,能力有限,就仅实现三个基本功能: 路由扫描、建立路由表。 通过路由跳转到目标页面。 通过路由调用其它模块对外暴露的服务。 拦截器等功能暂不打算实现。 一、总体规划 ...

tmacfrank 1100

【论文泛读|附源码】如何进行动力学重构? 神经网络自动编码器结合SINDy发现数据背后蕴含的方程

这一篇文章叫做 **数据驱动**的**坐标发现与方程发现算法**。想回答的问题很简单,就是根据数据写方程。 想想牛顿的处境,如何根据各种不同物体下落的数据,写出万有引力的数学公式的。这篇文章就是来做这件事的。当然,这篇论文并没有从牛顿视角,完全去思考牛顿所想。而是利用现有的**深度学习技术** 和 **动力学重构的方法** 。提出了一种框架,基于现有的计算机技术,去发现物质运动背后的物理规律。 这里直接给出这篇方法的核心思路图,我们后面会逐个讲解。

qq5q13638的博客 2456

【Android 组件化】路由组件 ( 路由组件结构 )

一、路由组件原理、 二、路由组件基本组成、 三、自定义注解模块、 四、注解处理器模块、 五、博客资源、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1777

STM32F407ZGT6开发板跑马灯实战:从原理图到烧录全流程(附FlyMcu配置)

本文以正点原子F4探索者开发板(STM32F407ZGT6)为例,手把手指导完成跑马灯实验。内容涵盖从原理图解读、GPIO驱动逻辑分析、HAL库工程搭建,到代码编写与FlyMcu串口烧录配置的全流程,帮助嵌入式开发新手快速实现第一个LED控制程序,打通软硬件开发链路。

weixin_29183637的博客 223

LVGL 磁罗盘效果

环境:LVGL 9.x + SDL2,窗口 1280×800。界面文案用英文(默认 Montserrat,无 CJK)。本文按实现顺序讲:先建立两个耦合转动体,再把磁倾角误差从卡面倾斜里推出来,最后用同一套投影把刻度、数字和目标画到卡上。画面上的迟滞、涡流、摆动和读数偏差都来自方程,没有补间动画。

摸鱼专家 86

Android组件化架构 - 3. 组件间跳转 & ARouter路由

组件间跳转 & ARouter路由 常见的跳转,对于用户来说就是页面跳转,对应Android中就是activity或fragment间的跳转,那我们肯定第一时间就想到, 用startActivity()发送一个包装好的intent,将intent交给ActivityManagerService完成新的Activity创建。 但是组件化中,两个功能模块是不存在直接依赖关系的(通过baseModule间接依赖),那么包装intent时就会发现引用不了其他module 中的activity类(xxx.cl

o118abcdef的博客 621

​​光流结合深度学习实现物体运动方向判断

光流计算:提取每一帧视频中像素的运动信息,生成光流图。光流特征提取:通过特定的预处理,将光流图转换为深度学习模型可用的输入格式。深度学习模型设计:构建一个卷积神经网络(CNN)或其他适合的深度学习架构,利用光流特征进行运动方向分类。模型训练与推理:对网络进行训练并使用训练好的模型判断运动方向。光流与深度学习结合的运动方向判断技术在多个领域具有广泛的应用前景。通过光流提取像素级动态信息,并利用深度学习模型学习高层次特征,可以实现高精度的运动检测与方向判断。

matlab_python22的博客 321

Android 组件化路由框架设计(仿Arouter)

Android 组件化路由框架设计(仿Arouter) 项目地址RouterDemo:https://github.com/532268948/RouterDemo 一、前言   在组件化开发中一个必须要面对的问题就是组件间页面跳转,实现的方法有很多,简单的可以通过反射获取,但是比较耗费性能,也可以通过隐式跳转,但是随着页面的增多,过滤条件会随之增多,后期维护麻烦。那还有什么方法呢,没错,就是...

yth532268948的博客 688

【BlueZ】编译产物详解:可执行文件/库文件/工具的生成路径与用途

BlueZ二次开发编译产物机制解析 摘要:在BlueZ蓝牙协议栈二次开发中,90%的报错源于对编译产物类型和路径的混淆。本文系统剖析BlueZ的三阶段编译机制:1)配置阶段生成Makefile;2)编译阶段在.libs目录下产生临时库和可执行文件(不可直接运行);3)安装阶段将产物部署到系统标准路径。重点解析守护进程、命令行工具、动态库的核心路径差异,并针对五大高频问题(如临时库运行崩溃、动态库不匹配、系统覆盖等)给出解决方案。

byte轻骑兵的技术小窝 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Android组件化架构下,基于APT注解的路由框架设计与实现详解

在Android开发中,组件化架构通过将应用拆分为独立模块来提升开发效率和可维护性,但同时也带来了模块间页面跳转的耦合难题。其核心原理在于利用编译时注解处理技术,在保持模块物理隔离的前提下,建立一套中心化的路由寻址机制。这项技术的价值在于彻底解耦模块依赖,支持安全、灵活的跨模块导航,是实现高效团队协作和项目长期健康度的关键基础设施。典型的应用场景包括电商、社交等中大型多模块应用,用于管理例如商品详情、用户中心、支付等业务模块间的页面流转。本文聚焦于基于APT注解处理器的路由框架,深入探讨其如何通过注解扫描、

weixin_33883104的博客 345

Devexpress16.2.6破解工具

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

android工程师面试题目和答案,组件化框架设计之阿里巴巴开源路由框架,安卓开发面试题及答案

很简单,定义了几个静态map,在初始化的时候来存放之前的注解生成的那些相关信息。初始化里面存的就是所有group索引的map,所有拦截器(本文不讲)索引的map,所有provider索引的map。至此,之前的那些注解类里面的信息都被存储起来了,这样后续在查找的时候就很方便可以找到对应的类,我们继续看初始化之后的afterInit方法:我们跟踪之后,发现最终会调用LogisticsCenter中的completion方法:/***/”);Class

m0_74931167的博客 995

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

深度学习工具包 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组件设计,Android组件化开发路由的设计实践

调研了一下目前的路由框架,ARouter(阿里的),ActivityRouter都使用了apt技术 编译时注解,个人想法是一口吃不成胖子,先做个比较实用的。 VpRouter路由框架主要应用于组件化开发中设计目的解耦跨模块跳转方便服务器配置schema,实现动态配置跳转目标对外部提供远程访问的功能,实现跨应用调用响应主要功能点支持intent,http,schema三种跳转路由表支持xml配置,可...

weixin_39779528的博客 113

android 登录组件开发,Android组件化开发路由的设计

调研了一下目前的路由框架,ARouter(阿里的),ActivityRouter都使用了apt技术 编译时注解,个人想法是一口吃不成胖子,先做个比较实用的。 VpRouter路由框架主要应用于组件化开发中设计目的解耦跨模块跳转方便服务器配置schema,实现动态配置跳转目标对外部提供远程访问的功能,实现跨应用调用响应主要功能点支持intent,http,schema三种跳转路由表支持xml配置,可...

weixin_30649185的博客 191

Android组件化开发路由的设计

调研了一下目前的路由框架,ARouter(阿里的),ActivityRouter都使用了apt技术 编译时注解,个人想法是一口吃不成胖子,先做个比较实用的。 VpRouter路由框架主要应用于组件化开发中 设计目的 解耦 跨模块跳转 方便服务器配置schema,实现动态配置跳转目标 对外部提供远程访问的功能,实现跨应用调用响应 主要功...

weixin_34396103的博客 223

android组件化开发约定资源名,Android组件化开发路由的设计

调研了一下目前的路由框架,ARouter(阿里的),ActivityRouter都使用了apt技术 编译时注解,个人想法是一口吃不成胖子,先做个比较实用的。 VpRouter路由框架主要应用于组件化开发中设计目的解耦跨模块跳转方便服务器配置schema,实现动态配置跳转目标对外部提供远程访问的功能,实现跨应用调用响应主要功能点支持intent,http,schema三种跳转路由表支持xml配置,可...

weixin_39548740的博客 179

android 组件化_Android 组件化路由框架设计(仿Arouter)

前言 在组件化开发中一个必须要面对的问题就是组件间页面跳转,实现的方法有很多,简单的可以通过反射获取,但是比较耗费性能,也可以通过隐式跳转,但是随着页面的增多,过滤条件会随之增多,后期维护麻烦。那还有什么方法呢,没错,就是接下来要介绍的Arouter路由框架,该框架是阿里巴巴开源项目,大厂出品,必属精品。使用过Arouter得同学都知道Arouter是通过给每个页面添加@Route注解然后调用一定...

weixin_39776298的博客 250

Android 组件化 —— 路由设计最佳实践

引子 这篇文章会告诉你 什么是路由,是为了解决什么问题才产生的业界现状是怎么样的,我们可以做什么来优化当前的问题路由设计思路是怎么样的,该怎么设计比较好如何用注解实现路由表URL的参数如何依赖注入到Activity、Fragement如何HookOnActivityResult,不需要再进行requstCode判断如何异步拦截路由,实现线程切换,不阻塞页面跳转如何用Apt实现Retrofi

Kslient的博客 1672

Android架构师-组件化-组件化路由架构设计 6

一:思考: 在组件化架构中,我们需要通过APT和JavaPoet技术生成什么样的类文件呢 组件化路由架构设计图: 思考: 1:为什么要组名,为什么不直接通过path路径来取Class类对象呢 例如:组名app 组名order 组名personal 比如组名有: app ,那么对应的路径的详细的Class类文件,那么这个文件就是ARouter$Path$$a...

u013815832的博客 254

Android组件化设计4 --- 路由参数传递

路由带参传递,封装路由管理类

qq_33235287的博客 2691
上一篇: Android 内存泄露分析
下一篇: Android 组件化之路 资源冲突问题
JohanMan
博客等级 码龄10年 72粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值