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,最近也在重构 ...
随机推荐
-
Leetcode: Rearrange String k Distance Apart
Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...
-
Class类的理解
在java中,每个类都有一个相应的Class类的对象,因为每个类编译完成后,在生成的.class文件中,就会产生一个Class对象. 在运行期间,如果我们要产生某个类的对象,jvm会检查类 ...
-
mongo数据库的导入导出
http://www.iwangzheng.com/ [root@a02]$show dbs; changhong_tv_cms 0.078GB [root@a02]$ mongodump -d ch ...
-
[HTML Q&;A][转]使pre的内容自动换行
<pre> 元素可定义预格式化的文本.被包围在 pre 元素中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体. <pre> 标签的一个常见应用就是用来表示计算机的源代码 ...
-
支付宝支付php的demo或sdk报错 Warning: openssl_sign() [function.openssl-sign]: Unknown signature algorithm. in
最近在做支付宝支付,在本地测试一切正常,上传到服务器就遇到报错: Warning: openssl_sign() [function.openssl-sign]: Unknown signature ...
-
docker入门(二)容器与镜像的理解
10张图带你深入理解Docker容器和镜像 申明:此篇文章是转载的(原文地址http://dockone.io/article/783),今天意外发现已经有人转载了(复制了),希望大家关注原创 原本打 ...
-
GANs的回顾
GANs第一篇比较熟悉,不介绍.看看变种. 1) LAPGANs:金字塔,逐步优化生成图片(Deep Generative Image Models using Lapalacian Pyramid ...
-
创建Docker私有仓库
1.有时候,在公司内部为了提高分享的速度,需要在公司内部自己搭建一个本地的仓库,供私人使用. 2.docker官方提供了一个工具docker-registry,我们可以借助这个工具构建私有镜像仓库a. ...
-
entity framework异常 The specified cast from a materialized &#39;System.Int32&#39; type to the &#39;System.String&#39; type is not valid
ROW_NUMBER() OVER (ORDER BY (select Null)) AS Id entity framework 查询中有这句会有异常
-
PHP_EOL换行 与 base64编码
base64编码包括64个字符:10个数字(0-9),26*2个字母(a-zA-Z),+,/ 其中还有一个第65个字符=作为后缀,没有实际作用. 来一段代码说明个问题: <?php $str = ...