This is the one stop complete tutorial for implementing Dagger 2 with Retrofit and RecyclerView in our Android Application.
Dagger 2 is a dependency injection library that’s vital for clean code and architecture. For a basic overview of Dependency Injection and Dagger 2 refer this tutorial before proceeding ahead.
这是在我们的Android应用程序中使用Retrofit和RecyclerView实现Dagger 2的一站式完整教程。
Dagger 2是一个依赖注入库,对于干净的代码和体系结构至关重要。 有关Dependency Injection和Dagger 2的基本概述,请在继续之前参考本教程。
Dependency Injection is our friend in the worst and best times. It helps in refactoring the code quickly and helps in testing individual things since nothing is tightly coupled. It enhances the readability and maintainability.
Regardless, of the knowledge of Dependency Injection, at some point in your Object Oriented Programming, you have definitely used it. Following example will definitely remind you of it.
在最坏的情况下,依赖注入是我们的朋友。 由于没有紧密耦合,因此它有助于快速重构代码并有助于测试单个事物。 它提高了可读性和可维护性。
不管依赖注入的知识如何,在面向对象编程中的某些时候,您肯定已经使用了它。 以下示例肯定会让您想起它。
public class A {
public static void main(String[] args){
B b = new B();
C c = new C(b);
D d = new D(b, c);
E e = new E(d, b);
A a = new A(e, b);
}
}
Class A is a dependent. Class E and B are dependencies that are injected.
As you can see in the above code, instead of initializing classes in the constructors, we do them separately. Though we still have the boilerplate code above.
A类是受抚养人 。 E和B类是注入的依赖项 。
如您在上面的代码中看到的,我们不是在构造函数中初始化类,而是分别进行处理。 虽然我们上面还有样板代码。
@Module
, @Provides
, @Inject
, @Component
@Scope
. 我们需要用注释: @Module
, @Provides
, @Inject
, @Component
@Scope
。 @Qualifier
our @Named
annotations to differentiate. 对于两个有冲突的依赖项,例如Application具有不同的Context,而Activity具有不同的。 Dagger 2需要@Qualifier
我们的@Named
批注进行区分。 @Component
is set on an interface. It acts as a bridge and is used to provide the dependencies specified in the @Module
to the Java class. The dependency would be retrieved with @Inject
in our Java class. @Component
在接口上设置。 它充当桥梁,用于将@Module
指定的依赖项提供给Java类。 依赖关系将在我们的Java类中使用@Inject
检索。 Dagger 2 is best understood through an example. It’s been a while and we’ve tried to create an Android Application that explains the concepts in the best possible way using RecyclerView and Retrofit.
We’ll be using the StarWars API.
Let’s dive deep!
通过示例可以最好地理解Dagger 2。 已经有一段时间了,我们试图创建一个Android应用程序,该应用程序使用RecyclerView和Retrofit以最佳方式解释这些概念。
我们将使用StarWars API 。
让我们深入吧!
That’s big! We created a separate package di
for dependency injection components, modules, scopes and qualifiers. The activities go into the ui
package. The API method and POJO class are inside the retrofit
and pojo
packages respectively. The adapter
holds the RecyclerViewAdapter class.
This project consists of two activities – MainActivity and DetailActivity.
好大! 我们为依赖项注入组件,模块,作用域和限定符创建了一个单独的软件包di
。 活动进入ui
包。 API方法和POJO类分别位于retrofit
和pojo
包中。 adapter
包含RecyclerViewAdapter类。
该项目包含两个活动– MainActivity和DetailActivity。
Add the following library dependencies inside the app’s build.gradle
.
在应用程序的build.gradle
添加以下库依赖build.gradle
。
implementation 'com.android.support:design:27.1.0'
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.2'
implementation group: 'com.squareup.retrofit2', name: 'converter-gson', version: '2.3.0'
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.10.0'
implementation group: 'com.squareup.okhttp3', name: 'logging-interceptor', version: '3.9.0'
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.2'
implementation(group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.3.0') {
exclude module: 'okhttp'
}
implementation 'com.google.dagger:dagger-android:2.11'
implementation 'com.google.dagger:dagger-android-support:2.11'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.13'
Ensure that you’ve added the the Internet Permissions in your AndroidManifest file.
确保已在AndroidManifest文件中添加了Internet权限。
Scopes define where all those Components would be used. In this application, their are two : ActivityScope and ApplicationScope.
范围定义了所有这些组件的使用位置。 在此应用程序中,它们是两个:ActivityScope和ApplicationScope。
ActivityScope.java
ActivityScope.java
package com.journaldev.dagger2retrofitrecyclerview.di.scopes;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;
@Scope
@Retention(RetentionPolicy.CLASS)
public @interface ActivityScope {
}
ApplicationScope.java
ApplicationScope.java
package com.journaldev.dagger2retrofitrecyclerview.di.scopes;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;
@Scope
@Retention(RetentionPolicy.CLASS)
public @interface ApplicationScope {
}
@ActivityScope and @ApplicationScope would be used on the Components later on.
稍后将在组件上使用@ActivityScope和@ApplicationScope。
So, a Context can be either of the Activity or the Application. How would Dagger2 differentiate between them?
Using Qualifiers.
因此,上下文可以是活动或应用程序。 Dagger2如何区分它们?
使用限定词。
The ActivityContext.java and the ApplicationContext.java classes are defined below.
下面定义了ActivityContext.java和ApplicationContext.java类。
package com.journaldev.dagger2retrofitrecyclerview.di.qualifier;
import javax.inject.Qualifier;
@Qualifier
public @interface ActivityContext {
}
package com.journaldev.dagger2retrofitrecyclerview.di.qualifier;
import javax.inject.Qualifier;
@Qualifier
public @interface ApplicationContext {
}
Now in the Modules wherever we use Context, we must annotate it with @ApplicationContext or @ActivityContext depending on the use case.
现在,无论在哪里使用Context的模块中,都必须根据用例使用@ApplicationContext或@ActivityContext对其进行注释。
Modules are what would provide the dependencies to the dependents via Components.
Let’s plan out our Dependency Graph first.
模块是通过组件向依赖项提供依赖项的模块。
让我们先计划一下依赖图。
So the APIInterface
isn’t dependent on anything.
The ApplicationComponent would hold the Retrofit and AppContext Modules.
The MainActivity would hold the Adapter and Activity Context Modules along with the ApplicationComponent’s dependencies.
The DetailActivityComponent doesn’t include any of its own modules. It just uses the ones present in the ApplicationComponent.
因此, APIInterface
不依赖任何东西。
ApplicationComponent将容纳Retrofit和AppContext模块。
MainActivity将保存适配器和活动上下文模块以及ApplicationComponent的依赖项。
DetailActivityComponent不包含任何其自身的模块。 它只使用ApplicationComponent中存在的那些。
package com.journaldev.dagger2retrofitrecyclerview.di.module;
import android.content.Context;
import com.journaldev.dagger2retrofitrecyclerview.di.qualifier.ApplicationContext;
import com.journaldev.dagger2retrofitrecyclerview.di.scopes.ApplicationScope;
import dagger.Module;
import dagger.Provides;
@Module
public class ContextModule {
private Context context;
public ContextModule(Context context) {
this.context = context;
}
@Provides
@ApplicationScope
@ApplicationContext
public Context provideContext() {
return context;
}
}
We’ve specified the Application Level scope and qualifier for the context.
我们为上下文指定了应用程序级别范围和限定符。
package com.journaldev.dagger2retrofitrecyclerview.di.module;
import com.journaldev.dagger2retrofitrecyclerview.di.scopes.ApplicationScope;
import com.journaldev.dagger2retrofitrecyclerview.retrofit.APIInterface;
import dagger.Module;
import dagger.Provides;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@Module
public class RetrofitModule {
@Provides
@ApplicationScope
APIInterface getApiInterface(Retrofit retroFit) {
return retroFit.create(APIInterface.class);
}
@Provides
@ApplicationScope
Retrofit getRetrofit(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.baseUrl("https://swapi.co/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
}
@Provides
@ApplicationScope
OkHttpClient getOkHttpCleint(HttpLoggingInterceptor httpLoggingInterceptor) {
return new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.build();
}
@Provides
@ApplicationScope
HttpLoggingInterceptor getHttpLoggingInterceptor() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return httpLoggingInterceptor;
}
}
@Provides denotes that a dependency would be provided from that method to it’s dependents.
For Retrofit we use an ApplicationScope.
@Provides表示将从该方法为其依赖项提供依赖项。
对于翻新,我们使用ApplicationScope。
package com.journaldev.dagger2retrofitrecyclerview.di.module;
import android.content.Context;
import com.journaldev.dagger2retrofitrecyclerview.di.qualifier.ActivityContext;
import com.journaldev.dagger2retrofitrecyclerview.di.scopes.ActivityScope;
import com.journaldev.dagger2retrofitrecyclerview.ui.MainActivity;
import dagger.Module;
import dagger.Provides;
@Module
public class MainActivityContextModule {
private MainActivity mainActivity;
public Context context;
public MainActivityContextModule(MainActivity mainActivity) {
this.mainActivity = mainActivity;
context = mainActivity;
}
@Provides
@ActivityScope
public MainActivity providesMainActivity() {
return mainActivity;
}
@Provides
@ActivityScope
@ActivityContext
public Context provideContext() {
return context;
}
}
The above module is used to provide the Activity Context and the Activity’s instance.
上面的模块用于提供活动上下文和活动实例。
The code for the AdapterModule is given below.
AdapterModule的代码如下。
package com.journaldev.dagger2retrofitrecyclerview.di.module;
import com.journaldev.dagger2retrofitrecyclerview.adapter.RecyclerViewAdapter;
import com.journaldev.dagger2retrofitrecyclerview.di.scopes.ActivityScope;
import com.journaldev.dagger2retrofitrecyclerview.ui.MainActivity;
import dagger.Module;
import dagger.Provides;
@Module(includes = {MainActivityContextModule.class})
public class AdapterModule {
@Provides
@ActivityScope
public RecyclerViewAdapter getStarWarsPeopleLIst(RecyclerViewAdapter.ClickListener clickListener) {
return new RecyclerViewAdapter(clickListener);
}
@Provides
@ActivityScope
public RecyclerViewAdapter.ClickListener getClickListener(MainActivity mainActivity) {
return mainActivity;
}
}
It’s used to create the RecyclerViewAdapter from the POJO data.
Also, the ClickListener is an interface defined in the RecyclerViewAdapter class to trigger the click listener callback methods from the Activity itself.
It injects the MainActivity dependency since we’ve included the MainActivityContextModule
in the definition.
它用于根据POJO数据创建RecyclerViewAdapter。
此外,ClickListener是RecyclerViewAdapter类中定义的接口,用于从Activity本身触发click listener回调方法。
由于我们已在定义中包含MainActivityContextModule
,因此它将注入MainActivity依赖项。
Let’s look at the APIInterface and the POJO classes.
让我们看一下APIInterface和POJO类。
The code for the APIInterface.java class is given below.
下面给出了APIInterface.java类的代码。
package com.journaldev.dagger2retrofitrecyclerview.retrofit;
import com.journaldev.dagger2retrofitrecyclerview.pojo.Film;
import com.journaldev.dagger2retrofitrecyclerview.pojo.StarWars;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
import retrofit2.http.Url;
public interface APIInterface {
@GET("people/?")
Call getPeople(@Query("format") String format);
@GET
Call getFilmData(@Url String url, @Query("format") String format);
}
@Url
is used to do a dynamic URL call in Retrofit. The URL would be specified at runtime.
@Url
用于在Retrofit中进行动态URL调用。 该URL将在运行时指定。
The POJO classes are created from the .jsonschema2pojo.
POJO类是从.jsonschema2pojo创建的。
StarWars.java
StarWars.java
package com.journaldev.dagger2retrofitrecyclerview.pojo;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class StarWars {
@SerializedName("results")
public List results = null;
public class People {
@SerializedName("name")
public String name;
@SerializedName("height")
public String height;
@SerializedName("mass")
public String mass;
@SerializedName("birth_year")
public String birthYear;
@SerializedName("gender")
public String gender;
@SerializedName("homeworld")
public String homeworld;
@SerializedName("films")
public List films = null;
}
}
Film.java
Film.java
package com.journaldev.dagger2retrofitrecyclerview.pojo;
import com.google.gson.annotations.SerializedName;
public class Film {
@SerializedName("title")
public String title;
@SerializedName("director")
public String director;
}
We’re only parsing the values which we’ll be using in our application.
我们仅解析将在应用程序中使用的值。
The star wars api looks like this:
星球大战api如下所示:
In the Components, we’ll include the Modules.
We’ll need to expose the fields that’ll be used in our Activity/Application.
在组件中,我们将包括模块。
我们需要公开将在“活动/应用程序”中使用的字段。
ApplicationComponent.java
ApplicationComponent.java
package com.journaldev.dagger2retrofitrecyclerview.di.component;
import android.content.Context;
import com.journaldev.dagger2retrofitrecyclerview.MyApplication;
import com.journaldev.dagger2retrofitrecyclerview.di.module.ContextModule;
import com.journaldev.dagger2retrofitrecyclerview.di.module.RetrofitModule;
import com.journaldev.dagger2retrofitrecyclerview.di.qualifier.ApplicationContext;
import com.journaldev.dagger2retrofitrecyclerview.di.scopes.ApplicationScope;
import com.journaldev.dagger2retrofitrecyclerview.retrofit.APIInterface;
import dagger.Component;
@ApplicationScope
@Component(modules = {ContextModule.class, RetrofitModule.class})
public interface ApplicationComponent {
public APIInterface getApiInterface();
@ApplicationContext
public Context getContext();
public void injectApplication(MyApplication myApplication);
}
Dagger2 would autogenerate a class named Dagger%ComponentName%. Eg. DaggerApplicationComponent.
injectApplication
is used to allow @Inject fields in our Activity/Application.
Dagger2将自动生成一个名为Dagger%ComponentName%的类。 例如。 DaggerApplicationComponent。
injectApplication
用于允许在我们的活动/应用程序中使用@Inject字段。
MainActivityComponent.java
MainActivityComponent.java
package com.journaldev.dagger2retrofitrecyclerview.di.component;
import android.content.Context;
import com.journaldev.dagger2retrofitrecyclerview.di.module.AdapterModule;
import com.journaldev.dagger2retrofitrecyclerview.di.qualifier.ActivityContext;
import com.journaldev.dagger2retrofitrecyclerview.di.scopes.ActivityScope;
import com.journaldev.dagger2retrofitrecyclerview.ui.MainActivity;
import dagger.Component;
@ActivityScope
@Component(modules = AdapterModule.class, dependencies = ApplicationComponent.class)
public interface MainActivityComponent {
@ActivityContext
Context getContext();
void injectMainActivity(MainActivity mainActivity);
}
The above component would have access to the ApplicationComponent dependencies too.
上面的组件也可以访问ApplicationComponent依赖项。
DetailActivityComponent.java
DetailActivityComponent.java
package com.journaldev.dagger2retrofitrecyclerview.di.component;
import com.journaldev.dagger2retrofitrecyclerview.di.scopes.ActivityScope;
import com.journaldev.dagger2retrofitrecyclerview.ui.DetailActivity;
import dagger.Component;
@Component(dependencies = ApplicationComponent.class)
@ActivityScope
public interface DetailActivityComponent {
void inject(DetailActivity detailActivity);
}
Now is the time to use the di in our Activity’s and Application.
Let’s look at the layout codes first.
现在是时候在我们的活动和应用程序中使用di了。
我们先来看一下布局代码。
activity_main.xml
activity_main.xml
activity_detail.xml
activity_detail.xml
recycler_view_list_row.xml
recycler_view_list_row.xml
Before we use dependency injection in our classes, REBUILD THE PROJECT. This is done to generate the Dagger Component classes.
在我们的类中使用依赖注入之前,请重新构建PROJECT 。 这样做是为了生成Dagger Component类。
The code for the MyApplication.java class is given below.
下面给出了MyApplication.java类的代码。
package com.journaldev.dagger2retrofitrecyclerview;
import android.app.Activity;
import android.app.Application;
import com.journaldev.dagger2retrofitrecyclerview.di.component.ApplicationComponent;
import com.journaldev.dagger2retrofitrecyclerview.di.component.DaggerApplicationComponent;
import com.journaldev.dagger2retrofitrecyclerview.di.module.ContextModule;
public class MyApplication extends Application {
ApplicationComponent applicationComponent;
@Override
public void onCreate() {
super.onCreate();
applicationComponent = DaggerApplicationComponent.builder().contextModule(new ContextModule(this)).build();
applicationComponent.injectApplication(this);
}
public static MyApplication get(Activity activity){
return (MyApplication) activity.getApplication();
}
public ApplicationComponent getApplicationComponent() {
return applicationComponent;
}
}
DaggerApplicationComponent.builder().contextModule(new ContextModule(this)).build();
is used to build the modules present in the component.
getApplicationComponent would be used to return the ApplicationComponent in our Activities.
DaggerApplicationComponent.builder().contextModule(new ContextModule(this)).build();
用于构建组件中存在的模块。
getApplicationComponent将用于在我们的Activity中返回ApplicationComponent。
Don’t forget to add the above application in our AndroidManifest.xml file.
不要忘记在我们的AndroidManifest.xml文件中添加上述应用程序。
The code for the MainActivity.java class is given below.
下面给出MainActivity.java类的代码。
package com.journaldev.dagger2retrofitrecyclerview.ui;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;
import com.journaldev.dagger2retrofitrecyclerview.MyApplication;
import com.journaldev.dagger2retrofitrecyclerview.R;
import com.journaldev.dagger2retrofitrecyclerview.adapter.RecyclerViewAdapter;
import com.journaldev.dagger2retrofitrecyclerview.di.component.ApplicationComponent;
import com.journaldev.dagger2retrofitrecyclerview.di.component.DaggerMainActivityComponent;
import com.journaldev.dagger2retrofitrecyclerview.di.component.MainActivityComponent;
import com.journaldev.dagger2retrofitrecyclerview.di.module.MainActivityContextModule;
import com.journaldev.dagger2retrofitrecyclerview.di.qualifier.ActivityContext;
import com.journaldev.dagger2retrofitrecyclerview.di.qualifier.ApplicationContext;
import com.journaldev.dagger2retrofitrecyclerview.pojo.StarWars;
import com.journaldev.dagger2retrofitrecyclerview.retrofit.APIInterface;
import java.util.List;
import javax.inject.Inject;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.ClickListener {
private RecyclerView recyclerView;
MainActivityComponent mainActivityComponent;
@Inject
public RecyclerViewAdapter recyclerViewAdapter;
@Inject
public APIInterface apiInterface;
@Inject
@ApplicationContext
public Context mContext;
@Inject
@ActivityContext
public Context activityContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
ApplicationComponent applicationComponent = MyApplication.get(this).getApplicationComponent();
mainActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityContextModule(new MainActivityContextModule(this))
.applicationComponent(applicationComponent)
.build();
mainActivityComponent.injectMainActivity(this);
recyclerView.setAdapter(recyclerViewAdapter);
apiInterface.getPeople("json").enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
populateRecyclerView(response.body().results);
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
private void populateRecyclerView(List response) {
recyclerViewAdapter.setData(response);
}
@Override
public void launchIntent(String url) {
Toast.makeText(mContext, "RecyclerView Row selected", Toast.LENGTH_SHORT).show();
startActivity(new Intent(activityContext, DetailActivity.class).putExtra("url", url));
}
}
Once this happens: mainActivityComponent.injectMainActivity(this);
, The fields present with the @Inject
would be automatically injected.
The rest is doing a Retrofit call and setting the data in the RecyclerViewAdapter.
The class implements the RecyclerViewAdapter.ClickListener
interface callback which triggers a launchIntent method whenever the RecyclerView row gets clicked.
Note that the Context injected needs to be specified with the relevant qualifier we had earlier defined.
一旦发生这种情况: mainActivityComponent.injectMainActivity(this);
,@ @Inject
出现的字段将被自动注入。
其余的工作是在进行Retrofit调用并在RecyclerViewAdapter中设置数据。
该类实现RecyclerViewAdapter.ClickListener
接口回调,每当单击RecyclerView行时,该回调都会触发launchIntent方法。
请注意,需要使用我们之前定义的相关限定符来指定注入的上下文。
The code for the RecyclerViewAdapter is given below.
下面给出了RecyclerViewAdapter的代码。
package com.journaldev.dagger2retrofitrecyclerview.adapter;
import android.support.constraint.ConstraintLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.journaldev.dagger2retrofitrecyclerview.R;
import com.journaldev.dagger2retrofitrecyclerview.pojo.StarWars;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
public class RecyclerViewAdapter extends RecyclerView.Adapter {
private List data;
private RecyclerViewAdapter.ClickListener clickListener;
@Inject
public RecyclerViewAdapter(ClickListener clickListener) {
this.clickListener = clickListener;
data = new ArrayList<>();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_list_row, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.txtName.setText(data.get(position).name);
holder.txtBirthYear.setText(data.get(position).birthYear);
}
@Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView txtName;
private TextView txtBirthYear;
private ConstraintLayout constraintLayoutContainer;
ViewHolder(View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.txtName);
txtBirthYear = itemView.findViewById(R.id.txtBirthYear);
constraintLayoutContainer = itemView.findViewById(R.id.constraintLayout);
constraintLayoutContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickListener.launchIntent(data.get(getAdapterPosition()).films.get(0));
}
});
}
}
public interface ClickListener {
void launchIntent(String filmName);
}
public void setData(List data) {
this.data.addAll(data);
notifyDataSetChanged();
}
}
The code for the DetailActivity.java class is given below:
下面给出了DetailActivity.java类的代码:
package com.journaldev.dagger2retrofitrecyclerview.ui;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.journaldev.dagger2retrofitrecyclerview.MyApplication;
import com.journaldev.dagger2retrofitrecyclerview.R;
import com.journaldev.dagger2retrofitrecyclerview.di.component.ApplicationComponent;
import com.journaldev.dagger2retrofitrecyclerview.di.component.DaggerDetailActivityComponent;
import com.journaldev.dagger2retrofitrecyclerview.di.component.DetailActivityComponent;
import com.journaldev.dagger2retrofitrecyclerview.di.qualifier.ApplicationContext;
import com.journaldev.dagger2retrofitrecyclerview.pojo.Film;
import com.journaldev.dagger2retrofitrecyclerview.retrofit.APIInterface;
import javax.inject.Inject;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class DetailActivity extends AppCompatActivity {
DetailActivityComponent detailActivityComponent;
@Inject
public APIInterface apiInterface;
@Inject
@ApplicationContext
public Context mContext;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
textView = findViewById(R.id.textView);
String url = getIntent().getStringExtra("url");
ApplicationComponent applicationComponent = MyApplication.get(this).getApplicationComponent();
detailActivityComponent = DaggerDetailActivityComponent.builder()
.applicationComponent(applicationComponent)
.build();
detailActivityComponent.inject(this);
apiInterface.getFilmData(url, "json").enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
Film films = response.body();
String text = "Film name:\n" + films.title + "\nDirector:\n" + films.director;
textView.setText(text);
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
}
Again the inject
method is used to inject all the dependency fields.
The retrofit makes a request to the dynamic URL specified and displays the response in a TextView.
再次使用inject
方法来注入所有依赖项字段。
改型向指定的动态URL发出请求,并在TextView中显示响应。
The output of the above application in action is given below.
下面给出了上面应用程序的输出。
This brings an end to this tutorial. You can download the full source code from the link below.
本教程到此结束。 您可以从下面的链接下载完整的源代码。
翻译自: https://www.journaldev.com/20405/android-dagger-2-retrofit-recyclerview