Null Pointer exception when trying to update textviews
Ok, What the app is supposed to do:
- displays a start button,
- when pressed two services start to run and the start button (view) changes to a stop button,
- when the stop button is pressed the code is supposed to change view again to display all of the results
what is happening at the moment is the code is running all the way up until the very last method call (update(); which is marked in the code) and the logcat is reporting a nullPointerException at line 146 whick I have marked in the code.
IMPORTANT TO NOTE!
- If I remove the "update();" method call the code executes perfectly and displays the values given to the text views in the xml itself. its just when I try update the textviews that it crashes. I have tried putting them in other locations in the file but I still get the same error
I had a very similar problem yesterday but I tried doing the same thing to fix this one and it has not worked. I have posted the xml layout file that it is accessing. The error I had yesterday was that the layout file idin't have a definition for one of the buttons (that I have now removed).
Here is my main class.
public class GPSMain extends Activity {
protected PowerManager powerManager;
protected PowerManager.WakeLock wL;
//text views to display latitude, longitude, speed and G force values
static TextView latituteField, longitudeField, kmphSpeedField, avgKmphField, topKmphField, accText, totalDistance;
//objects to store information for GPS locations and current, top, total and average speed
protected static double lat = 0, lon = 0, kmphSpeed = 0, avgKmph = 0, totalKmph = 0, topKmph = 0;
protected static float distanceBetweenPoints = 0.0f;
protected static Location previousLocation;
//accelerometer values
static String a = "x", b = "y", c = "z";
//context for Toast views
private Context context;
//The stop and start button
static Button button;
//switch to alternate between stop and start features
private int buttonSwitch = 2;
static int counter = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start);
context = this;
//gives the button the start value
button = (Button) findViewById(R.id.startbutton);
//calls the method to the initial button listener
switchButton();
//sets up the text views to display results
latituteField = (TextView) findViewById(R.id.lat);
longitudeField = (TextView) findViewById(R.id.lon);
totalDistance = (TextView) findViewById(R.id.totaldistance);
kmphSpeedField = (TextView) findViewById(R.id.kmph);
avgKmphField = (TextView) findViewById(R.id.avgkmph);开发者_StackOverflow
topKmphField = (TextView) findViewById(R.id.topkmph);
accText = (TextView) findViewById(R.id.acctext);
}
//defines the button functions
void switchButton(){
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(buttonSwitch%2==0){
buttonSwitch++;
startService();
}
else
{
buttonSwitch++;
stopService();
update(); //update method call
}
}
});
}
//rounds the float values from the accelerometer
static String roundTwoDecimalFloat(float a){
String formattedNum;
NumberFormat nf = new DecimalFormat();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
formattedNum = nf.format(a);
return formattedNum;
}
//starts the 2 services and changes the button from a start button to a stop button
void startService(){
setContentView(R.layout.stop);
GPSMain.button = (Button) findViewById(R.id.stopbutton);
switchButton();
Toast.makeText(context, "Accessing Accelerometer", Toast.LENGTH_LONG).show();
startService(new Intent(this, AccelerometerReader.class));
Toast.makeText(context, "Acquiring GPS Locations", Toast.LENGTH_LONG).show();
startService(new Intent(this, Calculations.class));
}
//stops the two services
void stopService(){
setContentView(R.layout.results);
Toast.makeText(context, "Terminating Accelerometer", Toast.LENGTH_LONG).show();
AccelerometerReader.myManager.unregisterListener(AccelerometerReader.mySensorListener);
stopService(new Intent(this, AccelerometerReader.class));
Toast.makeText(context, "Terminating Connection", Toast.LENGTH_LONG).show();
Calculations.locationManager.removeUpdates(Calculations.locationListener);
stopService(new Intent(this, Calculations.class));
}
//prints the results to the screen
static void update(){
146 latituteField.setText("Current Latitude: "+String.valueOf(lat));
longitudeField.setText("Current Longitude: "+String.valueOf(lon));
totalDistance.setText("Total Distance: "+String.valueOf(distanceBetweenPoints/1000));
kmphSpeedField.setText("Cuttent Speed (kmph): "+String.valueOf(kmphSpeed));
avgKmphField.setText("Average Speed (kmph): "+String.valueOf(avgKmph));
topKmphField.setText("Top Speed (kmph): "+String.valueOf(topKmph));
accText.setText("Accelerometer Values: "+" x: " + a + " y: " + b + " z: " + c);
}
}
Here is the xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linearlayout1"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/hello"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:id="@+id/lat"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Current Latitude: unknown"
/>
<TextView
android:id="@+id/lon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Current Longitude: unknown"
/>
<TextView
android:id="@+id/totaldistance"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Total Distance (km): unknown"
/>
<TextView
android:id="@+id/kmph"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Current Speed (kmph): unknown"
/>
<TextView
android:id="@+id/avgkmph"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Average Speed (kmph): unknown"
/>
<TextView
android:id="@+id/topkmph"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Top Speed (kmph): unknown"
/>
<TextView
android:id="@+id/acctext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Accelerometer Values: unknown"
/>
</LinearLayout>
The issue is you are calling switchButton()
method before initilizing the TextView ie latituteField = (TextView) findViewById(R.id.lat);
because of that you got null pointer exception. so first write initilization of all view elements after that call switchButton()
. I have modified your code. Try with the following code
Use the following code for onCreate method
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start);
context = this;
// gives the button the start value
button = (Button) findViewById(R.id.startbutton);
// calls the method to the initial button listener
// sets up the text views to display results
latituteField = (TextView) findViewById(R.id.lat);
longitudeField = (TextView) findViewById(R.id.lon);
totalDistance = (TextView) findViewById(R.id.totaldistance);
kmphSpeedField = (TextView) findViewById(R.id.kmph);
avgKmphField = (TextView) findViewById(R.id.avgkmph);
topKmphField = (TextView) findViewById(R.id.topkmph);
accText = (TextView) findViewById(R.id.acctext);
switchButton();
}
into the update method try using txt=(TextView)findviewbyId(R.id.yourtextid);
When you call setContentView() your references to any Views that were previously established are no longer valid.
In onCreate() you setContentView(R.layout.results) and then you establish latitudeField (and other references) which, assuming they do not come back null, is fine. (You didn't mention which layout you provided xml for).
Next you install your button listener, which either calls startService() or stopService(), each of which set a new content view, neither of which updates your View references; all priors are invalid at this point. Then you call update(), which tries to use an invalid reference.
Either update your references when you change views, or fetch them at the time they're needed.
精彩评论