Why does program stop unexpectedly? - java

I'm writing a very basic program that aims for the text view to display the phrase "Hello" after a button is pressed on the screen, but cannot figure out why every time I run it, it says that the application has stopped unexpectedly.
This is the program I wrote:
public class EtudeActivityActivity extends Activity{
TextView tvResponse;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView tvResponse = (TextView) findViewById (R.id.tvResponse);
}
public void updateTV(View v) {
tvResponse.setText("Hello");
}
}
Also, I inserted an android:onClick = "updateTV" into my main.xml file for the button.
Thanks for any help!

It is because you don't set the tvResponse member variable. Instead you set a new local variable by the same name. So when you call setText(), you are accessing an invalid reference
You need to change
final TextView tvResponse = (TextView) findViewById (R.id.tvResponse);
to
tvResponse = (TextView) findViewById (R.id.tvResponse);
to set the member variable, so it has a valid reference later on (when updateTV() is called)

I suspect you've got an instance variable called tvResponse which you haven't shown us - that's what the updateTV method will refer to. That's entirely separate from the local tvResponse variable you've declared inside onCreate. I suspect that if you change the last line of onCreate from a local variable declaration to a simple assignment to the tvResponse variable, it may work. Otherwise, if nothing is assigning a value to the instance tvResponse variable, it will have the default value of null, causing a NullPointerException in updateTV.

Related

Is there any way to make an Activity react differently for each button when clicked?

Consider you have a Button A and button B both of them when clicked it start Activity1 which contains only one TextView.
Now When I click on Button A it should start Activity1 and setTextView to "The click was from A"
and when clicked on B it should set the text to "The click was from B".
So I figure out that by making a global Boolean variable but I wanted to know is there any other way that is more efficient than making a global Boolean variable(the code become really messy with Boolean)
And this all is just an example in reality I want to add a lot of code instead of just setting the text.
TL;DR
Pass arguments with your Intent object that launches Activity2. Use putExtra methods. That is the default way of passing small pieces of data.
Explained
"making a global Boolean variable" is a bad solution (nothing personal, it just does not fit the given problem) in this situation as anyone has access to that variable and the value can be changed at any point in time making it unreliable.
When you launch activity with Intent you can use putExtra methods on it (example of such method in docs).
For example, there is a putExtra that accepts boolean as a value: link. Using that method you can remove the global variable, but the code still could be messy.
If this boolean variable is simply deciding which label to show you can pass the label itself using these putExtra methods. It would look like this:
// From Activity1 when you click Button A
buttonA.setOnClickListener {
Intent intent = new Intent(Activity1.this, Activity2.class);
intent.putExtra(Activity2.SOME_KEY, "This label is from buttonA.");
startActivity(intent);
}
// From Activity1 when you click Button B
buttonB.setOnClickListener {
Intent intent = new Intent(Activity1.this, Activity2.class);
intent.putExtra(Activity2.SOME_KEY, "This label is from buttonB. A slightly different one.");
startActivity(intent);
}
Activity2.SOME_KEY is some public static variable that you should declare to be sure that you use the same key for setting and getting back the value. You can name it differently. It must be of String type. There is no need to declare it in Activity2 class but since it is the key for passing arguments for Activity2 only I think that is the most fitting place.
And now in you can get that value back in Activity2:
class Activity2 extends Activity {
public static String SOME_KEY = "some string value";
private String labelValue = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
labelValue = getIntent().getStringExtra(SOME_KEY);
// ... other stuff here like setContentView
// use `labelValue` to set text into some TextView.
}
}

Activity Instance does not exist- null object reference

