Android开发中依赖注入的应用

什么是依赖注入?

  依赖是指一个对象持有其他对象的引用。依赖注入则是将这些依赖对象传递给被依赖对象,而不是被依赖对象自己创建这些对象。

public class MyClass{
     private AnotherClass mAnotherObject;

     public MyClass(){
          mAnotherObject = new AnotherClass();
     }
}
 

  通过传递对象的方式,所传递对象的更改不会影响代码。

public class MyClass{
     private MyInterface mAnotherObject;

     public MyClass(MyInterface anotherObject){
          mAnotherObject = anotherObject;
     }
}

  依赖注入可以简化代码编写,并提供一个可适配的环境,方便进行单元测试以及功能模块的配置。

开发中可能会遇到这样的麻烦。

  我们将通过一个例子来理解依赖注入的应用场景:某Android应用需要一个列表来显示用户的好友。

public class FriendListFragment{
     private FriendListAPI mFriendListAPI;
     ......

     public FriendListFragment(){
          mFriendListAPI = new FriendListAPI();
     }

     private void getFriendList(){
          mFriendListAPI.getFriendList(new Callback(){
               public void onSuccess(List<User> list){
                    ......
               }
               ......
          });
     }
}

public class FriendListAPI{
     private OkHttpClient mHttpClient;

     public FriendListAPI(){
          mHttpClient= new OkHttpClient();
          //接下来各种Http配置
          ......
     }
}

  代码写好了,运行程序试试。可是,后台API没有准备好或者没有数据怎么办?自己添点测试数据试试吧。在FriendListFragment里面添加一个生成测试数据的方方法buildTestData(),并替换getFriendList()方法。等后台API准备好后再改回来。

  我们想测试网络有延迟或错误的时候,程序是否会出现异常。这需要通过配置OkHttpClient参数来实现测试场景,于是又要更改FriendListAPI中相关HttpClient配置代码,测试完后再修改回来。

  这样对代码进行多次修改,很容易出错。因此,对于多次使用的模块,我们可以通过注入的方式,将引用传入需要使用的类中,而不是自己创建。通过编写两个API,一个是直接请求后台数据,另一个则只是一些静态测试数据。需要测试的时候注入可生成测试数据的API,测试完后则切换为正式API。

public class FriendListFragment{
     private FriendListAPI mFriendListAPI;
     ......

     public FriendListFragment(FriendListAPI friendListAPI){
          mFriendListAPI = friendListAPI;
     }
}

public class FriendListAPI{
     private OkHttpClient mHttpClient;

     public FriendListAPI(HttpClient okHttpClient){
          mHttpClient= okHttpClient;
          ......
     }
}

  现在引入一个稍微复杂的场景,更多的Fragment需要使用FriendListAPI,我们需要在两个不同的地方进行注入,因此产生了许多重复代码。

  因此,我们需要一个容器,它知道什么地方需要注入,注入什么样的对象。

Dagger解决方案。

  这里简单的展示轻量级依赖注入库Dagger实现的注入。

  首先定义模块:

public class MyModule{
     @Provides @Singleton OkHttpClient provideOkHttpClient(){
          //这里可进行各种Http配置
          return new OkHttpClient();
     }

     @Provides @Singleton FriendListAPI provideFriendListAPI(){
          return newFriendListAPI();
     }
}

  初始化模块以及依赖对象图。

public class MyApplication extends Application{
     private ObjectGraph graph;

     @Override public void onCreate() {
          super.onCreate();
          graph = ObjectGraph.create(getModules().toArray());
     }

     protected List<Object> getModules() {
          return Arrays.asList(
               new MyModule(this));
     }

     public void inject(Object object) {
          graph.inject(object);
     }
}

  最后添加注入点并进行注入。

public abstract class BaseActivity extends FragmentActivity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          ((MyApplication) getApplication()).inject(this);
    }
}

public class FriendListFragment{
     @Inject FriendListAPI mFriendListAPI;
     ......
}

public class FriendListAPI{
     @Inject OkHttpClient mHttpClient;
     ......
}

  如需进行单元测试,或使用可生成测试数据的模拟API,则再编写一个模块,在初始模块和依赖对象图时替换即可。

现有的依赖注入性能?

  依赖注入虽能简化代码编写,方便单元测试,可是由于当前基于反射的依赖注入框架(GuiceRoboGuice)性能并不好。原因是他们会在程序运行的时候需要扫描代码中的注解,并需要花费内存映射到内存中。

  这里推荐使用Dagger是因为它使用了编译时注解,也就是说在编译代码的时候,Dagger就已经完成传统依赖注入框架在运行时所执行的任务。

