Исключение нулевого указателя для onSetClickListener - PullRequest
1 голос
/ 15 июня 2011

ОК, я пытаюсь заставить свое приложение сделать следующее.

  1. при его открытии отобразить кнопку запуска.
  2. при нажатии этой кнопки запускаются две службы, одна для акселерометра и одна для GPS, и кнопка превращается в кнопку остановки.
  3. службы будут продолжать работать до тех пор, пока не будет нажата кнопка «Стоп», отключив слушателей и остановив службы.
  4. после нажатия кнопки «Стоп» приложение отображает количество вычислений, выполненных приложением во время сбора данных.

Важные факты, которые нужно знать:

  1. все расчеты работают
  2. проблема началась после того, как я изменил представления. Первоначально был только один вид, который отображал кнопки и все расчеты по мере их обновления в режиме реального времени.
  3. Затем я изменил приложение, чтобы иметь 3 просмотра. Один для каждой кнопки и один для результатов. после того, как я это сделал, приложение перестало работать. ТЕМ НЕ МЕНИЕ!!!! Возможно, я внес некоторые изменения, не проверив, работали ли они до того, как я изменил представления, но я пытался выяснить, в чем проблема, так долго, что я не могу правильно вспомнить точный порядок событий.

Это мой текущий метод onCreate:

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.start);

    setGPS();
    context = this;

    Button startButton = (Button) findViewById(R.id.startbutton);
    Button stopButton = (Button) findViewById(R.id.stopbutton);

    Log.d("NULL POINTER", "NULL POINTER");
    startButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Log.d("NULL POINTER", "NULL POINTER");
            //setContentView(R.layout.stop);
            startService();

        }
    });

    stopButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            //setContentView(R.layout.results);
            stopService();

        }
    });

Хорошо, в этом коде вы увидите два отпечатка Log.d с надписью «NULL POINTER». Когда я запускаю свой код, отображается первый, а второй нет, что, очевидно, означает, что код в середине вызывает сбой программы, и это отображается в журнале cat:

06-15 12:30:25.176: DEBUG/AndroidRuntime(1037): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
06-15 12:30:25.185: DEBUG/AndroidRuntime(1037): CheckJNI is ON
06-15 12:30:25.537: DEBUG/AndroidRuntime(1037): --- registering native functions ---
06-15 12:30:25.806: DEBUG/ddm-heap(1037): Got feature list request
06-15 12:30:26.147: INFO/ActivityManager(52): Starting activity: Intent {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=Hartford.gps/.GPSMain }
06-15 12:30:26.177: INFO/ActivityManager(52): Start proc Hartford.gps for activity Hartford.gps/.GPSMain: pid=1043 uid=10030 gids={}
06-15 12:30:26.196: DEBUG/AndroidRuntime(1037): Shutting down VM
06-15 12:30:26.196: DEBUG/dalvikvm(1037): DestroyJavaVM waiting for non-daemon threads to exit
06-15 12:30:26.196: DEBUG/dalvikvm(1037): DestroyJavaVM shutting VM down
06-15 12:30:26.196: DEBUG/dalvikvm(1037): HeapWorker thread shutting down
06-15 12:30:26.207: DEBUG/dalvikvm(1037): HeapWorker thread has shut down
06-15 12:30:26.207: DEBUG/jdwp(1037): JDWP shutting down net...
06-15 12:30:26.226: INFO/dalvikvm(1037): Debugger has detached; object registry had 1 entries
06-15 12:30:26.226: DEBUG/dalvikvm(1037): VM cleaning up
06-15 12:30:26.246: ERROR/AndroidRuntime(1037): ERROR: thread attach failed
06-15 12:30:26.317: DEBUG/dalvikvm(1037): LinearAlloc 0x0 used 638596 of 5242880 (12%)
06-15 12:30:26.456: DEBUG/ddm-heap(1043): Got feature list request
06-15 12:30:26.906: DEBUG/NULL POINTER(1043): NULL POINTER
06-15 12:30:26.916: DEBUG/AndroidRuntime(1043): Shutting down VM
06-15 12:30:26.916: WARN/dalvikvm(1043): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
06-15 12:30:26.916: ERROR/AndroidRuntime(1043): Uncaught handler: thread main exiting due to uncaught exception
06-15 12:30:26.926: ERROR/AndroidRuntime(1043): java.lang.RuntimeException: Unable to start activity ComponentInfo{Hartford.gps/Hartford.gps.GPSMain}: java.lang.NullPointerException
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.os.Looper.loop(Looper.java:123)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.app.ActivityThread.main(ActivityThread.java:4363)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at java.lang.reflect.Method.invokeNative(Native Method)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at java.lang.reflect.Method.invoke(Method.java:521)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at dalvik.system.NativeStart.main(Native Method)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043): Caused by: java.lang.NullPointerException
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at Hartford.gps.GPSMain.onCreate(GPSMain.java:70)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
06-15 12:30:26.926: ERROR/AndroidRuntime(1043):     ... 11 more