I am trying to develop an Android application. For my use case I want to use a custom typeface and I wrote a that gathers all available TextViews in a View, so that I can set the typeface easily by a loop. I thought I should source out the text manipulation things to an own class named TextManager.class . But now when I am executing the app I am getting an error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
It occurs when I am trying to set Typeface in TextMangaer.class . I did a bit of research and found out that it is because the activity instance does not exist at this point. But I don't get it why, cause when I am trying to do this in Start.class there is no problem.
//Start.class
public class Start extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // set fullscreen
//Initialize shared preferences
prefs = getSharedPreferences("User", Context.MODE_PRIVATE);
editor=prefs.edit();
setContentView(R.layout.start_screen);
TextManager textManager= new TextManager();
textManager.setTypeface(getTextViews((ViewGroup) findViewById(R.id.root_menu)));
}
}
and my TextManager.class:
public class TextManager extends Start{
public TextManager(){
super();
}
public void setTypeface(List<Integer> idsOfTextViews){
Typeface typeFaceIkarosLight= Typeface.createFromAsset(getAssets(), "font/ikaros_light.otf");
for(int i=0; i < idsOfTextViews.size();i++){
((TextView)findViewById(idsOfTextViews.get(i))).setTypeface(typeFaceIkarosLight);
}
}
}
So how could I fix this or how should I write this? If anybody could help me figure it out that would be great. Thanks in advance.
Problem is context is null for getting assets.
Use getContext() or getApplicationContext() in case of being used in an activity but if it is being used in a fragment then use getActivity().getContext()
Typeface font = Typeface.createFromAsset(getContext().getAssets(), "font/ikaros_light.otf");
Instead of
Typeface typeFaceIkarosLight= Typeface.createFromAsset(getAssets(), "font/ikaros_light.otf");
Its better to make method which return typeface instead passing textview ids as an argument. you can do it like this :
public Typeface getTypeFace(Context context){
Typeface typeFaceIkarosLight = Typeface.createFromAsset(context.getAssets(), "font/ikaros_light.otf");
return typeFaceIkarosLight;
}
If you want to use custom fonts then you can take this example
This tutorial will show you how to set custom font on TextView, EditText and on Button.
http://androiderstack.com/index.php/2017/08/14/use-custom-font-in-textview-edittext-and-button-in-android/
This will surely help you

How to use global variable in onCreate method of Android

I am very much new to Android world. I was just trying to check how a global variable can be used in onCreate() method in Android, whenever i tried doing so, it closed abruptly. When I displayed some random text in the code, it was displayed successfully.
Here's my code:
public class MyActivity extends AppCompatActivity
{
public static int num_i=0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find_beer);
TextView tv = findViewById(R.id.textView);
tv.setText(num_i);
num_i++;
}
}
Please help me in this.
setText(CharSequence text)
Sets the text to be displayed. it takes String as a parameter not a number
Sample : tv.setText("PREM");
setText(int resid)
Sets the text to be displayed using a string resource identifier.
Sample : tv.setText(R.string.app_name);
first you have to convert your int value in to a String
Try this use
tv.setText(String.valueOf(num_i));
or
tv.setText(num_i+"");
instead of this
tv.setText(num_i);
Don't use tv.setText() with a number as parameter. Try using String.valueOf(num_i).
So in your case:
tv.setText(String.valueOf(num_i)) or tv.setText(num_i + "");

Android: ImageButton causes crash upon assigning it a listener

So, basically, I have an ImageButton called boutonPortail, and another called logo. Initializing boutonPortail works fine, but when I assign it its listener with boutonPortail.setOnClickListener(boutonPortailListener); the app crashes, and I don't know why at all. It's not a problem with the listener since when I assign it to logo it works just fine. I doubt it is a problem with the XML since I copy/pasted the code of logo.
My app prompts for a password, and if the password is correct it switches to another view with the logo and the boutonPortail. Note that the password prompt view also has the logo.
Is the problem that boutonPortail is not on the main view? I tried assigning the listener after switching views, but it still crashes.
EDIT: After putting the button in the main view, the problem is definitely that the button is not in the main view, when I put it in the main view it works fine. Why does it crashes though?
Also, for some reason I can't manage to change the image of the button with boutonPortail.setImageResource(R.drawable.boutonfermer);. (this doesn't happen when it is in the main view)
onCreate method:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
logo = (ImageButton)findViewById(R.id.logo);
boutonPortail = (ImageButton)findViewById(R.id.boutonPortail);
codeEntered = (EditText)findViewById(R.id.codeEntered);
codeSurNotice = (TextView)findViewById(R.id.codeSurNotice);
//attribute all listeners
logo.setOnClickListener(boutonPortailListener);
codeEntered.addTextChangedListener(textWatcher);
codeEntered.setOnKeyListener(codeEnteredListener);
Method to change view:
void codeCorrect() {
setContentView(R.layout.activity_readytopress);
boutonPortail.setOnClickListener(boutonPortailListener); //this line crashes the app, even if put in the onCreate
}
Listener:
private OnClickListener boutonPortailListener = new OnClickListener() {
#Override
public void onClick(View v) {
boutonState++;
if(boutonState>=4)
boutonState=0;
boutonPortail.setImageResource(R.drawable.boutonfermer);
}
};
XML:
<ImageButton
android:id="#+id/boutonPortail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="40dip"
android:src="#drawable/boutonouvrir"
android:background="#00000000"
style="#00000000"
android:layout_gravity="center"
/>
Here's my full code if you want to test it (note that you'll have to call the codeCorrect() method manually since you don't have access to the bluetooth device I use):
MainActivity.java http://pastebin.com/ZXDahPZ6
activity_main.xml http://pastebin.com/f14cVBKj
activity_readytopress.xml http://pastebin.com/0iZm91eq
boutonouvrir.png http://puu.sh/mLGeU.png
ouvertureencours.png http://puu.sh/mLGfI.png
boutonfermer.png http://puu.sh/mLGe5.png
fermetureencours.png http://puu.sh/mLGgW.png
Thanks :)
You do not have a button with the id boutonPortail in activity_main.xml
It is crashing with a Null Pointer Exception.
You cannot add a listener to a null object.
Here is your relevant code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// On récupère toutes les vues dont on a besoin
logo = (ImageButton)findViewById(R.id.logo);
boutonPortail = (ImageButton)findViewById(R.id.boutonPortail);
So you call setContentView(R.layout.activity_main) and then you call findViewById(R.id.boutonPortail)
The findContentView() will return null, because acitivty_main.xml does not have a view ID of that value. So now boutonPortail is null.
Then you call boutonPortail.setOnClickListener(boutonPortailListener) which will crash with a Null Pointer Exception because boutonPortail is null

