博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android -- 带你从源码角度领悟Dagger2入门到放弃(三)
阅读量:6323 次
发布时间:2019-06-22

本文共 9383 字,大约阅读时间需要 31 分钟。

1, 前面两篇文章我们知道了怎么使用常用的四种标签,现在我们结合我们自己的项目中去简单的使用

  在我们搭建项目的时候,一般会创建自己的Application,在里面进行一些初始化如一些第三方的GreenDao、ShareSDK等等,再或者提供一些常用的属性初始化:例如初始化屏幕的宽高度、初始化SPUtils工具类等,所以我们可以创建App类继承自Application(这里我只写了简单的App对象创建,没有写其他的任何方法)

package com.qianmo.rxjavatext;import android.app.Application;/** * Created by Administrator on 2017/4/21 0021. * E-Mail:543441727@qq.com */public class App extends Application {    public static App instance;    public static synchronized App getInstance() {        return instance;    }    @Override    public void onCreate() {        super.onCreate();        instance = this;    }}

  一般情况下我们使用很多情况下会使用到上下文环境,而使用Activity的上下文环境会容易发生内存泄漏问题,即该Activity本应该被销毁,但因为外部类持有context对象的引用而导致无法回收Activity,所以这里我们一般使用App中的上下文,这时候我们要向所有的activity提供一个Application的上下文环境对象,再结合我们之前学习的Dagger2知识,先写一下AppModule提供对象的代码

package com.qianmo.rxjavatext.di;import com.qianmo.rxjavatext.App;import javax.inject.Singleton;import dagger.Module;import dagger.Provides;/** * Created by Administrator on 2017/4/21 0021. * E-Mail:543441727@qq.com */@Modulepublic class AppModule {    public final App application;    public AppModule(App application) {        this.application = application;    }    @Provides    @Singleton    App provideApplicationContext() {        return application;    }}

  很简单,就是在创建AppModule对象的时候将App对象传递进来,然后添加provideApplicationContext暴露app对象出去,再来看看AppComponent类

