I have espresso test which verifies that text is displayed:
public class InformationActivityTests {
@Rule
public ActivityTestRule<InformationActivity_> mInformationActivityTestRule =
new ActivityTestRule<InformationActivity_>(InformationActivity_.class) {
@Override
protected Intent getActivityIntent() {
Intent i = new Intent(getTargetContext(), InformationActivity_.class);
i.putExtra("INFORMATION", "Espresso");
return i;
}
};
@Test
public void textIsDisplayed() {
onView(withText("Espresso")).check(matches(isDisplayed()));
}
}
This test passes when Activity has following code:
@EActivity
public class InformationActivity extends AppCompatActivity {
@ViewById(R.id.information_view)
TextView informationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_information);
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}
but fails when I "move" setContentView to @EActivity annotation:
@EActivity(R.layout.activity_information)
public class InformationActivity extends AppCompatActivity {
@ViewById(R.id.information_view)
TextView informationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}
Error is:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.edu/com.edu.InformationActivity_}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Am I doing something wrong or is it an issue with espresso / android-annotations?
I've checked code generated by android-annotations when using @EActivity(R.layout.activity_information) and this is how onCreate looks like in generated class (InformationActivity_):
public void onCreate(Bundle savedInstanceState) {
OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
init_(savedInstanceState);
super.onCreate(savedInstanceState);
OnViewChangedNotifier.replaceNotifier(previousNotifier);
setContentView(R.layout.activity_information);
}
the problem is that it first calls super.onCreate (so onCreate from InformationActivity) where I handle intent and TextView and then it calls setContentView and this can't work like that.
The solution for this is what Be_Negative suggested, so using @AfterViews annotation. It also simplifies code a bit (I could remove onCreate method):
@EActivity(R.layout.activity_information)
public class InformationActivity extends AppCompatActivity {
@ViewById(R.id.information_view)
TextView informationView;
@AfterViews
void handleIntent() {
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}