什么时候需要依赖注入?

  当你需要将配置数据注入到一个或多个模块时。在开发过程中前端访问后台服务器地址会分为测试服务器和正式服务器,以及各种第三方分享key和ID,依赖注入都是非常好的选择。

  当需要将同一依赖注入到多个模块时。如加载图片以及图片存储管理组件(Picasso, Android-Universal-Image-Loader)。

  当需要对同一依赖注入不同的实现时。为方便开发和单元测试,后台API可有正式API和模拟API,通过依赖注入方便切换环境。

  当同一模块需要注入不同的配置时。

参考资料:

http://square.github.io/dagger/

时间: 2024-10-26 04:16:13

Android开发中依赖注入的应用的相关文章

Android快速开发必备——依赖注入(DI)类库的选择ButterKnife,AndroidAnnotations,RoboGuice

关注finddreams,一起学习,一起进步:http://blog.csdn.net/finddreams/article/details/45504133 现在做移动端开发的开发者,不管是Android和IOS,公司一般都是喜欢那种具备独立开发能力的人,因为APP项目相对较小,有时候一个人完全可以单独胜任一个项目.所以如果我们要能够具备独立开发的能力,快速敏捷开发是我们所必须要去思考的事情,毕竟一个人做APP所要做的事情还是挺多的,为了项目的如期上线,我们需要用到各种第三方的库和框架,这样可

Dagger——Android上的依赖注入框架

* 你也可以去Github查看这片文章 简介 在开发程序的时候,会用到各种对象,很多对象在使用之前都需要进行初始化.例如你要操作一个SharedPreference,你需要调用getSharedPreferences(String name,int mode)来获取一个对象,然后才能使用它.而如果这个对象会在多个Activity中被使用,你就需要在每个使用的场景中都写下同样的代码.这不仅麻烦,而且增加了出错的可能.dagger的用途就是:让你不需要初始化对象.换句话说,任何对象声明完了就能直接用

spring中依赖注入方式总结

Spring中依赖注入的四种方式 在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的setter方法注入 首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性.例如:为UserBiz类注入UserDAO,同时为UserBiz注入基本数据类型String,那么这时,就要为UserDAO对象和String类型设置se

Android开发中使用七牛云存储进行图片上传下载

Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储原理,上面这幅图片是官方给出的原理图,表述当然比较清晰了.可以看出,要进行图片上传的话可以分为五大步: 1. 客户端用户登录到APP的账号系统里面: 2. 客户端上传文件之前,需要向业务服务器申请七牛的上传凭证,这个凭证由业务服务器使用七牛提供的服务端SDK生成: 3. 客户端使用七牛提供的客户端S

Android开发中的MVP架构(转)

写在前面,本博客来源于公众号文章:http://mp.weixin.qq.com/s?__biz=MzA3MDMyMjkzNg==&mid=402435540&idx=1&sn=1cd10bd9efaac7083575367a8b4af52f&scene=1&srcid=0910ARzPpBvVYPI1NDBZnixa#wechat_redirect 最近越来越多的人开始谈论架构.我周围的同事和工程师也是如此.尽管我还不是特别深入理解MVP和DDD,但是我们的新项目

Android 开发中的日常积累

欢迎Star,Fork https://github.com/lizhangqu/CoreLink 里面记录了开发过程中有用的东西,欢迎补充,不定时更新. Android 性能优化 Android内存优化之OOM Android最佳性能实践(1):合理管理内存 Android最佳性能实践(2):分析内存的使用情况 Android最佳性能实践(3):高性能编码优化 Android最佳性能实践(4):布局优化技巧 Android 加固与反编译 Apktool dex2jar DecompileApk

MVP模式在Android开发中的最佳实践

这篇文章拖了好久了,一直存在草稿箱里没有继续写,趁今天有空,撸撸完. 回想一下,你刚刚学习Android的时候,总会看到一些书上写着,Android使用的是MVC模式,Activity就是一个Controller,或许那个时候,你没有什么深刻的体会.随着经验的积累.你发现,Activity既是Controller,掌管着许许多多的业务逻辑,同时它也作为View的一部分,控制着视图层的显示.久而久之,这个Controller便显得过于重,职责不再那么单一. 于是,再后来,为了使Activity的职

讨论Android开发中的MVC设计思想

最近闲着没事,总是想想做点什么.在时间空余之时给大家说说MVC设计思想在Android开发中的运用吧! MVC设计思想在Android开发中一直都是一套比较好的设计思想.很多APP的设计都是使用这套方案完成架构设计的. 谈到MVC我想分为以下几个点分点突进. 1.什么是MVC框架. 2.MVC如何工作 3.MVC的缺点 4.Android之MVC设计模式. 一.什么是MVC框架. MVC英文即Model-View-Controller,即把一个应用的输入.处理.输出流程按照Model.View.

Android开发中常见的设计模式

对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的同学,这里推荐2本书.一本是Head First系列的Head Hirst Design Pattern,英文好的可以看英文,可以多读几遍.另外一本是大话设计模式. 单例模式 首先了解一些单例模式的概念. 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 这样做有以下几个优点 对于