package com.qianmo.rxjavatext.di;import com.qianmo.rxjavatext.App;import javax.inject.Singleton;import dagger.Component;/** * Created by Administrator on 2017/4/21 0021. * E-Mail:543441727@qq.com */@Singleton@Component(modules = AppModule.class)public interface AppComponent {    //向下层提供上下文环境    App getContext();}

  这里可能大家有个疑问App getContext();这句代码是干什么的,我们知道Activity中有可能要使用到App上下文环境(虽然这个方法不一定能用到,但是我们还是准备着),这里就是给下层提供这个对象的。那么我们需要在App初始化这个AppComponent对象了

public class App extends Application {    public static App instance;    public static AppComponent appComponent;    public static synchronized App getInstance() {        return instance;    }    @Override    public void onCreate() {        super.onCreate();        instance = this;    }    public static AppComponent getAppComponent() {        if (appComponent == null) {            appComponent = DaggerAppComponent.builder().appModule(new AppModule(instance)).build();        }        return appComponent;    }}

  那么有同学就会有这个疑问什么叫“下层”,用什么表示上下层关系,这里给出的解释是当另一个Activity中的module也想拥有我们的上下文application对象呢?是还要想我们的AppModule一样吗?nonono,这是我们使用dependencies,首先创建Activity的Module,这个类很简单就是提供我们的activity对象,所以代码如下

package com.qianmo.rxjavatext.di;import android.app.Activity;import com.qianmo.rxjavatext.di.scope.ActivityScope;import javax.inject.Singleton;import dagger.Module;import dagger.Provides;/** * Created by Administrator on 2017/4/21 0021. * E-Mail:543441727@qq.com */@Modulepublic class ActivityModule {    private Activity mActivity;    public ActivityModule(Activity mActivity) {        this.mActivity = mActivity;    }    @Provides    @ActivityScope    Activity provideActivity() {        return mActivity;    }}

  这里的@ActivityScope就是我们上一篇学习的自定义Scope注解标签,没什么难的,再看看我们的ActivityComponent

package com.qianmo.rxjavatext.di;import android.app.Activity;import com.qianmo.rxjavatext.MainActivity;import com.qianmo.rxjavatext.di.scope.ActivityScope;import dagger.Component;/** * Created by Administrator on 2017/4/21 0021. * E-Mail:543441727@qq.com */@ActivityScope@Component(dependencies = AppComponent.class,modules = ActivityModule.class)public interface ActivityComponent {    //将当前的activity暴露出去    Activity getActivity();    void inject(MainActivity mainActivity);}

  dependencies 关键字就是这样使用的 ,例如我们创建student对象,需要App的对象(当然这个需求在现实中是不成立的),我们就可以这样写Module

package com.qianmo.rxjavatext.di;import android.app.Activity;import android.content.Context;import com.qianmo.rxjavatext.Student;import com.qianmo.rxjavatext.di.scope.ActivityScope;import javax.inject.Singleton;import dagger.Module;import dagger.Provides;/** * Created by Administrator on 2017/4/21 0021. * E-Mail:543441727@qq.com */@Modulepublic class ActivityModule {    private Activity mActivity;    public ActivityModule(Activity mActivity) {        this.mActivity = mActivity;    }    @Provides    @ActivityScope    Activity provideActivity() {        return mActivity;    }    @Provides    Student provideStudent(App app) {        return new Student(app);    }}

  我们按Ctrl+F9编译一下,发现我们的程序可以编译过来,正常的话不是应该报错误说App没有注入对象吗,为什么这里是可以运行,这就是dependencies 关键字的用法了,这里我们使用的是AppComponent中的getContext方法的app对象了。

  OK,这里我们在activity中开始调用试试创建Student对象,看看能不能拿到值

package com.qianmo.rxjavatext;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.CheckBox;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import com.jakewharton.rxbinding.view.RxView;import com.jakewharton.rxbinding.widget.RxCompoundButton;import com.qianmo.rxjavatext.di.ActivityComponent;import com.qianmo.rxjavatext.di.ActivityModule;import com.qianmo.rxjavatext.di.DaggerActivityComponent;import java.util.Collections;import java.util.List;import java.util.concurrent.TimeUnit;import javax.inject.Inject;import rx.Observable;import rx.Subscriber;import rx.android.schedulers.AndroidSchedulers;import rx.functions.Action0;import rx.functions.Action1;import rx.functions.Func1;import rx.schedulers.Schedulers;public class MainActivity extends AppCompatActivity {    //需要一个Student对象    @Inject    Student mStudent;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initInject();    }    //开始注解    public void initInject() {        getActivityComponent().inject(this);    }    protected ActivityComponent getActivityComponent() {        return DaggerActivityComponent.builder()                .appComponent(App.getAppComponent())                .activityModule(getActivityModule())                .build();    }    protected ActivityModule getActivityModule() {        return new ActivityModule(this);    }}

  运行一下看一下打印结果

04-21 05:36:19.510 2646-2646/com.qianmo.rxjavatext I/System.out: 打印上下文对象呀com.qianmo.rxjavatext.App@34877b0

  没问题,说明我们的程序没问题,但是在实际项目中我们都是要编写BaseActivity的,所以我们需要在BaseActivity中这样写

public abstract class BaseActivity
extends AppCompatActivity implements BaseView { @Inject protected T mPresenter; protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayout()); initInject(); if (mPresenter != null) mPresenter.attachView(this); App.getInstance().addActivity(this); initEventAndData(); } @Override protected void onStart() { super.onStart(); } @Override protected void onDestroy() { super.onDestroy(); } /** * 添加注解 */ protected abstract void initInject(); protected abstract int getLayout(); protected abstract void initEventAndData(); protected ActivityComponent getActivityComponent(){ return DaggerActivityComponent.builder() .appComponent(App.getAppComponent()) .activityModule(getActivityModule()) .build(); } protected ActivityModule getActivityModule(){ return new ActivityModule(this); }}

  这里的BaseView和BasePresenter都是我们的MVP的基类,里面很简单的没有说明代码的,我们在具体的activity中怎么使用呢?首先创建MainActivity,在这里调用 mPresenter.attachView(new MainView())方法

package com.qianmo.rxjavatext.mvp.view;import com.qianmo.rxjavatext.R;import com.qianmo.rxjavatext.base.BaseActivity;import com.qianmo.rxjavatext.mvp.presenter.MainPresenterImpl;/** * Created by Administrator on 2017/4/21 0021. * E-Mail:543441727@qq.com */public class SecondActivity extends BaseActivity
{ @Override public void showError(String msg) { } @Override public void useNightMode(boolean isNight) { } @Override protected void initInject() { getActivityComponent().inject(this); } @Override protected int getLayout() { return R.layout.activity_main; } @Override protected void initEventAndData() { mPresenter.attachView(new MainView()); }}

  再看看重要的MainPresenterImpl类

package com.qianmo.rxjavatext.mvp.presenter;import android.content.Context;import android.widget.Toast;import com.qianmo.rxjavatext.App;import com.qianmo.rxjavatext.base.BasePresenter;import com.qianmo.rxjavatext.mvp.view.MainView;import javax.inject.Inject;import rx.Observable;import rx.Subscriber;import rx.Subscription;/** * Created by MVPHelper on 2016/11/08 */public class MainPresenterImpl implements BasePresenter
{ private Context context; @Inject public MainPresenterImpl(App app) { this.context = app; } @Override public void attachView(MainView view) { Toast.makeText(context, "获取到值了", Toast.LENGTH_SHORT).show(); } @Override public void detachView() { }}

  在这里最关键的标注了构造函数MainPresenterImpl,这样我们就注解到了该presenter对象了,看一下效果,ok,基本上我们就是在MVP工程下注解presenter对象了,关键是封装!!!(如果你封装很好了,后面开发使用就很简单,而且也不用单独的写一些Module、component类)

  最后,说一下使用范围对于中小型的项目真心没必要使用Dagger2,还有如果你是Android负责人的话,你还要考虑一下你的Android同事他们上手Dagger2的情况,所以这里还是要试开发情况定(感觉这一片还是没和大家在项目封装的时候讲清楚啊,关键是封装是Dagger两个都是不容易上手的,麻蛋,自己思路写的也混乱了,祝大家早日拖坑)。

 

转载于:https://www.cnblogs.com/wjtaigwh/p/6744939.html

你可能感兴趣的文章
一个全新的拖拽分页—艺术啊
查看>>
Linux学习之CentOS(三十)--SELinux安全系统基础
查看>>
LVS+keepalived高可用群集
查看>>
jQuery库简介
查看>>
win7系统设置电脑不待机状态的操作方法
查看>>
u盘文件误删怎么恢复?简单几步就能解决
查看>>
手把手教你如何使用驰骋工作流程引擎的表单设计器做数据提交前的表单验证...
查看>>
nginx php 超过4M文件上传失败,uploadify i/o error解决。
查看>>
nginx+php安装配置
查看>>
LAMP+Centos6.5上安装zabbix
查看>>
android判断网络连接状态的三种方法
查看>>
ZOJ Monthly, March 2013 解题报告
查看>>
LaTex表格 Itemize&&enumerate
查看>>
Spring Boot中@OneToMany与@ManyToOne几个需要注意的问题
查看>>
文件传输协议之FTP
查看>>
Openstack 安装部署指南翻译系列 之 Glance服务安装(Image)
查看>>
Java 使用POI实现execl的导入导出数据实践
查看>>
Unity3D游戏开发之伤害数值显示
查看>>
如何在Linux上搭建一个基于Web的轻型监控系统
查看>>
linux基础命令使用
查看>>