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

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

Your problem is that you are never initializing informationview
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
}
}
So you first will have to initialize that view.

Related

Butterknife + Espresso NoMatchingViewException

Can Butterknife work with Espresso? I have a test sample, there are 2 activities. In the first activity I print the text, than click the button and send text to another activity. After that I created MainActivityTest and everything worked well. But when I started to use Butterknife I caught the error NoMatchingViewException.
My first activity:
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
#BindView(R.id.first_text)
EditText mEditText;
#OnClick(R.id.button_one)
public void click(){
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("TEXT",mEditText.getText().toString());
startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
The second activity:
public class SecondActivity extends AppCompatActivity {
public static final String TAG = SecondActivity.class.getSimpleName();
#BindView(R.id.second_text)
TextView mTextView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
#Override
protected void onResume() {
super.onResume();
if(getIntent().getStringExtra("TEXT")!=null) {
mTextView.setText(getIntent().getStringExtra("TEXT"));
}
}
}
My MainActivityTest:
public class MainActivityTest {
#Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
MainActivity.class);
#Before
public void setUp() throws Exception {
}
#Test
public void onCreate() throws Exception {
onView(withId(R.id.first_text)).perform(typeText("Test"));
onView(withId(R.id.button_one)).perform(click());
onView(withId(R.id.second_text)).check(matches(withText("Test")));
}
}

Illegal start of expression and expected ';' errors in Android code

I just wanted to create an application that works like an HTML page or something. Just after clicked button, new site is opening.
I don't know why there are 5 errors: 2 Errors:(15, 11 and 15,18) error: illegal start of expression, and 2 Errors:(15, 31 and 15,41) error: ';' expected.
Here's the code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
{
public void nextStep(View view) {
Intent i = new Intent(this, SecondaryActivity.class);
startActivity(i);
}
}
}
Coud you help me? :/
your message is not formated
It shows like if
{ public void nextStep(View view) {Intent i = new Intent(this, SecondaryActivity.class);startActivity(i); }
is inside you onCreate function,
if true, you can't write a function inside another function
There was problem with bracket.Try this
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void nextStep(View view) {
Intent i = new Intent(this, SecondaryActivity.class);
startActivity(i);
}
}

Put common listeners inside MainActivity class

Im interested if i can to set some common listeners inside main activity class? For my project i use FirebaseAuth, so i would like to init it in MainActivity onCreate(), setup needed listeners in onStart() and onStop(), and then inherit that class in every other activity class.
Some code to please you :]
MainActivity class [parent]:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
protected FirebaseAuthentication firebaseAuthentication;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
firebaseAuthentication = new FirebaseAuthentication(FirebaseAuth.getInstance(), FirebaseDatabase.getInstance());
}
#Override
protected void onStart() {
super.onStart();
firebaseAuthentication.addAuthStateListener();
}
#Override
public void onStop() {
super.onStop();
firebaseAuthentication.removeAuthStateListener();
}
}
AuthActivity class [child]:
public class AuthActivity extends MainActivity implements FirebaseAuthentication.OnUserAuthListener {
#BindView(R.id.viewPager) LockableViewPager viewPager;
private String userUID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_market);
ButterKnife.bind(this);
firebaseAuthentication.setOnUserAuthListener(this);
firebaseAuthentication.isSingedIn(); // check if user is singed in
}
#Override
// response for firebaseAuthentication.isSingedIn() above
public void onAuthSuccess(String userUID) {
this.userUID = userUID;
}
#Override
// response for firebaseAuthentication.isSingedIn() above
public void onAuthFailure(String message) {
snackbar(message);
Intent intent = new Intent(this, AuthActivity.class);
startActivity(intent);
finish(); // TODO mb should to delete it
}
}
Can this implementations bring me errors (maybe NullPointerExeption or what unexpectedly in future)?
Would be great if you provide me some sources to read/watch.
Thank you.
Perfect example of abstraction, but not really a question.
You will not get any nullpointers or other errors by implementing it like this.

Split code to two classes

I have a class with a lot of code. I want to put some of the methods into another class, but load them from the class that i already have. I don't want to change the contentview either. I tried
Class1:
public class Class1 extends Activity {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState;
Intent intent = new Intent (this, Class2.class);
startActivity(intent);
}
}
Class2:
public class Class2 extends Class1 {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
method2();
}
}
public void method2 {
Log.e("Error", "Wut?")
}
When i run that code, the app just displays the error message over and over. The app is probably running the "method2" method over and over again... I just want to run the "method2"once. I don't want the code in the same file either, because there is gonna be a lot of code...
All you have to do is call the class2 in a object Class. Remember that is a java class so. Call it!
Class2 newClass = new Class2();
newClass. method2();
The class2 is not a activity, is only a class for has all your methods.. It is would not extends of nothing!
As I see no sense in your approach here's a workaround.
public class Class1 extends Activity {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState;
if(!this instanceof Class2)
{
Intent intent = new Intent (this, Class2.class);
startActivity(intent);
}
}
}

passing data from activity to activity in android

What is the problem with my code :(
This is the sending class:
public class Send extends AppCompatActivity {
String message_text;
final static String MSG_KEY = "this.is.the.message";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.send_layout);
}
public void sendMessage(View view) {
EditText entryText = (EditText)findViewById(R.id.message_text);
message_text = entryText.getText().toString();
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(message_text, MSG_KEY);
startActivity(intent);
}
}
this is the receiver:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView theMessage = (TextView)findViewById(R.id.theMessage);
theMessage.setText(getIntent().getStringExtra("this.is.the.message"));
}
}
the app starts but it does not pass text, just an empty recieving activity ???
intent.putExtra(message_text, MSG_KEY);
replace with
intent.putExtra(MSG_KEY, message_text);
Frist argument is NAME , second argument - VALUE
You are using value as key and key as value which is causing this issue.
Change
intent.putExtra(message_text, MSG_KEY);
to
intent.putExtra(MSG_KEY, message_text);
If changing intent.putExtra(MSG_KEY, message_text); doesn't fix the issue. Check AndroidManifest.xml to make sure that MainActivity is not the launcher otherwise your MainActivity starts before the send class.

Categories

Resources