Android; Declaring edittext in class body (Out of any method)

I have experience with programming languages but am a bit new to android programming.
I have a program with some fields that function as labels(textview), buttons, and data entry(edittext).
Whenever i declare them at the beginning of the program out of any methods(but in the class of course), when I start my application it crashes and simulation gives a "unfortunately, your program has stopped" alert.
Eclipse doesn't give any errors for the declaration and i did use the same way for defining regular variables with no issue. It also gives the same error when i declare a mediaplayer object in the class body.
Does anyone know why it gives error?
And is there another way to declare global objects like edittext, viewtext, etc... Declaring them over and over again in methods sounds weird to me.
Thank you!!
public class TrainerActivity extends Activity {
Button stopTimer = (Button)findViewById(R.id.StopTimer);
Button startTimer = (Button)findViewById(R.id.StartTimer);
EditText totalTime = (EditText)findViewById(R.id.TotalTime);
EditText enterMin = (EditText)findViewById(R.id.EnterMin);
EditText enterSec = (EditText)findViewById(R.id.EnterSec);
private boolean breaker = false;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startTimer.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Button_StartTimer();
}
});
stopTimer.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Button_StopTimer();
}
});
}
Without seeing example code of what you're trying it's impossible to say for definite (we don't do mind-reading here). But let me guess, you're doing something like this?...
public class MyActivity extends Activity {
TextView tv1; // This is fine.
  TextView tv2 = (TextView) findViewById(R.id.textview2); // Don't do this.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv1 = (TextView) findViewById(R.id.textview1); // This is fine
tv1.setText("Some text"); // This works
tv2.setText("Some text"); // NullPointerException here
}
}
The tv2.setText(...) will fail because you used findViewById(...) BEFORE you call setContenetView(...) and as a result, tv2 will be null.
It's quite acceptable to declare your widgets as instance members in your Activity but don't try to use findViewById(...) until AFTER you have set your content view.
try declaring the widget objects names only outside the onCreate() method
Button stopTimer;
Button startTimer;
EditText totalTime;
EditText enterMin;
EditText enterSec;
then initialise them after setContentView() inside onCreate()
setContentView(R.layout.main);
stopTimer = (Button)findViewById(R.id.StopTimer);
startTimer = (Button)findViewById(R.id.StartTimer);
totalTime = (EditText)findViewById(R.id.TotalTime);
enterMin = (EditText)findViewById(R.id.EnterMin);
enterSec = (EditText)findViewById(R.id.EnterSec);
Can you post a bit of sample code that illustrates the issue? It is fine to declare a member variable that is an EditText or TextView in the class.
logcat(in DDMS) should be give you some info about the error as well. If you are using eclipse there is a tab for DDMS, if not you can just run DDMS from a command line look at the logcat tab and launch your app (with your phone plugged in via usb, of course.) You should be able to see the actual error being reported.
You can declare these variables inside the Class body or inside the method body. In the former case, the variables are global and thus can be accessed within the whole class; in the latter case, they are local and thus can be only accessed within that method. Both of them could be commonly seen in proramming.
In Android, the typical application is that you declare the variables in the Class body and instantiate them in the onCreate() method. Something like this:
public Class MyClass extends Activity{
TextView label;// so this variable can be accessed within any methods in this Class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(Bundle savedInstanceState);
setContentView(R.layout.main) // load the layout of the activity
label=(TextView)findViewById(R.id.<the TextView id defined in the layout file>); //this variable get instantiated. From now on you can manipulate it anywhere inside the class.
Button submit=(Button)findViewById(R.id.<the Button id defined in the layout file>);//you declared and instantiated it, but it could only be used within this method since you declared it here.
}
}
If you just declare a variable in the Class body,in most caeses, you can't use it until you instantiate it, because they are null before the instantiation. I think this is why you have problems. Please post the logcat so we can specify the real problem.

Categories