尝试更新文本视图时出现空指针异常

时间:2011-06-16 11:37:42

标签: android layout view nullpointerexception

好的,该应用应该做什么:

  1. 显示一个开始按钮,
  2. 按下两个服务开始运行,开始按钮(视图)变为停止按钮
  3. 当按下停止按钮时,代码应该再次改变视图以显示所有结果
  4. 目前正在发生的事情是代码一直在运行,直到最后一个方法调用(update();在代码中标记)并且logcat在第146行报告了一个nullPointerException,我已经标记了在代码中。

    需要注意!

    1. 如果我删除“update();”方法调用代码执行完美,并在xml本身中显示给予文本视图的值。它只是当我尝试更新它崩溃的textviews时。我已经尝试将它们放在文件中的其他位置,但我仍然得到相同的错误
    2. 昨天我遇到了一个非常类似的问题,但我尝试做同样的事情来解决这个问题但是没有用。我发布了它正在访问的xml布局文件。我昨天遇到的错误是布局文件没有其中一个按钮的定义(我现在删除了)。

      这是我的主要课程。

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

      这是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>
      

3 个答案:

答案 0 :(得分:2)

问题是你在启动TextView之前调用switchButton()方法即latituteField = (TextView) findViewById(R.id.lat);,因为你有空指针异常。所以首先在调用switchButton()之后编写所有视图元素的初始化。我修改了你的代码。请尝试使用以下代码

对onCreate方法

使用以下代码
@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();

    }

答案 1 :(得分:0)

进入更新方法尝试使用txt=(TextView)findviewbyId(R.id.yourtextid);

答案 2 :(得分:0)

当你调用setContentView()时,对先前建立的任何视图的引用都不再有效。

在onCreate()中你setContentView(R.layout.results)然后你建立latitudeField(和其他引用),假设它们没有返回null,就可以了。 (你没有提到你为xml提供的布局)。

接下来安装按钮侦听器,它调用startService()或stopService(),每个都设置一个新的内容视图,这两个视图都不会更新View引用;所有先辈在这一点上都是无效的。然后调用update(),它尝试使用无效的引用。

更改视图时更新引用,或者在需要时获取它们。