开发者

Null Pointer exception when trying to update textviews

Ok, What the app is supposed to do:

  1. displays a start button,
  2. when pressed two services start to run and the start button (view) changes to a stop button,
  3. 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!

  1. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