使用espresso时setContentView可以换成android-annotations吗?

Can setContentView be replaced by android-annotations when espresso is used?

我有 espresso 测试来验证是否显示了文本:

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()));
    }
}

当 Activity 具有以下代码时,此测试 通过

@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);
    }
}

但是当我 "move" 将 ContentView 设置为 @EActivity 注释时 失败 :

@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);
    }
}

错误是:

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

我是做错了什么还是浓缩咖啡/android-注释有问题?

你的问题是你从来没有初始化信息视图

public class InformationActivity extends AppCompatActivity {
@ViewById(R.id.information_view)
TextView informationView; //<-- Null

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    String information = intent.getStringExtra("INFORMATION");
    informationView.setText(information); //<--STILL NULL
}
}

因此您首先必须初始化该视图。

我检查了使用@EActivity(R.layout.activity_information) 时由 android 注释生成的代码,这就是生成的 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);
}

问题是它首先调用 super.onCreate(因此从 InformationActivity 创建),我在其中处理 intent 和 TextView,然后它调用 setContentView 这不能那样工作。

解决方案是 Be_Negative 建议的,因此使用 @AfterViews 注释。它还稍微简化了代码(我可以删除 onCreate 方法):

@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);
    }    
}