0

ボタンでAsyncTaskを開始し、別のボタンで停止するという単純なアクティビティがあります。

AsyncTaskでは、LocationListnerを使用してGPSセンサーから更新を取得し、取得したロケーション間の距離を計算します。

スタートボタンを押すと、新しいスレッドが作成され、コードは正常に機能します。デバッグの観点から、GPSの更新が定期的にキャッチされ、それに応じて変数が更新されていることがわかります。

しかし、キャンセルボタンを押すと問題が発生します。ドキュメント(http://developer.android.com/reference/android/os/AsyncTask.html)で、doInBackgroundコードが終了したときにcancel()メソッドがonCancelled()を呼び出す必要があることを読みました。そのため、私は次のように述べています。

if (isCancelled()){
    locManager.removeUpdates(locListener);
}

doInBackgroundメソッド全体で、私がそれから抜け出すことを望んでいます。残念ながら、私はその部分にさえ到達しません。終了ボタンを押すと、次のエラーが発生します。

05-22 11:10:05.043: E/Handler(6353): java.lang.NullPointerException
05-22 11:10:05.043: E/Handler(6353):    at com.pavle.taximetar.TaximetarActivity$2.onClick(TaximetarActivity.java:43)
05-22 11:10:05.043: E/Handler(6353):    at android.view.View.performClick(View.java:3538)
05-22 11:10:05.043: E/Handler(6353):    at android.view.View$PerformClick.run(View.java:14330)
05-22 11:10:05.043: E/Handler(6353):    at android.os.Handler.handleCallback(Handler.java:607)
05-22 11:10:05.043: E/Handler(6353):    at android.os.Handler.dispatchMessage(Handler.java:92)
05-22 11:10:05.043: E/Handler(6353):    at android.os.Looper.loop(Looper.java:154)
05-22 11:10:05.043: E/Handler(6353):    at android.app.ActivityThread.main(ActivityThread.java:4974)
05-22 11:10:05.043: E/Handler(6353):    at java.lang.reflect.Method.invokeNative(Native Method)
05-22 11:10:05.043: E/Handler(6353):    at java.lang.reflect.Method.invoke(Method.java:511)
05-22 11:10:05.043: E/Handler(6353):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-22 11:10:05.043: E/Handler(6353):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-22 11:10:05.043: E/Handler(6353):    at dalvik.system.NativeStart.main(Native Method)

任意のアイデア、このエラーの背後にあるもの。これが完全なコードです。(ビルドターゲットはAndroid 4.0.3です)。コードはHTCOneVでテストされています。

public class TaximetarActivity extends Activity {

DistanceCalculator distanceCalculator;
public ArrayList<Drive> listOfRides = new ArrayList<Drive>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final Button startRide = (Button) findViewById(R.id.button1);
    final Button endRide = (Button) findViewById(R.id.button2);

    startRide.setOnClickListener(new OnClickListener() {        
        public void onClick(View v) {
            distanceCalculator = new DistanceCalculator();
            distanceCalculator.execute(getApplicationContext());
        }   
    });

    endRide.setOnClickListener(new OnClickListener() {  
        public void onClick(View v) {
            distanceCalculator.cancel(true);
        }
    });
}
}

public class DistanceCalculator extends AsyncTask<Context, Void, Void> {

Drive currentRide = new Drive();
Float distanceOfaRide = (float) 0;
LocationManager locManager;
LocationListener locListener;
Context mCtx;
boolean startPointEntered = false;

@Override
protected Void doInBackground(Context... params) {

    mCtx = params[0];


    Looper.prepare();

    if (isCancelled()){
        locManager.removeUpdates(locListener);
    }

    locManager = (LocationManager) mCtx.getSystemService(Context.LOCATION_SERVICE);
    locListener = new LocationListener() {

        public void onStatusChanged(String provider, int status, Bundle extras) {
            if (isCancelled()){
                locManager.removeUpdates(locListener);
            }
        }

        public void onProviderEnabled(String provider) {
            if (isCancelled()){
                locManager.removeUpdates(locListener);
            }
        }

        public void onProviderDisabled(String provider) {
            if (isCancelled()){
                locManager.removeUpdates(locListener);
            }               
        }

        public void onLocationChanged(Location location) {
            if (DistanceCalculator.this.isCancelled()){
                locManager.removeUpdates(locListener);
            }
            calculateDistance(location);
        }
    };

    locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, locListener);
    Looper.loop();
    return null;
}

@Override
protected void onCancelled() {
    locManager.removeUpdates(locListener);
    Intent intent = new Intent(mCtx, DisplayRide.class);
    intent.putExtra("Distance", distanceOfaRide);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    mCtx.startActivity(intent);
}

private void calculateDistance(Location location){
    if (startPointEntered){
        Location lastPoint = currentRide.drivePoints.get(currentRide.drivePoints.size()-1);
        currentRide.addNewPoint(location);
        distanceOfaRide = distanceOfaRide + location.distanceTo(lastPoint);
    }
    else{
        currentRide.setStartPoint(location);
        startPointEntered = true;
    }
}
}

public class Drive {

    Location startPoint;
    Location endPoint;
    ArrayList<Location> drivePoints = new ArrayList<Location>();

    public Drive() {
        // TODO Auto-generated constructor stub
    }

    public void setStartPoint(Location location){
            startPoint = new Location(location);
        drivePoints.add(0, startPoint);
    }
    public void setEndPoint(Location location){
        endPoint = new Location(location);  
    }
    public void addNewPoint(Location location){
        drivePoints.add(location);
    }
    public Location getStartPoint(){
        return startPoint;
    }
}
4

2 に答える 2

0

locManager割り当てる前にアクションを実行しています。

if (isCancelled()){
    locManager.removeUpdates(locListener);
}

locManager = (LocationManager) mCtx.getSystemService(Context.LOCATION_SERVICE);

対...

locManager = (LocationManager) mCtx.getSystemService(Context.LOCATION_SERVICE);
if (isCancelled()){
    locManager.removeUpdates(locListener);
}
于 2012-05-31T21:12:28.757 に答える
0

コードのこの部分に問題がありました:

endRide.setOnClickListener(new OnClickListener() {  
    public void onClick(View v) {
        distanceCalculator.cancel(true);
    }
});

ここでは、非同期タスクで作成されたハンドラーにメッセージを送信する必要があります。そのメッセージに応答して、メッセージハンドラー関数はタスクをキャンセルする必要があります。

于 2012-06-02T15:05:56.923 に答える