Dhroid框架笔记(IOC、EventBus)

dhroid 目前包含了6大组件供大家使用
1.Ioc容器: (用过spring的都知道)视图注入,对象注入,接口注入,解决类依赖关系
2.Eventbus: android平台事件总线框架,独创延时事件,事件管理轻松
3.Dhnet: 网络http请求的解决方案,使用简单,减少代码,自带多种网络访问缓存策略
4.adapter模块: 数据绑定轻松,不用写多余的adapter,天生网络支持(一行代码搞定加载,刷新问题)
5.DhDb: android中sqlite的最轻量orm框架(增删改查轻松搞定)
6.Perference: android自带Perference 升级版,让你的Perference更强大,更方便

说了这么多,来点干货吧

1.1 IOC容器的注解

1.1.1 注入视图

@InjectView(id=R.id.text)TextView textV;
//注入布局文件
@InjectView(layout=R.layout.ioc_head)ViewGroup headV;
//添加注入事件
@InjectView(id=R.id.assertFile,click="toInstal")View instalApkV;

//
@InjectView(id=R.id.listView,itemClick="toEditStudent",itemLongClick="toDeleteStudent")ListView listView; 

public void toEditStudent(AdapterView<?> parent, View view, int position, long id) {
Log.v("dhroid", "itemClick事件");
}
public void toDeleteStudent(AdapterView<?> parent, View view, final int position, long id) {
Log.v("dhroid", "itemLongClick事件");
}

1.1.2注入资源

使用注解@InjectResource,资源可以注入drawable,string,color,dimen

//注入字串
@InjectResource(string=R.string.app_name)
String appname;
//注入颜色
//这里不能为int因为int有默认值0 有值的属性会被忽略,防止重复注入
@InjectResource(color=R.color.link)
Integer colorLink;
//注入图片
@InjectResource(drawable=R.drawable.ic_launcher)
Drawable icDraw;
//注入dimen
@InjectResource(dimen=R.dimen.testdimen)
Float dime;

1.1.3 注入extra

页面间数据传递也可以注入的,下面代码相当于getIntent().getStringExtra("str");

//接受传入的字符串
@InjectExtra(name="str",def="默认值")String extra;

 Integer,Long,Float,Double,Boolean(特殊的JSONObject,JSONArray,其他bean对象都能传)

 这里需要特殊说明一下不能使用int,long,float,double因为他们有默认值,注入时发现有值会滤过的

如果有默认值请写到def属性下,

特殊的JSONObject,JSONArray和bean对象是特殊强制转换的结果,传入的对象都还string类型

传入时

it.putExtra("jo", "{name:'我是json字符串'}");
it.putExtra("array", "[{name:'我是json数组'}]");
it.putExtra("bean", "{name:'我是json字符串'}");

接受时

@InjectExtra(name="jo")JSONObject extrajo;
@InjectExtra(name="array")JSONArray extraarray;
@InjectExtra(name="bean")User extrauser;

1.1.4 注入assert

@InjectAssert主要是用来注入assert中的文件的

下面代码可以注入assert文件夹下面的testtext.json的文本内容

@InjectAssert(path="testtext.json")  String testassert; @InjectAssert(path=“testtext.json”)   //文本内容本来就是json可以写为   JSONObject jo;
@InjectAssert(path="anzhi.apk")     File apkFile;

     因为assert本身不支持文件读写的所以其实先将文件拷贝出去后然后赋值的,文件拷贝时是异步的使用时需要注意文件是否拷贝完成,
可以在需要使用前面的页面就进行一次注入(文件只会拷贝一次)
Fragment 中使用  如果你不是继承自BaseActivity,你需要在setContentView()后调用 InjectUtil.inject(this);
如果你在Fragment 中使用,需要在onActivityCreated方法中调用 InjectUtil.inject(this);
同时还可以在自定义View中使用,也是InjectUtil.inject(this);
其实BaseActivity里面很简单的

关于类继承问题
继承类时
父类中的 只有有共有属性,即public的属性才能被注入

1.5 对象依赖问题

//或者在属性在加注解  @InjectIDialog dialoger;

IocContainer的知识:

使用ioc需要先在application初始化

