
Passing data between Activities using Intent extras often becomes repetitive and error-prone. I’ve noticed this especially when dealing with multiple data types like Parcelable, primitives, and bundles.
Managing putExtra, putInt, and putParcelable Repeatedly increases boilerplate and reduces readability.
Dart and Henson simplify this process by introducing a structured and type-safe way to handle Intent data passing.
Dart and Henson are Android dependency injection libraries designed to simplify Intent data passing.
They eliminate the need for repetitive key-based methods like putParcelable, putInt, putString, and putBundle.
By using annotation processing, they generate type-safe code, reducing boilerplate and improving maintainability.
The setup is straightforward and requires adding the following Gradle dependencies:
compile 'com.f2prateek.dart:dart:2.0.2'
annotationProcessor 'com.f2prateek.dart:dart-processor:2.0.2'
compile 'com.f2prateek.dart:henson:2.0.2'
annotationProcessor 'com.f2prateek.dart:henson-processor:2.0.2'Once configured, annotation-based injection replaces manual Intent handling.
Dart and Henson is an Android dependency Injection library to deal with Intent data passing without using cumbersome putParcelable, putInt, putString, putBundle key mechanism. It is a library created by a team of Groupon developers who presented article at DroidCon Italy 2017.
The library setup is very simple and easy to use by just adding following Gradle dependencies:
compile 'com.f2prateek.dart:dart:2.0.2'
annotationProcessor 'com.f2prateek.dart:dart-processor:2.0.2'
compile 'com.f2prateek.dart:henson:2.0.2'
annotationProcessor 'com.f2prateek.dart:henson-processor:2.0.2'That’s it you’re done to use Injection mechanism for Intent data sharing in your project.
To simplify implementation, consider two activities:
We build Android Studio plugins that cut manual effort, improve speed, and make your development process seamless.
Source Activity — MainActivity.java
Initiates navigation and passes data such as User (Parcelable), fromScreen (String), and isSuccess (boolean).
Target Activity — DetailsActivity.java
Receives and displays the passed data using injection.
Dart is an injection library that assigns Intent extras directly to fields in the target activity using annotations.
Instead of manually retrieving extras, Dart maps them automatically during activity initialization.
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.TextView;
import com.f2prateek.dart.Dart;
import com.f2prateek.dart.InjectExtra;
import butterknife.BindView;
import butterknife.ButterKnife;
@BindView(R.id.txt_mobile)
TextView txtMobile;
@BindView(R.id.txt_name)
TextView txtName;
@BindView(R.id.txt_email)
TextView txtEmail;
@BindView(R.id.btn_click_me)
Button btnClickMe;
@InjectExtra User user;
@Nullable
@InjectExtra String fromScreen;
@InjectExtra boolean isSuccess = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
ButterKnife.bind(this);
Dart.inject(this);
}STEP 1: Inject Dart in Target Activity
Dart.inject(this);STEP 2: Define fields using @InjectExtra
@InjectExtra User user;
@Nullable
@InjectExtra String fromScreen;
@InjectExtra boolean isSuccess = false;
Optional injection allows fields to remain unset if not provided.
Using @Nullable ensures the field does not cause runtime issues when missing.
Default values can be assigned directly during field declaration.
This ensures fallback behavior without additional checks during runtime.
Henson handles navigation between activities while passing Intent data in a structured way.
It generates builder-style methods based on injected fields, reducing manual Intent construction.
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.EditText;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.edt_mobile)
EditText edtMobile;
@BindView(R.id.edt_name)
EditText edtName;
@BindView(R.id.edt_email)
EditText edtEmail;
@BindView(R.id.btn_login)
Button btnLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick(R.id.btn_login)
public void onLoginClicked(){
Intent intent = Henson.with(MainActivity.this)
.gotoDetailsActivity()
.build();
}
}Yeah! Now Henson setup is done. Click Build — Rebuild Project
Chill! I know compiler throws Compilation error in .build() method as follows

The reason behind this because we haven’t passed any @InjectExtra annotation methods which are created in DetailsActivity.java
@InjectExtra User user;
@Nullable
@InjectExtra String fromScreen;
@InjectExtra boolean isSuccess = false;Cool. Let’s add all the parameters in the Intent as
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.EditText;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.edt_mobile)
EditText edtMobile;
@BindView(R.id.edt_name)
EditText edtName;
@BindView(R.id.edt_email)
EditText edtEmail;
@BindView(R.id.btn_login)
Button btnLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick(R.id.btn_login)
public void onLoginClicked(){
User user = new User();
user.setEmail(edtEmail.getText().toString());
user.setMobile(edtMobile.getText().toString());
user.setName(edtName.getText().toString());
Intent intent = Henson.with(MainActivity.this)
.gotoDetailsActivity()
.isSuccess(true)
.user(user)
.build();
startActivity(intent);
}
}Note: We haven’t passed fromScreen method since it is optional (By default it will be ‘null’).
What is .gotoDetailsActivity()?
I know everyone would be wondering from where this .gotoDetailsActivity() comes into the picture? Cool we have a answer for the same.
goto (Henson generated appending string to start an Activity) + DetailsActivity (Our own TargetActivity).
Yeah! We’re almost done. Let’s play with the intents in the TargetActivity (DetailsActivity.java)
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.f2prateek.dart.Dart;
import com.f2prateek.dart.InjectExtra;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class DetailsActivity extends AppCompatActivity {
@BindView(R.id.txt_mobile)
TextView txtMobile;
@BindView(R.id.txt_name)
TextView txtName;
@BindView(R.id.txt_email)
TextView txtEmail;
@BindView(R.id.btn_click_me)
Button btnClickMe;
@InjectExtra User user;
@Nullable
@InjectExtra String fromScreen;
@InjectExtra boolean isSuccess = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
ButterKnife.bind(this);
Dart.inject(this);
updateFields();
}
private void updateFields() {
txtMobile.setText(user.getMobile());
txtEmail.setText(user.getEmail());
txtName.setText(user.getName());
}
@OnClick(R.id.btn_click_me)
public void onClickMeClicked(){
if(isSuccess){
Toast.makeText(DetailsActivity.this, "Dart and Henson is really working!", Toast.LENGTH_SHORT).show();
}
}
}They reduce boilerplate code in Intent data passing by replacing manual key-based methods with annotation-based injection.
We build Android Studio plugins that cut manual effort, improve speed, and make your development process seamless.
Dart uses annotation processing to inject Intent extras directly into fields in the target activity.
Henson simplifies navigation between activities by generating type-safe builder methods for passing data.
Yes. They generate compile-time safe code, reducing runtime errors caused by missing or incorrect Intent data.
Yes. Fields annotated with @Nullable can be omitted without causing issues.