RoboGuice 3.0 (一)入坑篇

时间:2022-09-15 10:05:42

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 (一)入坑篇的更多相关文章

  1. Dagger2 (一) 入坑篇

    为什么是Dagger2 为了更好的了解Dagger2,请先阅读RoboGuice篇了解依赖注入. 官方文档称,依赖注入这种技术已经在存在多年了,为什么Dagger2要造*? Dagger2是第一个全 ...

  2. mybatis(1):入坑篇

    依赖 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artif ...

  3. 【Mysql MHA】CentOS7&period;6&plus;Mysql8&period;0&period;16 入坑

    1.防火墙 firewall-cmd --add-port=/tcp --permanent firewall-cmd --reload 2.SELINUX sed -i 's/SELINUX=enf ...

  4. vuex 入坑篇

    Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 这个状态自管理应用包含 ...

  5. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  6. web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】

    http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...

  7. Vue入坑第一篇

    写在前面的话:文章是个人学习过程中的总结,为方便以后回头在学习.文章中会参考官方文档和其他的一些文章,示例均为亲自编写和实践,若有写的不对的地方欢迎大家和我一起交流. 一.前言 本篇作为vue入门的一 ...

  8. Vue2&period;0史上最全入坑教程(下)—— 实战案例

    书接上文 前言:经过前两节的学习,我们已经可以创建一个vue工程了.下面我们将一起来学习制作一个简单的实战案例. 说明:默认我们已经用vue-cli(vue脚手架或称前端自动化构建工具)创建好项目了 ...

  9. RxJava&plus;RxAndroid&plus;MVP入坑实践(基础篇)

    转载请注明出处:http://www.blog.csdn.net/zhyxuexijava/article/details/51597230.com 前段时间看了MVP架构和RxJava,最近也在重构 ...

随机推荐

  1. Leetcode&colon; Rearrange String k Distance Apart

    Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...

  2. Class类的理解

      在java中,每个类都有一个相应的Class类的对象,因为每个类编译完成后,在生成的.class文件中,就会产生一个Class对象.     在运行期间,如果我们要产生某个类的对象,jvm会检查类 ...

  3. mongo数据库的导入导出

    http://www.iwangzheng.com/ [root@a02]$show dbs; changhong_tv_cms 0.078GB [root@a02]$ mongodump -d ch ...

  4. &lbrack;HTML Q&amp&semi;A&rsqb;&lbrack;转&rsqb;使pre的内容自动换行

    <pre> 元素可定义预格式化的文本.被包围在 pre 元素中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体. <pre> 标签的一个常见应用就是用来表示计算机的源代码 ...

  5. 支付宝支付php的demo或sdk报错 Warning&colon; openssl&lowbar;sign&lpar;&rpar; &lbrack;function&period;openssl-sign&rsqb;&colon; Unknown signature algorithm&period; in

    最近在做支付宝支付,在本地测试一切正常,上传到服务器就遇到报错: Warning: openssl_sign() [function.openssl-sign]: Unknown signature ...

  6. docker入门&lpar;二&rpar;容器与镜像的理解

    10张图带你深入理解Docker容器和镜像 申明:此篇文章是转载的(原文地址http://dockone.io/article/783),今天意外发现已经有人转载了(复制了),希望大家关注原创 原本打 ...

  7. GANs的回顾

    GANs第一篇比较熟悉,不介绍.看看变种. 1) LAPGANs:金字塔,逐步优化生成图片(Deep Generative Image Models using Lapalacian Pyramid ...

  8. 创建Docker私有仓库

    1.有时候,在公司内部为了提高分享的速度,需要在公司内部自己搭建一个本地的仓库,供私人使用. 2.docker官方提供了一个工具docker-registry,我们可以借助这个工具构建私有镜像仓库a. ...

  9. entity framework异常 The specified cast from a materialized &&num;39&semi;System&period;Int32&&num;39&semi; type to the &&num;39&semi;System&period;String&&num;39&semi; type is not valid

    ROW_NUMBER() OVER (ORDER BY (select Null)) AS Id entity framework 查询中有这句会有异常

  10. PHP&lowbar;EOL换行 与 base64编码

    base64编码包括64个字符:10个数字(0-9),26*2个字母(a-zA-Z),+,/ 其中还有一个第65个字符=作为后缀,没有实际作用. 来一段代码说明个问题: <?php $str = ...