> 接口回调与抽象类
-- interface
接口回调的一些优势和弱点,接口回调比较单一 冗余较多等。
使用接口回调的方式实现的,是在Java Swing中典型的事件驱动机制处理方式。事件驱动机制采用委托方式实现,委托又通过接口回调来完成具体功能。
持有接口对象,可以达到解耦。Java接口比Java抽象类更抽象化。但是接口不是类。
一个接口类型的引用指向了一个实现给接口的对象,这是java中的一种多态现象。java中的接口不能被实例化,但是可以通过接口引用指向一个对象,这样通过接口来调用方法可以屏蔽掉具体的方法的实现,这是在JAVA编程中经常用到的接口回调,也就是经常说的面向接口的编程。面向接口编程是面向对象的思想之一。
接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。这就像契约模式,如果实现了这个接口,那么就必须确保使用这些方法。接口只是一种形式,接口自身不能做任何事情。
-- 在代码解耦中,有一种非常重要的方法就是“面向接口编程”,面向接口编程使得协作的模块之间只需要关注接口API,而无需关注API的具体实现。
Java的代理模式可以分成静态代理和动态代理。
静态代理模式很简单,它有三部分组成:接口、委托类、代理类。代理类直接持有委托类的实例,代理类实现了接口里面的方法,没有方法的执行内部直接通过调用委托类实例对应的方法执行。
动态代理比静态代理来的更加方便些,当然其本质也是一样的。看过动态代理源码之后可以简单的总结一下:动态代理在运行时生成代理类的字节码,从字节码中创建出代理类的实例,对其所有的方法调用都转发到 invocation handler 的 invoke 方法,在 invoke 方法中执行额外的逻辑。
-- abstract
abstract抽象类是用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板。
抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。一个类只能继承一个抽象类,而一个类却可以实现多个接口。
抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
-- 什么时候使用抽象类和接口:
1.如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
2.如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
3.如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。
Java8中的默认方法和静态方法:Oracle已经开始尝试向接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异。现在,我们可以为接口提供默认实现的方法了并且不用强制子类来实现它。
-- 接口传值,回调
public interface IPresenter {
void codeMsg(String str);
}
public class ObjA {
private IPresenter ip;
public ObjA(IPresenter ip) {
this.ip = ip;
set();
}
public void set() {
ip.codeMsg("A class");
}
}
public class ObjB implements IPresenter{
public static void main(String[] args) {
new ObjA(new ObjB());
}
@Override
public void codeMsg(String str) {
System.out.println(str);
}
}
> 事件驱动 ,观察者模式(区别于接口回调);编程范式,回调函数,EventBus
-- 观察者模式与事件驱动模式, 观察者模式和回调机制
Android中大量的使用了观察者模式,Framework层里面的事件驱动都是基于观察者模式实现的。另外在Framework层里面的各种服务在数据变更的时候,也是通过观察者模式实现上层数据更新的。像View的Listener监听、GPS位置信息监听、BroadcastReceiver等都是基于观察者模式实现的。
-- Android中Activity、Service、Fragment之间的相互通信比较麻烦,主要有以下几种方式:
(1)使用广播,发送者发出广播,接收者接收广播后进行处理;
(2)使用Handler和Message,如下载线程完成下载任务后,给UI发送Message,UI收到Message后更新界面。
(3)简单有效的方法事件总线
-- 事件总线:EventBus,Otto,Rxjava,RxAndroid,AndroidEventBus(已经不维护)。
事件驱动编程是一种编程范式,程序的执行流程是由动作(actions,例如用户交互,其他线程发送的消息等等)触发的事件(event)决定的。
otto和AndroidEventBus采用的是注解;EventBus则是规定方法名基础上采用反射,v3.0后也采用了注解,有某些高级特性例如线程传递和订阅者优先级.
-- EventBus在ViewPager Fragment中使用
fragment引用EventBus 多次调用问题-> lazyViewPager,懒加载Fragment。
RxJava基于事件的程序的库,RxJava是利用可观察序列和操作符来编写异步和基于事件的程序。
RxBus的实现及简单使用- https://lingyunzhu.github.io/2016/03/01/RxBus%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8F%8A%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8/
RxBus并不是一个库,而是一种模式。如果项目已经加入RxJava和EventBus,不妨用RxBus代替EventBus,以减少库的依赖。
RxBus在rxjava2.0 的使用-https://blog.csdn.net/u011271348/article/details/69946650
JakeWharton 大神写了即使出现异常也不会终止订阅关系的 RxRelay- https://github.com/JakeWharton/RxRelay
Android optimized event bus that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality.
EventBus 3.0版本之前使用约定优于配置原则,接受事件的方法必须以 onEvent 开头,使用起来不是很方便,3.0版本之后也支持了注解方式。根据官方的性能对比,EventBus 在各个方面都明显比 Otto 更快,因此 EventBus 和 Otto 对比建议使用 EventBus。
如果项目中已经集成了 RxJava,可以考虑使用 RxBus 去实现。
Android事件驱动编程-基于EventBus(一) 虽然在Android开发具有某些事件驱动的特性,但它还远不是纯粹的事件驱动架构。事件驱动编程是一种编程范式,程序的执行流程是由动作(actions,例如用户交互,其他线程发送的消息等等)触发的事件(event)决定
EventBus从字面上看是事件总线,解决了传统的观察这模式的问题;
用于搭建高性能、全异步(a)、树形结构(t)的BUS消息系统的跨平台框架库- https://github.com/atframework/libatbus
Android事件总线(一)EventBus3.0用法全解析- https://blog.csdn.net/itachi85/article/details/52205464
Android常用框架----事件总线系列框架- https://blog.csdn.net/siwenyy/article/details/75041216
android-eventbus3.0 demo- https://github.com/henrymorgen/android-eventbus3.0
EventBus- https://github.com/greenrobot/EventBus
EventBus3.0使用详解- https://blog.csdn.net/baidu_17508977/article/details/51612098
EventBus的使用:
-- 1.EventBus注册和取消注册写在onCreate()和onDestory()。
-- 2.EventBus消息发送函数
EventBus3.0设置tag,只有post(Ojbect obj )的方法,并没有post(Object obj,String tag)的方法啊??基本数据类型消息不可以传的
EventBus.getDefault().post(new MsgBody(MsgBody.TYPE_1));
postSticky(Object event)
postSingleEvent(Object event, EventBus.PostingThreadState postingState)
postToSubscription(Subscription subscription, Object event, boolean isMainThread)
-- 3.EventBus消息接受函数onEvent,onEventBackgroundThread,onEventAsync,onEventMainThread
EventBus 给消息实体加个消息类型参数;或者构造不同的消息实体
EventBus3.0加个标签标识不同fragment或不同的消息类型
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(AdapterEvent event) {
if (event.getWhich() == which) {
//......
}
}
@Subscribe(threadMode = ThreadMode.POSTING)
@Subscribe(threadMode = ThreadMode.MAIN)
@Subscribe(threadMode = ThreadMode.BACKGROUND)
@Subscribe(threadMode = ThreadMode.ASYNC)
> GUI界面
-- 几乎所有的GUI界面都采用事件驱动编程模型,很多服务器网络模型的消息处理也会采用,甚至复杂点的数据库业务处理也会用这种模型,因为这种模型解耦事件发送者和接收者之间的联系,事件可动态增加减少接收者,业务逻辑越复杂,越能体现它的优势。
-- Android界面渲染流程线:
UI对象—->CPU处理为多维图形,纹理 ->通过OpenGL ES接口调用GPU -> GPU对图进行光栅化(Frame Rate ) ->硬件时钟(Refresh Rate) ->垂直同步 ->投射到屏幕。
android的广播机制是基于系统的Binder机制实现IPC或者进程内部的通信,而Binder这种IPC机制相比于Linux原有的机制来说具有,性能更好、安全性更高和易用性更好的特点.所以android系统中很多系统事件都是基于广播的方式来发送,如开机广播、电量低的提醒广播等。
一般,用户经常会通过界面与应用交互,Android框架采用事件驱动的形式与用户交互。可以通过从用户交互的View设置事件监听器的方式来实现对事件的处理,一个事件监听器是View类中一个包含单一回调方法的接口。当注册了监听器的View发生了对应的监听事件时,Android框架就会回调相应的监听方法。