Я нахожусь в конце своего остроумия, пытаясь заставить это работать! Я перепробовал все, что мог придумать, но я думаю, что на этом этапе у меня есть тонкое зрение, и ему просто нужен другой набор глаз, чтобы посмотреть на него.

Я могу выложить больше кода, если потребуется

Любая помощь, которую может предложить кто-нибудь, будет потрясающей!

@ Mark

о, хорошо, спасибо! Как вы имеете в виду, что они могут быть нулевыми? Вот файл start.xml, он идентичен файлу stop.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button
        android:id="@+id/startbutton"
        android:layout_width="100px" 
        android:layout_height="100px" 
        android:text="Start"
        android:layout_centerInParent="true"
    />

</LinearLayout>

@ Егор и Мах

вот полный файл со строкой 70, помеченной

import java.text.DecimalFormat;
import java.text.NumberFormat;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class GPSMain extends Activity   {

PowerManager powerManager;
PowerManager.WakeLock wL;

//text views to display latitude and longitude
static TextView latituteField;
static TextView longitudeField;
static TextView kmphSpeedField;
static TextView avgKmphField;
static TextView topKmphField;
static TextView accText;

//objects to store positional information
protected static double lat;
protected static double lon;

//objects to store values for current and average speed
protected static double kmphSpeed;
protected static double avgKmph;
protected static double totalKmph;
protected static double topKmph=0;

static String a, b, c;

private Context context;

//counter that is incremented every time a new position is received, used to calculate average speed
static int counter = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.start);

    setGPS();
    context = this;

    Button startButton = (Button) findViewById(R.id.startbutton);
    Button stopButton = (Button) findViewById(R.id.stopbutton);

    Log.d("NULL POINTER", "NULL POINTER");
    startButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Log.d("NULL POINTER", "NULL POINTER");
            //setContentView(R.layout.stop);
            startService();

        }
    });

70      stopButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            //setContentView(R.layout.results);
            stopService();

        }
    });

    latituteField = (TextView) findViewById(R.id.lat);
    longitudeField = (TextView) findViewById(R.id.lon);     
    kmphSpeedField = (TextView) findViewById(R.id.kmph);
    avgKmphField = (TextView) findViewById(R.id.avgkmph);
    topKmphField = (TextView) findViewById(R.id.topkmph);
    accText = (TextView) findViewById(R.id.acctext);

}

void setGPS(){
    powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
    wL = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,"My Tag");

}

static String roundTwoDecimalFloat(float a){

    String formattedNum;
    NumberFormat nf = new DecimalFormat();
    nf.setMaximumFractionDigits(2);
    nf.setMinimumFractionDigits(2);
    formattedNum = nf.format(a);
    return formattedNum;
}

void startService(){

    wL.acquire();
    Log.d("DEBUG", "start");
    startService(new Intent(this, AccelerometerReader.class));
    Toast.makeText(context, "Accessing Accelerometer", Toast.LENGTH_LONG).show();
    //startService(new Intent(this, Calculations.class));
    //Toast.makeText(context, "Acquiring GPS Locations", Toast.LENGTH_LONG).show();

}

void stopService(){

    wL.release();
    Calculations.locationManager.removeUpdates(Calculations.locationListener);
    stopService(new Intent(this, AccelerometerReader.class));
    Toast.makeText(context, "Terminating Accelerometer", Toast.LENGTH_LONG).show();
    //stopService(new Intent(this, Calculations.class));
    //Toast.makeText(context, "Terminating Connection", Toast.LENGTH_LONG).show();

}

static void update(){

    latituteField.setText("Current Latitude: "+String.valueOf(lat));
    longitudeField.setText("Current Longitude: "+String.valueOf(lon));
    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);

}

}

1 Ответ

1 голос
/ 15 июня 2011

Вы ошибаетесь в своем утверждении, что два оператора Log доказывают, что между ними возникает ошибка. Код onClick () будет выполнен позже.

Наиболее вероятной причиной вашей ошибки является то, что startButton или stopButton имеет значение null, и что один или оба из ваших findViewById поисков завершаются неудачно. Попробуйте сбросить их в операторах журнала или запустить их в отладчике и проверить их, чтобы выяснить, какое из них пустое.

РЕДАКТИРОВАТЬ: Просмотр ваших файлов XML, проблема теперь ясна. Вы надувает start.xml, и в нем содержится определение R.id.startbutton. Но он не содержит определения для R.id.stopbutton. Поэтому ваш Button stopButton = (Button) findViewById(R.id.stopbutton); устанавливает stopButton в ноль, потому что он не существует в вашем макете. Затем вы пытаетесь добавить OnClickListener к этому нулевому объекту, который вызывает ваш NPE.

...