Android dagger的使用

官方讲解:https://developer.android.google.cn/training/dependency-injection/dagger-basics?hl=zh_cn
Google demo:https://github.com/android/architecture-samples

添加依赖库

	//dagger2
    implementation 'com.google.dagger:dagger:2.35'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.35'
 	// retrofit2
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    // okhttp3
    implementation 'com.squareup.okhttp3:okhttp:3.8.0'
    // log拦截器
    implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0'
    // cookie管理
    implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'

创建实例提供者

Api

@Module
public class ApiModule {

    @Provides
    @Singleton
    public ServiceApi provideServiceApi(Retrofit retrofit) {
        return retrofit.create(ServiceApi.class);
    }

    @Provides
    @Singleton
    public Retrofit getRetrofit(OkHttpClient okHttpClient) {
        Gson gson = new GsonBuilder()
//                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
                    @Override
                    public Date deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                        String date = element.getAsString();
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        format.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        try {
                            Date date1 = format.parse(date);
                            return date1;
                        } catch (ParseException exp) {
                            exp.printStackTrace();
                            return null;
                        }
                    }
                })
                .create();
        return new Retrofit.Builder()
                // 集成RxJava处理
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                // 集成Gson转换器
                .addConverterFactory(GsonConverterFactory.create(gson))
                // 使用OkHttp Client
                .client(okHttpClient)
                // baseUrl总是以/结束,@URL不要以/开头
                .baseUrl(AppConfig.API_SERVER_URL)
                .build();
    }

    @Provides
    @Singleton
    public OkHttpClient okHttpClient(Cache cache, App application) {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);
        ClearableCookieJar cookieJar =
                new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(application.getApplicationContext()));
        return new OkHttpClient.Builder()
                .addInterceptor(authTokenInterceptor())
                .addInterceptor(loggingInterceptor) // 添加日志拦截器
                .addInterceptor(buildCacheInterceptor())
                .cache(cache) // 设置缓存文件
                .retryOnConnectionFailure(true) // 自动重连
                .connectTimeout(15, TimeUnit.SECONDS) 
                .readTimeout(20, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .cookieJar(cookieJar)
                .build();
    }

    @Provides
    @Singleton
    public Cache getCache(App application) {
        File cacheFile = new File(application.getCacheDir(), "networkCache");
        // 创建缓存对象,最大缓存50m
        return new Cache(cacheFile, 1024 * 1024 * 50);
    }

    private Interceptor authTokenInterceptor() {
        return chain -> {
            Request request = chain.request();
            TimeZone timeZone = TimeZone.getDefault();
            timeZone.setID("");
            String tz2 = timeZone.getDisplayName(true, TimeZone.SHORT);
            Request authRequest = request.newBuilder()
                    .header("timeZone", tz2)
                    .build();
            return chain.proceed(authRequest);
        };
    }

    private Interceptor buildCacheInterceptor() {
        return chain -> {
            Request request = chain.request();
            // 无网络连接时请求从缓存中读取
            if (!NetworkUtils.isConnected()) {
                request = request.newBuilder()
                        .cacheControl(CacheControl.FORCE_CACHE).build();
            }

            // 响应内容处理:在线时缓存5分钟;离线时缓存4周
            Response response = chain.proceed(request);
            if (NetworkUtils.isConnected()) {
                int maxAge = 300;
                response.newBuilder()
                        .header("Cache-Control", "public, max-age=" + maxAge)
                        .removeHeader("Pragma") // 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
                        .build();
            } else {
                // 无网络时,设置超时为4周
                int maxStale = 60 * 60 * 24 * 28;
                response.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                        .removeHeader("Pragma")
                        .build();
            }
            return response;
        };
    }

}

  • 根据需要创建其他实例提供者,比如OSS或者App
@Module
public class OSSModule {

