Reputation: 569
So I'm learning android coding and I've come across a NullPointerException and I can't figure out why.
I know that whatever is causing the app to stop is in line 26:
LinearLayout billLL = (LinearLayout)findViewById(R.id.billLayout);
How is it wrong? The xml file has the id I'm interested in. I would really appreciate anyone's input on this. Thanks
this is TipCalc.java
package com.example.tipcalc;
import android.os.Bundle;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class TipCalc extends Activity {
private double bill;
private double tipRate;
private double tip;
EditText billET;
EditText tipRateET;
EditText tipET;
TextView billTV;
TextView tipRateTV;
TextView tipTV;
LinearLayout billLL = (LinearLayout)findViewById(R.id.billLayout);
LinearLayout tipRateLL = (LinearLayout)findViewById(R.id.tipRateLayout);
LinearLayout tipLL = (LinearLayout)findViewById(R.id.tipLayout);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tip_calc);
bill = 0;
tipRate = .15;
tip = bill*tipRate;
billET = (EditText)billLL.findViewById(R.id.editText);
tipRateET = (EditText)tipRateLL.findViewById(R.id.editText);
tipET = (EditText)tipLL.findViewById(R.id.editText);
billTV = (TextView)billLL.findViewById(R.id.name);
tipRateTV = (TextView)tipRateLL.findViewById(R.id.name);
tipTV = (TextView)tipLL.findViewById(R.id.name);
billTV.setText(getString(R.string.bill_total_name));
tipRateTV.setText(getString(R.string.tip_rate));
tipTV.setText(getString(R.string.tip_name));
billET.addTextChangedListener(billListener);
tipRateET.addTextChangedListener(tipRateListener);
billET.setText(String.format("%.02f",bill));
tipRateET.setText(String.format("%.02f",tipRate));
tipET.setText(String.format("%.02f",tip));
}
private TextWatcher billListener = new TextWatcher(){
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
try{
bill = Double.parseDouble(s.toString());
}
catch(NumberFormatException e){
bill = 0.0;
}
updateTip();
}
};
private TextWatcher tipRateListener = new TextWatcher(){
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
try{
tipRate = Double.parseDouble(s.toString());
}
catch(NumberFormatException e){
tipRate = 0.15;
}
updateTip();
}
};
public void updateTip(){
tip = bill*tipRate;
tipET.setText(String.format("%.02f", tip));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.tip_calc, menu);
return true;
}
}
this is activity_tip_calc.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title" />
<include
android:id="@+id/billLayout"
layout="@layout/line" />
<include
android:id="@+id/tipRateLayout"
layout="@layout/line" />
<include
android:id="@+id/tipLayout"
layout="@layout/line" />
</LinearLayout>
and this is line.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<EditText
android:id="@+id/editText"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="number" >
<requestFocus />
</EditText>
</LinearLayout>
here is the log as well
07-31 18:40:30.225: E/AndroidRuntime(31866): FATAL EXCEPTION: main
07-31 18:40:30.225: E/AndroidRuntime(31866): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.tipcalc/com.example.tipcalc.TipCalc}: java.lang.NullPointerException
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2137)
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.app.ActivityThread.access$600(ActivityThread.java:141)
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.os.Handler.dispatchMessage(Handler.java:99)
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.os.Looper.loop(Looper.java:137)
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.app.ActivityThread.main(ActivityThread.java:5103)
07-31 18:40:30.225: E/AndroidRuntime(31866): at java.lang.reflect.Method.invokeNative(Native Method)
07-31 18:40:30.225: E/AndroidRuntime(31866): at java.lang.reflect.Method.invoke(Method.java:525)
07-31 18:40:30.225: E/AndroidRuntime(31866): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
07-31 18:40:30.225: E/AndroidRuntime(31866): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-31 18:40:30.225: E/AndroidRuntime(31866): at dalvik.system.NativeStart.main(Native Method)
07-31 18:40:30.225: E/AndroidRuntime(31866): Caused by: java.lang.NullPointerException
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.app.Activity.findViewById(Activity.java:1853)
07-31 18:40:30.225: E/AndroidRuntime(31866): at com.example.tipcalc.TipCalc.<init>(TipCalc.java:26)
07-31 18:40:30.225: E/AndroidRuntime(31866): at java.lang.Class.newInstanceImpl(Native Method)
07-31 18:40:30.225: E/AndroidRuntime(31866): at java.lang.Class.newInstance(Class.java:1130)
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
07-31 18:40:30.225: E/AndroidRuntime(31866): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2128)
07-31 18:40:30.225: E/AndroidRuntime(31866): ... 11 more
Upvotes: 2
Views: 368
Reputation: 44571
Just to add a code example to the previous 2, nicely explained answers (+1 to them for explanation), it should look something like this
LinearLayout billLL, tipRateLL, tipLL; // declare here so they can be used anywhere in the Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tip_calc);
// but initialize here
billLL = (LinearLayout)findViewById(R.id.billLayout);
tipRateLL = (LinearLayout)findViewById(R.id.tipRateLayout);
tipLL = (LinearLayout)findViewById(R.id.tipLayout);
Upvotes: 1
Reputation:
NullPointerException means the DVM is unable to find the referenced item at that location and is returning "Null".
So, You need to investigate on this. Now, Since you have the logs, It is pointing that the line where you have referenced the id of a LinearLayout is causing the issue. Now, You must look If You are having that id in your R.java file, still why you are encountering that issue. Since, You have the Linear Layout present in the activity_tip_calc layout file. So, You must have called the setContentView(viewID) before referring to the layout ID. Thanks!!
Upvotes: 0
Reputation: 3330
You're trying to findbyId before you've actually set the content view. Any finding by id should be after the line
setContentView(R.layout.activity_tip_calc);
So try placing all 3
(LinearLayout)findViewById(R.id.billLayout);
looking things after you've actually set the content view within oncreate.
The reason you get a Null is the fact that there's no layout to go searching for R.id.billLayout, the activity has no idea yet what it's layout is going to be so therefore can't work find the billLayout.
Upvotes: 2
Reputation: 41099
You need to run this line:
LinearLayout billLL = (LinearLayout)findViewById(R.id.billLayout);
and the two line afrer it:
LinearLayout tipRateLL = (LinearLayout)findViewById(R.id.tipRateLayout);
LinearLayout tipLL = (LinearLayout)findViewById(R.id.tipLayout);
only after you inflated you view in this line:
setContentView(R.layout.activity_tip_calc);
and activity_tip_calc
needs to have billLayout
in it. While the activity doesn't have a contentView that you have specified for it you can't use the findViewById
to actually look for a View
in it's layout.
Upvotes: 3