اندروید Dagger 2 + Retrofit + RecyclerView
در این مقاله ، پیاده سازی کامل Dagger 2 به همراه Retrofit و Recyclerview را خواهید آموخت.
Dagger2 یک کتابخانه ی تزریق وابستگی است که برای کدنویسی تمیز و معماری ضروری است.
تزریق وابستگی به چه معناست؟
در تزریق وابستگی به عبارت ساده ، به جای اینکه خودتان با استفاده از کلمه کلیدی new نمونه ای ایجاد کنید ، این موارد از بیرون برای شما فراهم می شود.
تزریق وابستگی دوست ما در بدترین و بهترین زمان ها ست. به ما کمک می کند تا کد به سرعت refactor شود و به تست های واحد نیز کمک می کند زیرا tightly coupled اتفاق نخواهد افتاد (tightly coupled وقتی گروهی از کلاسها بسیار به یکدیگر وابسته باشند را گویند). بنابراین باعث افزایش خوانایی و قابلیت نگهداری خواهد شد.
صرف نظر از دانش تزریق وابستگی ، در قسمتی از برنامه نویسی شی گرا ، قطعاً از آن استفاده کرده اید. مثال زیر قطعاً آن را به شما یادآوری می کند.
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);
}
کلاس A وابسته است. کلاس E و B وابستگی هایی هستند که تزریق می شوند.
همانطور که در کد بالا مشاهده می کنید ، ما به جای شروع کلاس در سازنده ها ، آنها را جداگانه انجام می دهیم. اگرچه ما هنوز boilerplate code را در بالا داریم.
نکات مهمی که باید در مورد Dagger 2به آن توجه کنید
- نمودار وابستگی شی را در زمان کامپایل بررسی و پیاده سازی می کند.
- ما نیاز داریم از annotation های زیر استفاده کنیم:
@Module, @Provides, @Inject, @Component @Scope
- برای دو وابستگی که با هم در تضاد هستند ، مانند Application یک Context متفاوت و یک Activity متفاوت است. Dagger2 برای تفکیک به annotation Named@ و @Qualifier نیاز دارد.
- @Component روی یک interface تنظیم شده است. که به عنوان یک پل عمل می کند و برای ارائه وابستگی های مشخص شده در@Module به کلاس جاوا استفاده می شود. وابستگی در کلاس جاوا با @Inject بازیابی می شود.
- Dagger 2 فیلدهای private را نمی تواند تزریق کند.
ساختار پروژه
ما یک package جداگانه برای اجزای تزریق وابستگی ، components ها ، modules ها و scopes ها ایجاد کردیم. activity ها در بسته ui قرار می گیرند. متدهای API و کلاس POJO به ترتیب درون پکیج های retrofit سازی و POJO هستند. Adapter کلاس RecyclerViewAdapter را در خود جای داده است.
این پروژه شامل دو Activity ، MainActivity و DetailActivity است.
وابستگی های کتابخانه زیر را در 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'
اطمینان حاصل کنید که مجوزهای اینترنت را در فایل AndroidManifest خود اضافه کرده اید.
پکیج های تزریق وابستگی
Scopes
Scopesها مشخص می کنند که همه آن Componentها در کجا استفاده می شوند. در این برنامه ، دو مورد وجود دارد ActivityScope و ApplicationScope
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
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 و @ApplicationScope در Components استفاده می شود.
qualifiers
بنابراین ، یک Context می تواند یا از Activity باشد یا از Application باشد. چگونه Dagger2 بین آنها تفاوت ایجاد می کند؟
با استفاده از qualifiers
کلاس ActivityContext.java و ApplicationContext.java در زیر تعریف شده اند.
package com.journaldev.dagger2retrofitrecyclerview.di.qualifier;
import javax.inject.Qualifier;
@Qualifier
public @interface ApplicationContext {
}
اکنون در modules هر کجا که از Context استفاده می کنیم ، بسته به مورد استفاده ، باید آن را باApplicationContext یاActivityContext، annotate کنیم.
Modules
Moduleها مواردی هستند که وابستگی ها را از طریق component ها به موارد وابسته فراهم می کنند.
ابتدا نمودار وابستگی خود را مطرح کنیم.
بنابراین APIInterface به هیچ چیز وابسته نیست.
ApplicationComponent ماژول های Retrofit و AppContext را نگه می دارد.
MainActivity ماژول های Adapter و Activity Context را به همراه وابستگی های ApplicationComponent نگه می دارد.
DetailActivityComponent هیچ یک از ماژول های خاص خود را ندارد. فقط از موارد موجود در ApplicationComponent استفاده می کند.
ContextModule
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;
}
}
RetrofitModule
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 نشان می دهد که وابستگی خواستار ارائه شدن از آن متد وابسته است. برای Retrofit از ApplicationScope استفاده می کنیم.
MainActivityContextModule
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;
}
}
Module فوق برای ارائه Activity Context و نمونه سازی Activity استفاده می شود.
AdapterModule
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;
}
}
برای ایجاد RecyclerViewAdapter از داده های POJO استفاده می شود.
همچنین ، ClickListener یک interface است که در کلاس RecyclerViewAdapter تعریف شده است تا متدهای پاسخ به callback click listener را از خود Activity ایجاد کند.
این وابستگی MainActivity را تزریق می کند زیرا ما MainActivityContextModule را در تعریف گنجانده ایم.
بیایید به کلاسهای APIInterface و POJO نگاهی بیندازیم.
کد کلاس 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<StarWars> getPeople(@Query("format") String format);
@GET
Call<Film> getFilmData(@Url String url, @Query("format") String format);
}
@Url برای انجام یک تماس URL پویا در Retrofit استفاده می شود. URL در زمان اجرا مشخص می شود.
StarWars.java
package com.journaldev.dagger2retrofitrecyclerview.pojo;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class StarWars {
@SerializedName("results")
public List<People> 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<String> films = null;
}
}
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;
}
ما فقط مقادیری را pars می کنیم که در برنامه خود استفاده خواهیم کرد.
stratwar یک api مشابه شکل زیر دارد.
Components
در Component ها ، Moduleها را قرار خواهیم داد .
ما باید فیلدهایی را که در Activity / Application استفاده خواهد شد ، نشان دهیم.
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 یک کلاس به نام ٪ ComponentName٪ Dagger را ایجاد می کند. به عنوان مثال. DaggerApplicationComponent.
injectApplication برای اجازه دادن به قسمتهایInject در Activity / Application ما استفاده می شود.
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);
}
Component فوق به وابستگی ApplicationComponent نیز دسترسی خواهد داشت.
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);
}
اکنون زمان استفاده از di در Activity ها و Application ما است.
ابتدا کدهای layout را بررسی می کنیم.
Layout
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
activity_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.DetailActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Loading..."
android:textColor="@android:color/black"
android:textSize="28sp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
recycler_view_list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txtBirthYear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/txtName" />
</android.support.constraint.ConstraintLayout>
قبل از اینکه از تزریق وابستگی در کلاس های خود استفاده کنیم ، پروژه را Rebuild می کنیم. این کار برای تولید کلاس های Dagger Component انجام می شود.
کد کلاس 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();
برای ساخت ماژول های موجود در جز component استفاده می شود.
getApplicationComponent برای بازگرداندن ApplicationComponent در فعالیتهای ما استفاده می شود.
فراموش نکنید که برنامه فوق را در فایل AndroidManifest.xml اضافه کنید.
UI package
کد کلاس 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<StarWars>() {
@Override
public void onResponse(Call<StarWars> call, Response<StarWars> response) {
populateRecyclerView(response.body().results);
}
@Override
public void onFailure(Call<StarWars> call, Throwable t) {
}
});
}
private void populateRecyclerView(List<StarWars.People> 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));
}
}
وقتی کد زیر اتفاق افتاد:
mainActivityComponent.injectMainActivity
فیلدهای های موجود با @Inject به طور خودکار تزریق می شوند.
بقیه در حال انجام call کردن Retrofit و تنظیم داده ها در RecyclerViewAdapter هستند.
این کلاسimplementمی کند RecyclerViewAdapter.ClickListener را و هر زمان که روی ردیف RecyclerView کلیک شود ، روش launchIntent را آغاز می کند.
توجه داشته باشید که Context تزریق شده باید با qualifier مربوطه که قبلاً تعریف کردیم مشخص شود.
کد 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<RecyclerViewAdapter.ViewHolder> {
private List<StarWars.People> 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<StarWars.People> data) {
this.data.addAll(data);
notifyDataSetChanged();
}
}
کد کلاس 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<Film>() {
@Override
public void onResponse(Call<Film> call, Response<Film> response) {
Film films = response.body();
String text = "Film name:\n" + films.title + "\nDirector:\n" + films.director;
textView.setText(text);
}
@Override
public void onFailure(Call<Film> call, Throwable t) {
}
});
}
}
دوباره متد تزریق برای تزریق تمام فیلدهای وابستگی استفاده می شود.
Retrofit درخواستی را به URL dynamic مشخص شده ارائه می دهد و پاسخ را در یک TextView نمایش می دهد.
دیدگاهتان را بنویسید