    @Provides
    @Singleton
    OSS provideOss(App app, ServiceApi api) {
        final String[] endpoints = {"https://oss-cn-xxxxx.aliyuncs.com"};
        OSSCustomSignerCredentialProvider provider = new OSSCustomSignerCredentialProvider() {
            @Override
            public String signContent(String content) {
                String sign = null;
                return sign;
            }
        };
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
        conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒
        conf.setMaxConcurrentRequest(5); // 最大并发请求书,默认5个
        conf.setMaxErrorRetry(3); // 失败后最大重试次数,默认2次
        return new OSSClient(app, endpoints[0], provider, conf);
    }
}

@Module
public class ApplicationModule {
    private App mApplication;
    public ApplicationModule(App application) {
        mApplication = application;
    }

    @Provides
    @Singleton
    App provideApplication() {
        return mApplication;
    }

    @Provides
    @ApplicationContext
    @Singleton
    Context provideContext() {
        return mApplication;
    }
}
  • 组合的实例提供者
@Singleton
@Component(modules = {
        ApplicationModule.class,
        ApiModule.class,
        OSSModule.class
})
public interface ApplicationComponent {

    @ApplicationContext
    Context context();

    App application();

    ServiceApi serviceApi();

    OSS oss();

    OkHttpClient okHttpClicent();
}
  • 可选项,限定符
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationContext {
}
  • 可选项,使用范围
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {
}

@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerFragment {
}

@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerService {
}

创建注入器

每用一个,都要在这里加一个注入接口

@PerActivity
@Component(dependencies = {ApplicationComponent.class})
public interface ActivityComponent {
    void inject(MainActivity mainActivity);
}

@PerFragment
@Component(dependencies = {ApplicationComponent.class})
public interface FragmentComponent {
    void inject(HomeFragment homeFragment);
}

注入

可在基类中封装,也可以单独在每个界面注入

public class App extends Application{
	private ApplicationComponent mApplicationComponent;
	public ApplicationComponent getApplicationComponent() {
        if (mApplicationComponent == null) {
            mApplicationComponent = DaggerApplicationComponent.builder()
                    .applicationModule(new ApplicationModule(this))
                    .apiModule(new ApiModule())
                    .oSSModule(new OSSModule())
                    .build();
        }
        return mApplicationComponent;
    }
}

基类封装
    private ActivityComponent mActivityComponent;
    public ActivityComponent getActivityComponent() {
        if (mActivityComponent == null) {
            mActivityComponent = DaggerActivityComponent.builder()
                    .applicationComponent(App.getApp().getApplicationComponent())
                    .build();
        }
        return mActivityComponent;
    }
    
    @Override
    @CallSuper
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        inject(getActivityComponent());
    }
    
    protected void inject(ActivityComponent activityComponent) {
        // 子类具体实现dagger注入
    }
    
子类具体注入
	@Override
    protected void inject(ActivityComponent activityComponent) {
        activityComponent.inject(this);
    }

结合mvp

  • 基类
// 基类Activity
public abstract class BaseActivity<P extends BaseActivityPresenter>{
	@Inject
    protected P mPresenter;
    
	@Override
    @CallSuper
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    	if (mPresenter != null) {
            mPresenter.attachView(this);
        }
    }
    
	@Override
    @CallSuper
    protected void onDestroy() {
    	if (mPresenter != null) {
            mPresenter.detachView();
        }
    }
}


// 基类Presenter
public abstract class BaseActivityPresenter<T extends BaseActivity> {

    protected T mActivity;
    public void attachView(T activity) {
        mActivity = activity;
    }

    public void detachView() {
        if (mActivity != null) {
            mActivity = null;
        }
    }
}

  • 子类
public class MainActivity extends BaseActivity<MainPresenter> {

	mPresenter.xxxApi()
	private onXxxApiOk(){
	}

}

public class MainPresenter extends BaseActivityPresenter<MainActivity> {
    private ServiceApi mApi;

