Android 设计模式之代理模式

Android源码设计模式探索与实战【代理模式】 理解: 代理模式是结构性设计模式的一种。在软件开发中我们常常会遇到这样的情况,有些对象,我们不想客户端可以直接访问,或者我们不想客户端可以访问到这个对象的一些操作方法,所以需要一个“中介”的角色。举个例子,卖房子的人为了减少频繁的电话&看房等麻烦,会把自己的房子托给中介,中介替他去找合适的买家,针对于买房的人来说,买这套房子,只能通过中介去了解,而不能直接打电话给房主。定义: 为一个对象提供一个替身,以控制对这个对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中 阅读详情

一、代理模式的介绍

定义:为其他的对象提供一种代理,控制这个对象的访问。
使用场景:当无法或者不想直接访问某个对象后者访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。
角色划分:目标接口、目标对象、代理对象
实现方式:静态代理、动态代理

在我们的平时开发中,所使用的一些开源框架也有应用,如 XUtils 框架、Retrofit 框架等,Android 系统源码中也有大量应用,如
ActivityManagerProxy 代理类,对于 MVP 架构设计、插件化架构设计,代理模式更显神通。下面,通过仿照XUtils IOC 实现方式进行对代理模式的深入研究。

二、XUtils 框架分析

XUtils 主要通过注解的方式进行 UI,资源和事件绑定,下面主要对 XUtils
中 ViewUtils 模块IOC框架的实现进行分析。
IOC实现哪些功能?
* 第一个功能:布局文件注入
第一步:新建一个布局注解
第二步:注入布局

  • 第二个功能:View注入
    第一步:新建一个View注解
    第二步:注入View

  • 第三个功能:事件注入
    第一步:新建一个事件注解
    第二步:注入事件

1.布局文件注入注解

 //类注解
//Target:作用目标->作用在类身上(ElementType.TYPE)
@Target(ElementType.TYPE)
//Retention:生命周期->运行时注解(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    //布局ID
    int value();
}

2.View注入注解

 //Target:作用目标->作用在属性身上(ElementType.FIELD)
@Target(ElementType.FIELD)
//Retention:生命周期->运行时注解(RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
    //View的ID
    int value();
}

3.事件注入注解

 //动态指定事件
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Event {
    int[] value();
    Class<?> type() default View.OnClickListener.class;
    String setter() default "";
    String method() default "";
}

3.1注解事件的管理类

public class EventListenerManager {

    private static DynamicHandler dynamicHandler;

    private EventListenerManager() {
    }

