RoboGuice 3.0 (一)入坑篇
RoboGuice是什么?
一个Android上的依赖注入框架。
依赖注入是什么?
从字面理解,这个框架做了两件事情,第一是去除依赖,第二是注入依赖。简单理解就是,将对象的初始化委托给一个容器控制器,即去除依赖,再从容器控制器中构建依赖,注入回原本的对象中,即注入依赖。
依赖注入的好处是对象不需要在乎其依赖的初始化,使代码变得无比简洁。
一.接入
在build.grade中添加依赖
dependencies {
provided 'org.roboguice:roboblender:3.0.1'
compile 'org.roboguice:roboguice:3.0.1'
}
二.视图注入
接触依赖注入后,最方便的可能就是视图的注入了,将之前成片的findViewById的代码省去,Activity中的代码量完成了史上第一次大扫除。
视图注入分三个步骤:
- 继承自RoboGuice的RoboActivity 当然RoboFragmentActivity也可以
- 为Activity加入content view(setContentView也可以使用注解来实现)
- 使用@InjectView来注入视图
@ContentView(R.layout.activity_main)
public class MainActivity extends RoboFragmentActivity {
@InjectView(R.id.text_test)
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textView.setText("hello there!");
}
}
由此可见,视图注入大大简化了Activity中的代码量。
同理 ,Fragment也是一样的。需要注意的是,视图注入需要在onViewCreated后使用。
public class AFragment extends RoboFragment {
@InjectView(R.id.fragment_text)
TextView textView;
public static AFragment newInstance() {
return new AFragment();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.a_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
textView.setText("Hi there!");
}
}
三.资源注入
RoboGuice除了提供了视图注入,还提供了资源的注入。
比如String资源、color资源、Animation资源等。
@ContentView(R.layout.activity_main)
public class MainActivity extends RoboFragmentActivity {
@InjectView(R.id.text_test)
TextView textView;
@InjectResource(R.string.app_name)
String appName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textView.setText(appName);
}
}
四.系统服务注入
在Activity中可以注入各种系统服务,比如震动、通知管理。
完整的列表在这:https://github.com/roboguice/roboguice/wiki/Provided-Injections
这样我们不用再去写烦人的getSystemService这种代码。
@ContentView(R.layout.activity_main)
public class MainActivity extends RoboFragmentActivity {
@Inject
Vibrator vibrator;
@Inject
NotificationManager notificationManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vibrator.vibrate(500L);
notificationManager.cancelAll();
}
}
五.对象注入
对象的注入最大程度的完成了代码的解耦工作。也是类似框架中上手最慢的。
想象一个场景,比如在Activity中用户判断登录状态,我们不需要在乎UserInfo是如何初始化的,只在乎得到用户是否登陆的状态。
结合实际情况,举个例子。这是一个用来储存用户信息的model。
public class UserInfo {
private String userId;
private String token;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public boolean isLogin(){
return !TextUtils.isEmpty(token);
}
}
使用注解注入UserInfo,RoboGuice会帮我们完成初始化工作,初始化时调用UserInfo的默认构造方法。
这样在没有写userInfo = new UserInfo()
我们便操作了对象。
@ContentView(R.layout.activity_main)
public class MainActivity extends RoboFragmentActivity {
@Inject
UserInfo userInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
userId = sharedPreferences.getString("userId", "");
token = sharedPreferences.getString("token", "");
String userId = sharedPreferences.getString("userId", "");
String token = sharedPreferences.getString("token", "");
userInfo.setUserId(userId);
userInfo.setToken(token);
}
}
再然而onCreate内部的取用户信息的代码确实很丑陋,我们需要在Activity中完成与页面不相关的初始化工作,核心原因是我们依赖了Activity中的Context。这就相当于,如果对象中的成员初始化时需要对象的一些属性,我们很难巧妙的将属性交给容器管理着负责初始化成员。
那么又该如何处理这么丑陋的代码呢。
RoboGuice提供了更让人欣喜的功能,将对象中的成员初始化需要的属性封装起来,提交给容器管理者,这样当依赖对象属性的成员初始化过程就可以完全脱离对象,在成功后注入回对象即可。
Talk is cheap! Show me the code.
在RoboGuice的Activity中,容器管理者已经默认提供了的属性比如页面中的Context,这样当成员初始化时,可以使用@Inject来标记构造方法以用来告诉RoboGuice不使用默认构造方法进行初始化,当构造方法中的参数属性已经由Activity对象提交给容器管理者时,即容器管理者会使用该构造方法进行初始化。
我们经过改装,UserInfo和Activity是这样的。其中@ContextSingleton注解标示UserInfo随Context的生命周期销毁而销毁,如果这里改为@Singleton,那么UserInfo的生命周期将是整个应用的生命周期,如果两个Activity都使用了该注解,那么产生的对象将是同一个。
这里需要注意的是,如果@ContextSingleton使用不当,将造成内存泄露,这个以后会有例子说明。
@ContextSingleton
public class UserInfo {
private static final String TAG = "UserInfo";
private Context context;
private String userId;
private String token;
@Inject
public UserInfo(Context context) {
this.context = context;
init();
}
private void init() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
userId = sharedPreferences.getString("userId", "");
token = sharedPreferences.getString("token", "");
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public boolean isLogin(){
return !TextUtils.isEmpty(token);
}
public void saveUserInfo(String userId) {
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
editor.putString("userId", userId);
editor.apply();
}
}
@ContentView(R.layout.activity_main)
public class MainActivity extends RoboFragmentActivity {
@InjectView(R.id.text_test)
TextView textView;
@Inject
UserInfo userInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(userInfo.isLogin()){
textView.setText(userInfo.getUserId());
} else {
textView.setText("未登录");
}
}
}
至此,入坑篇告一段落,这篇主要说明了RoboGuice的视图、资源、系统服务、对象等注入,为开发带来便捷,同时也减少了模块的耦合性。
RoboGuice 3.0 (一)入坑篇的更多相关文章
- Dagger2 (一) 入坑篇
为什么是Dagger2 为了更好的了解Dagger2,请先阅读RoboGuice篇了解依赖注入. 官方文档称,依赖注入这种技术已经在存在多年了,为什么Dagger2要造轮子? Dagger2是第一个全 ...
- mybatis(1):入坑篇
依赖 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artif ...
- 【Mysql MHA】CentOS7.6+Mysql8.0.16 入坑
1.防火墙 firewall-cmd --add-port=/tcp --permanent firewall-cmd --reload 2.SELINUX sed -i 's/SELINUX=enf ...
- vuex 入坑篇
Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 这个状态自管理应用包含 ...
- web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史
秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...
- web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】
http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...
- Vue入坑第一篇
写在前面的话:文章是个人学习过程中的总结,为方便以后回头在学习.文章中会参考官方文档和其他的一些文章,示例均为亲自编写和实践,若有写的不对的地方欢迎大家和我一起交流. 一.前言 本篇作为vue入门的一 ...
- Vue2.0史上最全入坑教程(下)—— 实战案例
书接上文 前言:经过前两节的学习,我们已经可以创建一个vue工程了.下面我们将一起来学习制作一个简单的实战案例. 说明:默认我们已经用vue-cli(vue脚手架或称前端自动化构建工具)创建好项目了 ...
- RxJava+RxAndroid+MVP入坑实践(基础篇)
转载请注明出处:http://www.blog.csdn.net/zhyxuexijava/article/details/51597230.com 前段时间看了MVP架构和RxJava,最近也在重构 ...
随机推荐
- php继承多态
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- JavaScript:声明变量名的语法规则
一.语法规则 1.变量必须使用字母.下划线(_)或者美元符($)开始. 2.然后可以使用任意多个英文字母.数字.下划线(_)或者美元符($)组成. 3.不能使用JS关键词与保留字. 二.示例 var ...
- iOS开发之使用XMPPFramework实现即时通信(一)
关于XMPP的理论介绍在本篇博客中就不做赘述了,如何在我们之前的微信中加入XMPP协议来实现通信呢?下面将会介绍一下XMPP的基本的知识,让我们的微信可以实现互联通信.要做的准备工作是要有服务器支持X ...
- Objective-C中把数组中字典中的数据转换成URL
可能上面的标题有些拗口,学过PHP的小伙伴们都知道,PHP中的数组的下标是允许我们自定义的,PHP中的数组确切的说就是键值对.而在OC我们要用字典(Dictionary)来存储,当然了Java用的是M ...
- ASP.NET MVC 6 一些不晓得的写法
今天在看 Scott Guthrie 的一篇博文<Introducing ASP.NET 5>,在 MVC 6 中,发现有些之前不晓得的写法,这边简单记录下,算是对自己知识的补充,有些我并 ...
- jar包依赖性查询
项目中碰到jar包冲突,需要排除一些jar包时先要了解jar的依赖关系,maven提供了命令行来查询: mvn dependency:tree 返回依赖的属性结构
- Oracle巡检脚本:ORAWatcher.sh
Oracle巡检脚本:ORAWatcher.sh #!/usr/bin/ksh echo "" echo "ORAWatcher Version:1.0.1" ...
- 符合我公司GIS开源解决方案的探讨
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 这一周,我对GIS开源解决方案中涉及到的开源软件以及相关技术 ...
- PHP之验证码的实现
简单的用PHP实现验证码: ?php /** *制作验证码 *1.启动session *2.设定标头 *3.创建画布 *4.创建颜色 *5.创建随机数并放到画布上 *6.将得到的若干随机数放入sess ...
- Gobblin采集kafka数据
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 找时间记录一下利用Gobblin采集kafka数据的过程,话不多说,进入正题 一.Gobblin ...