    @Inject
    public MainPresenter(ServiceApi api) {
        mApi = api;
    }

public void xxxApi(String xxxId) {
        mApi.xxxxxxx(xxxId)
                .xxx// rxjava 和 retrofit那一套
                .subscribe(new RxSubscriber<BaseHttpEntity<XXXEntity>>() {
                    @Override
                    protected void onSuccess(BaseHttpEntity<XXXEntity> response) {
                        mActivity.onXxxApiOk(response.getDetails());
                    }
                });
    }
 }   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/914872.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ISAAC SIM踩坑记录--ROS2相机影像发布

其实这个例子官方和大佬NVIDIA Omniverse和Isaac Sim笔记5&#xff1a;Isaac Sim的ROS接口与相机影像、位姿真值发布/保存都已经有详细介绍了&#xff0c;但是都是基于ROS的&#xff0c;现在最新的已经是ROS2&#xff0c;这里把不同的地方简单记录一下。 搭建一个简单的场景&a…

【thm】 Investigating Windows

0x00 rdp连接目标机器 apt install rdesktop 我们直接在kali里面安装这个&#xff0c;然后去连接 rdesktop 10.10.187.161 然后直接输入用户名密码就可。 0x01 hacker的任务 查看系统的信息&#xff0c;我们直接在命令行中输入systeminfo就可以直接查看。 然后我们输入 Get…

Python爬虫知识体系-----requests-----持续更新

数据科学、数据分析、人工智能必备知识汇总-----Python爬虫-----持续更新&#xff1a;https://blog.csdn.net/grd_java/article/details/140574349 文章目录 一、安装和基本使用二、get请求三、post请求四、代理 一、安装和基本使用 和解析库urllib几乎一摸一样&#xff0c;但是…

Netty篇(入门编程)

目录 一、Hello World 1. 目标 2. 服务器端 3. 客户端 4. 流程梳理 &#x1f4a1; 提示 5. 运行结果截图 二、Netty执行流程 1. 流程分析 2. 代码案例 2.1. 引入依赖 2.2. 服务端 服务端 服务端处理器 2.3. 客户端 客户端 客户端处理器 2.4. 代码截图 一、Hel…

酯化反应干催化剂树脂

油酸酯和丙三醇的合成反应&#xff1a; 油酸酯和丙三醇的合成反应是一个酯化反应&#xff1a;酯化反应的基本原理和条件&#xff0c; 在这个反应中&#xff0c;丙三醇&#xff08;甘油&#xff09;和油酸反应生成三酸甘油酯&#xff08;油酸酯&#xff09;和水。这种反应通常在…

Java 值传递详解

目录 形参&实参 值传递&引用传递 为什么 Java 只有值传递&#xff1f; 案例 1&#xff1a;传递基本类型参数 案例 2&#xff1a;传递引用类型参数 1 案例 3&#xff1a;传递引用类型参数 2 引用传递是怎么样的&#xff1f; 为什么 Java 不引入引用传递呢&#x…

Hadoop(环境搭建篇)

这里我用的是ubnatu22.4的系统&#xff0c;请大家严格按照这个系统来安装 一、网络设置 1、打开虚拟机的编辑&#xff0c;并选择虚拟网络编辑器 2、点击更改设置 3、更改IP 二、更改主机名 1、打开终端 2、输入以下命令 hostnamectl set-hostname master 3、然后关闭终端在…

深入浅出研究AI协同办公领域发展和趋势

协同办公&#xff0c;又称OA&#xff0c;是指企业内部或外部各类人员之间利用信息技术来进行协作工作的一种形式。这种协作工作既可以由直接员工进行&#xff0c;也可以来自外部的咨询机构、合作伙伴或联营企业。协同办公的优势在于可以对资源进行有效管理和配置&#xff0c;各…

C语言数据结构与算法--简单实现栈的出栈与入栈

&#xff08;一&#xff09;栈的基本概念 栈(Stack)是限定仅在表尾进行插入和删除操作的线性表&#xff0c;如铁路调度。如下 图&#xff1a; &#xff08;二&#xff09;栈的的表现形式 栈有两种表示形式&#xff1a;栈的表示和实现、栈的 链式表示。 1&#xff0e;栈的表示…