    public static void addEventMethod_2_0(
            Annotation eventAnnotation, Object handler, Method method, Object view) {
        try {
            if (view != null) {
                EventBase eventBase = eventAnnotation.annotationType()
                        .getAnnotation(EventBase.class);
                // 监听类型:OnClickListener、OnTouchListener、OnLongClickListener等等......
                Class<?> listenerType = eventBase.listenerType();
                // 事件源(你要给那个View绑定监听,而且该监听对应的方法)
                // View.setOnClickListener() View.setOnTouchListener
                // View.setOnLongClickListener
                String listenerSetter = eventBase.listenerSetter();
                // 监听方法: onClick方法、onTouch、onLongClick方法
                String methodName = eventBase.methodName();

                // 从缓存中获取
                // 提高了性能,节约内存

                Object proxy = null;

                // 第一次添加监听
                dynamicHandler = new DynamicHandler(handler);
                dynamicHandler.addMethod(methodName, method);

                // proxy:代理对象
                proxy = Proxy.newProxyInstance(
                        listenerType.getClassLoader(),
                        new Class<?>[]{listenerType}, dynamicHandler);

                // 绑定监听
                Method setEventListenerMethod = view.getClass().getMethod(
                        listenerSetter, listenerType);
                setEventListenerMethod.invoke(view, proxy);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public static void addEventMethod_3_0(
            Event event, Object handler, Method method, Object view) {
        try {
            if (view != null && event != null) {
                // 监听类型:OnClickListener、OnTouchListener、OnLongClickListener等等......
                Class<?> listenerType = event.type();
                // 事件源(你要给那个View绑定监听,而且该监听对应的方法)
                // View.setOnClickListener() View.setOnTouchListener
                // View.setOnLongClickListener
                String listenerSetter = event.setter();
                // 监听方法: onClick方法、onTouch、onLongClick方法
                String methodName = event.method();

                // 从缓存中获取
                // 提高了性能,节约内存

                Object proxy = null;

                // 第一次添加监听
                dynamicHandler = new DynamicHandler(handler);
                dynamicHandler.addMethod(methodName, method);

                // proxy:代理对象
                proxy = Proxy.newProxyInstance(
                        listenerType.getClassLoader(),
                        new Class<?>[]{listenerType}, dynamicHandler);

                // 绑定监听
                Method setEventListenerMethod = view.getClass().getMethod(
                        listenerSetter, listenerType);
                setEventListenerMethod.invoke(view, proxy);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    // WeakReference?为什么?
    // 第一点:及时清理内存
    // 第二点:Activity很有可能会被意外释放(意外关闭,而这个时候你刚好执行代码到了控件的加载)
    // 添加软引用目的:为了防止对象意外被释放关闭而产生异常(典型:空指针异常)
    public static class DynamicHandler implements InvocationHandler {
        private WeakReference<Object> handlerRef;
        private final HashMap<String, Method> methodMap = new HashMap<String, Method>(
                1);

        // 目标对象: Activity、Fragment
        public DynamicHandler(Object handler) {
            this.handlerRef = new WeakReference<Object>(handler);
        }

        public void addMethod(String name, Method method) {
            methodMap.put(name, method);
        }

        public Object getHandler() {
            return handlerRef.get();
        }

        public void setHandler(Object handler) {
            this.handlerRef = new WeakReference<Object>(handler);
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            Object handler = handlerRef.get();
            if (handler != null) {
                String methodName = method.getName();
                method = methodMap.get(methodName);
                // 为什么做判断?
                // 目的:确定代理要代理的方法
                if (method != null) {
                    return method.invoke(handler, args);
                }
            }
            return null;
        }
    }
}

4.最终注解的工具类

public class InjectUtils {

    public static void inject(Object obj) {
        injectLayout(obj);
        Map<Integer, Object> viewMap = injectView(obj);
//        injectEvent_2_0(obj, viewMap);
        injectEvent_3_0(obj, viewMap);
    }


    public static void injectLayout(Object obj) {
        // 获取Activity的ContentView的注解
        Class<?> handlerType = obj.getClass();
        try {
            //获取类对象身上的注解
            ContentView contentView = handlerType.getAnnotation(ContentView.class);
            if (contentView != null) {
                //获取布局ID
                int viewId = contentView.value();
                if (viewId > 0) {
                    Method setContentViewMethod = handlerType.getMethod(
                            "setContentView", int.class);
                    setContentViewMethod.invoke(obj, viewId);
                }
            }
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

    public static Map<Integer, Object> injectView(Object handler) {
        Map<Integer, Object> viewMap = new HashMap<Integer, Object>();
        //获取类对象
        Class<?> handlerType = handler.getClass();
        //获取对象属性列表
        Field[] fields = handlerType.getDeclaredFields();
        //判定是否存在属性
        if (fields != null && fields.length > 0) {
            //遍历属性
            for (Field field : fields) {

                //判断属性修饰符
                Class<?> fieldType = field.getType();
                if (
                /* 不注入静态字段 */Modifier.isStatic(field.getModifiers()) ||
                /* 不注入final字段 */Modifier.isFinal(field.getModifiers()) ||
                /* 不注入基本类型字段(int、double、float、char、boolean等等...) */fieldType.isPrimitive() ||
                /* 不注入数组类型字段 */fieldType.isArray()) {
                    continue;
                }

                //获取属性注解
                ViewInject viewInject = field.getAnnotation(ViewInject.class);
                if (viewInject != null) {
                    try {
                        //获取ViewID
                        int viewId = viewInject.value();
                        //获取findViewById方法对象
                        Method findViewByIdMethod = handlerType.getMethod(
                                "findViewById", int.class);
                        //执行findViewById方法,获取对象
                        Object view = findViewByIdMethod.invoke(handler,viewId);
                        if (view != null) {
                            //修改访问权限(private)
                            //setAccessible:将属性修饰符修改为public
                            field.setAccessible(true);
                            //赋值
                            field.set(handler, view);

                            viewMap.put(viewId, view);
                        } else {
                            throw new RuntimeException(
                                    "Invalid @ViewInject for "
                                            + handlerType.getSimpleName() + "."
                                            + field.getName());
                        }
                    } catch (Throwable ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
        return viewMap;
    }


    //2.0版本->实现
    public static void injectEvent_2_0(Object obj, Map<Integer, Object> viewMap){
        //获取类对象
        Class<?> handlerType = obj.getClass();
        //获取对象方法->activity
        Method[] methods = handlerType.getDeclaredMethods();
        if (methods != null && methods.length > 0) {
            //遍历方法
            for (Method method : methods) {
                //获取方法注解
                Annotation[] annotations = method.getDeclaredAnnotations();
                if (annotations != null && annotations.length > 0) {
                    //遍历注解目的:为了获取我们想要的注解对象
                    for (Annotation annotation : annotations) {
                        //获取注解身上注解
                        //获取注解类型
                        Class<?> annType = annotation.annotationType();
                        if (annType.getAnnotation(EventBase.class) != null) {
                            method.setAccessible(true);
                            try {
                                //获取注解value方法
                                Method valueMethod = annType.getDeclaredMethod("value");
                                //获取OnClick、OnLongClick等等....注解身上的value方法
                                //values说白了就是控件的id数组
                                int[] values = (int[]) valueMethod.invoke(annotation);

                                //遍历id数组
                                for (int i = 0; i < values.length; i++) {
                                    int viewId = values[i];
                                    Object view = viewMap.get(viewId);
                                    //对事件进行动态代理
                                    EventListenerManager.addEventMethod_2_0(annotation, obj, method, view);
                                }
                            } catch (Throwable e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }

    //3.0版本->实现
    public static void injectEvent_3_0(Object handler, Map<Integer, Object> viewMap){
        //获取类对象
        Class<?> handlerType = handler.getClass();
        //获取对象方法->activity
        Method[] methods = handlerType.getDeclaredMethods();
        if (methods != null && methods.length > 0) {
            for (Method method : methods) {

                // 注意:静态方法不允许添加控件注解,私有方法运行访问,非私有方法不允许访问
                // 在XUtils框架3.0之后,要求我们的方法必须是私有方法(注意:public不行)
                // 希望该方法配置了注解,不希望子类继承,只有当前类可以享受
                if (Modifier.isStatic(method.getModifiers())) {
                    continue;
                }

                // 检查当前方法是否是event注解的方法
                Event event = method.getAnnotation(Event.class);
                if (event != null) {
                    try {
                        // id参数
                        int[] values = event.value();
                        // 循环所有id,生成ViewInfo并添加代理反射
                        for (int i = 0; i < values.length; i++) {
                            int valueId = values[i];
                            if (valueId > 0) {
                                Object view = viewMap.get(valueId);
                                // ViewInfo info = new ViewInfo();
                                // 不管你再怎么样,永远都会创建对象
                                method.setAccessible(true);
                                EventListenerManager.addEventMethod_3_0(event, handler, method, view);
                            }
                        }
                    } catch (Throwable ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    }

}

三、使用

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {

    @ViewInject(R.id.bt_1)
    private Button bt_1;
    @ViewInject(R.id.bt_2)
    private Button bt_2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InjectUtils.inject(this);
    }

    //2.0版本->写法
//    @OnClick({R.id.tv_text, R.id.tv_text_a})
//    public void click(View v){
//        Toast.makeText(this,"点击了TextView", Toast.LENGTH_LONG).show();
//    }

    //3.0版本->写法
    @Event(
            value = {R.id.bt_1, R.id.bt_2},
            type = View.OnClickListener.class,
            setter = "setOnClickListener",
            method = "onClick")
    public void click(View v) {
        if (v.getId() == R.id.bt_1) {
            Toast.makeText(this, "点击了Button->1", Toast.LENGTH_LONG).show();
        } else if (v.getId() == R.id.bt_2) {
            Toast.makeText(this, "点击了Button->2", Toast.LENGTH_LONG).show();
        }
    }
}

四、总结

对于代理模式,我认为需要不断的实践,代码是最好的老师,多去运用在自己的项目当中去,最后,附上我以前写的一个IOC注解框架,也是使用注解反射结合XUtils和ButterKnife实现方式,可拓展的开源框架,感兴趣的可以去瞧瞧,地址:Vegen的Github:自己打造IOC注解框架 ,觉得不错给个star鼓励下嘻嘻。

WebViewProxy:设置 Android WebView 代理的类 网络视图代理 设置 Android WebView 代理的类 立即下载

相关推荐

若依集成mybatisplus、兼容旧分页【亲测有效】

service类继承ServiceImpl类 实现 你的Service接口。hutool工具包和lombok工具包如果不需要的话可以自行删除并修改后面的类里面的代码。自带的pagehelper用的1.4.6里面的jsqlparser用的4.5.0。mybatis-plus用的3.4.2里面的jsqlparser用的4.0.0。jsqlparser包,不剔除是这样的,有个冲突,我用的前端写的请求,返回的格式和原来的一样,已兼容。你的Entity类上面需要增加表的名字。

lh155136的博客 3566

Android中给webview设置代理

亲测:支持安卓9.0以下都可以正常使用 webview在loadUrl之前,调用如下函数,设置代理: public static boolean setProxy(WebView webview, String host, int port, String applicationClassName) 在关闭、或者销毁webview之前,调用如下函数,取消代理: public stati...

huangwenkui1990的专栏 1万+

RagFlow实战:如何用DeepDoc引擎高效处理扫描PDF文档(附完整代码解析)

本文详细解析了如何利用RagFlow的DeepDoc引擎高效处理扫描PDF文档。通过实战演示从环境搭建、PDF预处理、文本检测与识别,到布局分析与表格结构提取的完整流程,并提供了完整的代码实现。该方案超越了传统OCR,能输出保留原始版面信息的结构化数据,为构建高质量知识库提供了强大支持。

weixin_29245767的博客 300

Android 在webview中设置代理

在android1.6之前的api中有有直接的方法来对webview设置代码,但是在之后的API中去掉了。所以只能寻求别的方法来设置代码。 下面代码是用反射原理来对webview设置代理: Java代码   public static boolean setProxy(Context ctx, String host, int port) {  

binyao02123202的专栏 1万+

黑五数据集实战:从消费者行为解码到零售智能决策

零售智能决策依赖对消费者行为的深度理解,其核心在于将结构化字段还原为真实商业动作。本文基于经典Black Friday数据集,系统阐释如何通过字段语义重定义、业务驱动的特征工程、轻量高效模型(如LightGBM)及定制化损失函数,构建可落地的库存预警、流失拦截与动线优化方案。重点融合‘消费人格指纹’与‘生态位稳定性分’两大热词,揭示数据背后的城市引力场、品类竞争网络与决策节奏图谱,为电商、快消及零售从业者提供从数据分析到业务闭环的完整方法论。

weixin_28630185的博客 345

win x64下安装oracle 12c出现[INS-30131]报错的解决方案

问题:  win x64下安装oracle 12c出现[INS-30131]报错的解决方案 安装oracle11g碰到“无法访问临时位置”的问题,详细信息如下: INS-30131] 执行安装程序验证所需的初始设置失败。 原因 - 无法访问临时位置。   操作 - 请确保当前用户具有访问临时位置所需的权限。   附加信息:  - 所有节点上的框架设置检查都失败  

一条道走到黑的GISer 1347

android webview 代理,Webview的用法

借助WebView控件,我们就可以在我们的应用程序中嵌入一个浏览器,从而非常轻松地实现各种各样的网页。先设置Layout:xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.an...

weixin_36127082的博客 469

立创·庐山派-K230-CanMV(嘉楠勘智)开发板通过ATK-ESP8266实现图像识别数据无线传输与原子云对接

本文详细介绍了如何利用立创·庐山派K230开发板与ATK-ESP8266模块实现图像识别数据的无线传输及与原子云平台的对接。通过硬件连接、环境配置、代码实现及调试技巧的讲解,为开发者提供了一套完整的物联网解决方案,特别适用于智能监控和边缘计算场景。

study的专栏 950

Android中的设计模式之代理模式

动态一般指的是在运行时的状态,是相对编译时的静态来区分,就是在运行时生成一个代理对象帮我们做一些逻辑处理。主要使用反射技术获得类的加载器并且创建实例。 动态代理可以在运行时动态创建一个类,实现一个或多个接口,可以在不修改原有类的基础上动态为通过该类获取的对象添加方法、修改行为。

金戈鐡馬 1326

【中国大学生计算机设计大赛信息可视化赛道】国奖项目深入剖析—中国古代奇异怪兽移动端可视化应用项目

【中国大学生计算机设计大赛信息可视化赛道】国奖项目深入剖析—中国古代奇异怪兽移动端可视化应用项目 注:本文主要目的是对于往年国奖项目案例-可视化项目的深入剖析讲解,对源码、项目特点、要点、特色继续深入分析。帮助大家学习技术,掌握规律。

一键难忘的博客 3729

Python爬虫博客:如何抓取时事新闻信息 —— 从各大新闻网站获取实时新闻数据

发送请求:向目标新闻网站发送 HTTP 请求,获取网页内容。解析网页:使用解析库(如)从网页中提取新闻标题、摘要、内容、发布时间等。绕过反爬虫机制:使用代理、设置请求头、模拟浏览器行为等策略绕过反爬虫技术。数据存储与清洗:将抓取的数据保存到本地文件或数据库中,并进行清洗,确保数据的可用性。在抓取过程中,我们还会面对很多实际问题,比如反爬虫技术、分页抓取、动态加载的内容等。接下来,我们将逐步介绍如何使用不同技术抓取静态和动态网页,并对抓取的内容进行处理。Scrapy。

2201_76125261的博客 2135

Android设计模式—代理模式

代理模式也是平时比较常用的设计模式之一。所谓代理模式就是在进行交互的时候,不和原本的对象直接交互,而是通过代理的方式,用代理来代替真正的对象进行交互,这样做的好处是降低了耦合性。 代理模式其实就是提供了一个新的对象,实现了对真实对象的操作,或成为真实对象的替身。在日常生活中也是很常见的。例如A要租房,为了省麻烦A会去找中介,中介会替代A去筛选房子,A坐享中介筛选的结果,并且交房租也是交给中介,这就是一个典型的日常生活中代理模式的应用。平时打开网页,最先开到的一般都是文字,而图片等一些大的资源都会延迟加载,这

zenmela2011的专栏 1839

10款AI工具赋能虚拟展厅设计:架构师效率提升90%的秘密武器

2020年全球疫情成为数字转型的催化剂,虚拟展厅从"可选项"迅速转变为"必需品"。根据Gartner最新报告,到2025年,超过70%的企业将采用虚拟展厅作为客户体验和产品展示的核心渠道。这一转变不仅是应急措施,更是商业模式的永久性革新。虚拟展厅突破了物理空间的限制——一个精心设计的虚拟展厅可以同时接待来自全球各地的访客,无需考虑场地容量;展品可以以数字形式永久保存,避免了物流和损耗问题;数据分析功能可以精确追踪每位访客的行为轨迹,提供前所未有的洞察。数据透视。

AI 领航者的博客 1573

Android设计模式-代理模式

介绍代理模式(Proxy Patter)也称委托模式,属于结构型设计模式。这是一个相当重要的设计模式,Android源码中随处可见。何为代理模式呢?比如每天吃饭时赶进度是常事,就叫公司的同时帮忙买饭,这就是一种代理;如果碰到辞职时老板不给发工资,还得委托个律师 帮你打官司,这也是代理。总之,即便在现实生活中,代理也是无处不在。定义为其他对象提供一种代理以控制这个对象的访问。使用场景当无法或者不想直接

vanpersie_9987的博客 1397

深度学习工具包 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")

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Android的设计模式-代理模式

前言Android的设计模式系列文章介绍,欢迎关注,持续更新中: Android的设计模式-设计模式的六大原则 创建型模式: Android的设计模式-单例模式 Android的设计模式-建造者模式 Android的设计模式-工厂方法模式 Android的设计模式-简单工厂模式 Android的设计模式-抽象工厂模式 Android的设计模式-原型模式

四月葡萄的博客 965

Devexpress16.2.6破解工具

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

Android设计模式之代理模式

为其他对象提供一种代理以控制对这个对象的访问。

lqw_qgf的博客 1051

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Android常用设计模式-代理模式

代理模式是Java中常用的设计模式之一,主要用于为其他对象提供一种代理以控制对这个对象的访问。

maoning20080808的专栏 747

Android设计模式之代理模式与使用场景

在Android开发中,代理模式是一种常用的结构型设计模式,它允许通过代理对象控制对另一个对象(即目标对象)的访问。下面详细介绍代理模式及其在Android中的典型应用场景。通过合理使用代理模式,可以提高代码的可维护性和可扩展性,同时遵循单一职责原则。:通过代理对象间接访问目标对象,代理可以增强或控制对目标对象的访问。

分享技术和日常 1087

一文搞懂Android设计模式之代理模式

前言 今天分享的文章是关于设计模式中的代理模式,代理模式在Android中的应用还是很广的,而且也是比较常用的一种设计模式。本来说是连续的写一系列的设计模式的文章的,但是发现这样效果可能不好,所以就穿插着写,希望大家喜欢。如果文中有任何错误的地方,欢迎大家指正,如果有更好的想法可以加我文末微信,直接给我提出,感谢你的不吝赐教。 本文主要是写个简单的demo来带着大家熟悉认识代理模式,最后举例分...

技术是个累积的过程 5028

Android中设计模式无处不在之简单工厂模式和代理模式

<br />最近在研究一些具体的设计模式,结合之前看到很多Android中java代码,发现在Android源码中使用设计模式的地方还真不少啊,好的系统果然要注重好的设计,注重可扩展、可维护。本次就从PhoneService中使用到的一些简单的设计模式类型开始介绍:<br /> <br />1.简单工厂模式:<br /><br />注:个人觉得这个工厂模式和标准的工厂模式有点稍微差别,标准的是有客户端来决定创建哪个实例,例如,要使用GSMPhone的话,一般使用Phone phone = PhoneFact

mawl2002的专栏 8079

java/android 设计模式学习笔记(9)---代理模式

这篇博客我们来介绍一下代理模式(Proxy Pattern),代理模式也成为委托模式,是一个非常重要的设计模式,不少设计模式也都会有代理模式的影子。代理在我们日常生活中也很常见,比如上网时连接的代理服务器地址,更比如我们平时租房子,将找房子的过程代理给中介等等,都是代理模式在日常生活中的使用例子。   代理模式中的代理对象能够连接任何事物:一个网络连接,一个占用很多内存的大对象,一个文件,或者是一

Shawn_Dut的专栏 1万+

Android设计模式——代理模式

Android设计模式——代理模式1.代理模式定义2.使用场景3.代理模式分类3.1 静态代理3.2 动态代理4.源码中的代理模式 1.代理模式定义   为其他对象提供一种代理控制这个对象的访问。说白了就是我们生活中的经纪人,我们想要做什么事情,都需要先询问经纪人,经纪人在来询问我们。 2.使用场景   当无法或不想直接访问某个对象或者访问该对象存在困难时可以通过一个代理对象来间接访问,为了保证客...

weixin_45468727的博客 384

Android常见设计模式——代理模式(Proxy Pattern)

文章目录1. 前言2. 代理模式(Proxy Pattern)2.1 静态代理模式2.2 动态代理模式3. Android 中的代理模式3.1 Retrofit中的代理模式(没有被代理者) 1. 前言 首先看下百度百科对代理模式的介绍: 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 其实也就是中介模式或者委托模式。在日常生活中代理模式很多,比如叫同事带饭、打官司等。使用代理模式的

梦否 2924
上一篇: Builder设计模式之构建万能Dialog
下一篇: 自定义View实战一:打造仿系统TextView
胡小明同学
博客等级 码龄10年 35粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值