Dipendency Injection (DI), "object injection".
In short, allowing the dependencies to be replaced freely makes it easier to run tests (insert mock) and manages each object.
For example, if you want to store data in SharedPreferences, running it without DI will instantiate, store, and retrieve the data from SharedPreferences, all of which must be described like an activity.
If your app grows this way, it can be irreparable in the worst case.
So instead of instantiating SharedPreferences in the activity every time, inject it from another class.
A library developed by Square developers in 2012.
Dagger1 was used to instantiate a class and inject dependencies via Reflection. Later, in collaboration with Google's development team, Dagger 2 was introduced with a much faster version that doesn't use Reflections.
Dagger2 is a compile-time Android Dependency Injection framework that uses Java Specification Requirement (JSR) 330 and an annotation processor.
The basic annotations used in Dagger2 are as follows.
@Module: A class that builds an object that is finally provided as a dependency @Provides: Used in a method in the Module class that returns an object @Inject: Indicates that a dependency was requested (used in constructor / field / method) @Component: Bridge class for passing dependencies to the class requesting Module @Singleton: Indicates to create a single instance in a dependency
Sample
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="com.journaldev.dagger2.MainActivity">
<EditText
android:id="@+id/inUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:hint="Username" />
<EditText
android:id="@+id/inNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/inUsername"
android:layout_margin="8dp"
android:inputType="number"
android:hint="Number" />
<Button
android:id="@+id/btnSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SAVE"
android:layout_below="@+id/inNumber"
android:layout_toLeftOf="@+id/btnGet"
android:layout_toStartOf="@+id/btnGet"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp" />
<Button
android:id="@+id/btnGet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GET"
android:layout_below="@+id/inNumber"
android:layout_alignRight="@+id/inNumber"
android:layout_alignEnd="@+id/inNumber" />
</RelativeLayout>
Define dependencies in Module
SharedPrefModule.java
package com.journaldev.dagger2;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class SharedPrefModule {
private Context context;
public SharedPrefModule(Context context) {
this.context = context;
}
@Singleton
@Provides
public Context provideContext() {
return context;
}
@Singleton
@Provides
public SharedPreferences provideSharedPreferences(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
}
Definition of the object passed to the dependent class in Component
MyComponent.java
package com.journaldev.dagger2;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {SharedPrefModule.class})
public interface MyComponent {
void inject(MainActivity activity);
}
Write @inject where it is needed in the dependency (injected there)
MainActivity.java
package com.journaldev.dagger2;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import javax.inject.Inject;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
EditText inUsername, inNumber;
Button btnSave, btnGet;
private MyComponent myComponent;
@Inject
SharedPreferences sharedPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
myComponent = DaggerMyComponent.builder().sharedPrefModule(new SharedPrefModule(this)).build();
myComponent.inject(this);
}
private void initViews() {
btnGet = findViewById(R.id.btnGet);
btnSave = findViewById(R.id.btnSave);
inUsername = findViewById(R.id.inUsername);
inNumber = findViewById(R.id.inNumber);
btnSave.setOnClickListener(this);
btnGet.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnGet:
inUsername.setText(sharedPreferences.getString("username", "default"));
inNumber.setText(sharedPreferences.getString("number", "12345"));
break;
case R.id.btnSave:
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("username", inUsername.getText().toString().trim());
editor.putString("number", inNumber.getText().toString().trim());
editor.apply();
break;
}
}
}
It's rough, but the above is the explanation of Dagger2. I will update it in the future.
Recommended Posts