数据分析-46-时间序列显示之如何精准可视化多个时间序列数据

文章目录 1 可视化1.1 可视化的重要性1.2 数据加载探索2 可视化单个时间序列2.1 无连接线的散点图2.2 带连接线的散点图2.3 无点的线图2.4 填充区域的线图3 可视化多个时间序列3.1 无连接的散点图(差的设计)3.2 带连接的散点图(好的设计)3.3 直接标注的曲线(优的设计)4 参考附录…

ubuntu24.04播放语音视频

直接打开ubuntu自带的video播放.mp4文件&#xff0c;弹窗报错如下&#xff1a; 播放此影片需要插件 MPEG-4 AAC 编码器安装方式&#xff1a; sudo apt install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly sudo apt install ffmpeg验证AA…

python第七次作业

01.设计一个函数&#xff0c;可以传入一个或多个单词的字符串&#xff0c;并返回该字符串&#xff0c;但所有五个或更多字母的单词都前后颠倒 a input("输入:") print(a) #将一句话以空格为分界拆分为单个单词 b a.split(" ") ls_1 [] ls_2 []for i i…

精挑细选的五款GIS工具箱,你需要了解的优缺点

本文将为大家介绍五款功能各异的GIS工具箱&#xff0c;包括GISBox、QGIS、MapTiler、Saga GIS和Whitebox GAT。每款工具箱都有其独特的功能和应用场景&#xff0c;能够满足不同类型的GIS任务需求。无论是数据处理、空间分析、影像处理还是可视化需求&#xff0c;这些工具都能为…

Trimble X12三维激光扫描仪正在改变游戏规则【上海沪敖3D】

Trimble X12 三维激光扫描仪凭借清晰、纯净的点云数据和亚毫米级的精度正在改变游戏规则。今天的案例我们将与您分享&#xff0c;X12是如何帮助专业测量咨询公司OR3D完成的一个模拟受损平转桥运动的项目。 由于习惯于以微米为单位工作&#xff0c;专业测量机构OR3D是一家要求…

Appium配置2024.11.12

百度得知&#xff1a;谷歌从安卓9之后不再提供真机layout inspector查看&#xff0c;仅用于支持ide编写的app调试用 所以最新版android studio的android sdk目录下已经没有了布局查看工具... windows x64操作系统 小米k30 pro手机 安卓手机 Android 12 第一步&#xff1a…

ctfshow-web入门-反序列化(web271-web278)

目录 1、web271 2、web272 3、web273 4、web274 5、web275 6、web276 7、web277 8、web278 laravel 反序列化漏洞 1、web271 laravel 5.7&#xff08;CVE-2019-9081&#xff09; poc <?php namespace Illuminate\Foundation\Testing{use Illuminate\Auth\Generic…

005_ipc概述及信号量

【信号量】 在Linux系统中&#xff0c;信号量主要用于进程间的同步。Linux提供了两种类型的信号量&#xff1a;POSIX信号量和System V信号量&#xff0c;信号量&#xff08;Semaphore&#xff09;是一种同步机制&#xff0c;用于多线程或进程间的同步和互斥。信号量可以控制对…

SSA-CNN-LSTM-MATT多特征分类预测

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

有手就会:java 环境变量配置 - 包含windows、macos、linux和vscode的详细配置步骤

java 环境变量配置 本文旨在帮助用户完成Java环境变量的配置&#xff0c;涵盖Windows、Linux和macOS三大操作系统。对于每个系统&#xff0c;不仅提供了通过命令行设置环境变量的方法&#xff0c;还介绍了如何在VSCode中进行相应配置以启动Java项目&#xff0c;确保开发者能够…

Error response from daemon:

指出在尝试解析 auth.docker.io&#xff08;Docker Hub 的一个域名&#xff0c;用于身份验证和镜像拉取&#xff09;时&#xff0c;DNS 查询超时了。这通常意味着你的 Docker 客户端无法通过配置的 DNS 服务器&#xff08;在这个案例中是 &#xff09;来解析域名 解决方案&…