//IOC的初始化
IocContainer.getShare().initApplication(this);
IocContainer.getShare().bind(具体实现类).to(目标类或借口) //这是单例 .scope(作用域)
//接受传入的字符串
@InjectExtra(name="str",def="默认值")
String extra;
//接受传入的数字
@InjectExtra(name="int",def="1")
Integer extraint;
//接受传入的json对象(传入时是已字符串传入的)这个默认值没用
@InjectExtra(name="jo")
JSONObject extrajo;
//标准注入 单例  注入接口 需要在application中配置
@Inject
IDialog dialoger;
//标准注入 单例  注入类
@Inject
DhDB db;
//根据tag拿对象这里拿到的manager1和manager1copy是同一对象,manager2和manager2copy是同一对象
@Inject(tag="manager1")
TestManager manager1;
@Inject(tag="manager1")
TestManager manager1copy;
@Inject(tag="manager2")
TestManager manager2;
@Inject(tag="manager2")
TestManager manager2copy;


//这个测试根据名字获取对象配置请看application
@Inject(name="testmm")//这里获取到的对象是TestManagerMM
TestManager managermm;

2.1  EventBus  事件总线

eventbus 事件总线也是一个编程思想,为什么要设计EventBus了,因为他是领域驱动设计中比不可少的模块,它承担传输数据的作用,它可以解耦模块之间的耦合性。

Android开发过程中,我们总会遇到各个组件模块之间的通信,当功能点越来越多的时候,组件间的通信难免会变得混乱。

案例1:

需求:假设你有A,B,C,D,E,F几个页面,A 是列表,A->B,或者A->C,B->D->E-F,F 是发布页,A页面从B,C,D,E返回时都是不需要刷新的,只有从F返回,A才需要刷新;

需求:有一个service是轮询后台服务器的查看用户消息数,当有新消息时,如果用户在msg页面,需要刷新当前页

需求:在第一个页面的左侧滑中,会显示用户的头像,用户名等信息,你是每次打开侧滑时你是一直获取数据吗,当然有人知道可以放到perference中但是什么时候更新perference中的数据了,用户更新了各种资料,发布了什么都可以更新数据,维护这个更新也不容易吧

使用eventbus只需要在类中注入一个eventbus单例接口:

@Inject EventBus bus;
//这个是在后台处理事件
bus.registerListener("事件名", "监听器名字", new OnEventListener(){
      @Override
       public Boolean doInBg(Event event) {
              super.doInBg(event);Log.v(log_tag, "我是在后台线程处理的请勿操作UI,我接受到的参数是"+event.getParams()[0]);
              return false; } });

或者

//这个是前台处理事件
bus.registerListener("事件名", "监听器名字", new OnEventListener(){
      @Override
      public Boolean doInUI(Event event) {
             super.doInUI(event); dialoger.showToastShort(EventBusOneActivity.this, 我是在UI线程处理的,我接受到的参数1是"+event.getParams()[0]+"我接受到的参数2是"+event.getParams()[1]); return false; }});

在onCreate中注册 需要在finish取消注册;在onResume中注册需要在onStop取消注册。

我们的监听是有延时的,就是说registerListener时,eventbus会将之前发布的事件触发一下,也就是说你先fireEvent,然后在registerListener也是可以监听到事件的

有人可能会问为什么会这样设计

因为我希望 A 页面中,在onResume中我们注册事件,在onStop中我们取消监听

如果你要清空你注册事件之前发布的事件可以

bus.clearEventTime("事件名", "监听名");

bus.fireEvent("事件名","可以传递多个参数","参数2");

bus.unregisterListener("事件名","监听器名");

问题2解决,只需要在service中发布事件,在你有关的页面,监听事件就行

问题3解决, 先注册一个监听器,事件发布时网络获取用户信息,当用户更新头像后,发布一下事件就行

下面是用注解实现:

@OnEvent(name="事件名",ui=true,onBefore=true)

public void onEvent2(String p1,String p2){
   dialoger.showToastShort(this, "事件2触发参数1:"+p1+"参数2:"+p2 );
}

注解name参数,事件名,ui是否在ui线程,onBefore=true,可以监听事件监听前的事件.

当然使用这个注解还需要:

@Override
protected void onResume() {
super.onResume();
EventInjectUtil.inject(
this); } @Override protected void onStop() { super.onStop(); EventInjectUtil.unInject(this); }
原文地址:https://www.cnblogs.com/Jsonlu/p/4746018.html