Android Fatal Exception Timer-0

时间:2011-11-03 07:13:52

标签: android

以下是我遇到的错误

11-03 03:03:02.380: W/dalvikvm(1381): threadid=9: thread exiting with uncaught exception (group=0x40015560)
11-03 03:03:02.400: E/AndroidRuntime(1381): FATAL EXCEPTION: Timer-0
11-03 03:03:02.400: E/AndroidRuntime(1381): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.os.Handler.<init>(Handler.java:121)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:173)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:173)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.location.LocationManager._requestLocationUpdates(LocationManager.java:579)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:446)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at com.colinlgray.MyService$1.run(MyService.java:84)
11-03 03:03:02.400: E/AndroidRuntime(1381):     at java.util.Timer$TimerImpl.run(Timer.java:284)

这是我的服务,我正在尝试使用其中的计时器来更新我计划用​​于发送到网络服务器的GPS位置

package com.colinlgray;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import java.util.Timer;
import java.util.TimerTask;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import com.google.android.maps.GeoPoint;

import android.content.Context;

public class MyService extends Service{
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();

GeoPoint geopoint;

private LocationManager lm;
private LocationListener locationListener;

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // We want this service to continue running until it is explicitly
    // stopped, so return sticky.
    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
    doSomethingRepeatedly();
    return START_STICKY;
}

private void doSomethingRepeatedly() {
    timer.scheduleAtFixedRate( new TimerTask() {
        public void run() {
            lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

            class MyLocationListener implements LocationListener{

                public void onLocationChanged(Location location) {
                    geopoint = new GeoPoint(
                            (int) (location.getLatitude() * 1E6),
                            (int) (location.getLongitude() * 1E6));
                    double latitude = location.getLatitude();
                    double longitude = location.getLatitude();
                    double altitude = location.getAltitude();
                    double accuracy = location.getAccuracy();
                    Log.d("LONGITUDE", String.valueOf(longitude));
                    Log.d("LATITTUDE", String.valueOf(latitude));

                }

                public void onProviderDisabled(String provider) {
                    // TODO Auto-generated method stub

                }

                public void onProviderEnabled(String provider) {
                    // TODO Auto-generated method stub

                }

                public void onStatusChanged(String provider, int status,
                        Bundle extras) {
                    // TODO Auto-generated method stub

                }
            }

            locationListener= new MyLocationListener();
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,locationListener);
        }
    }, 0, UPDATE_INTERVAL);
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (timer != null){
        timer.cancel();
    }
    Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}

}

我会感激任何帮助或建议。感谢

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。 我已经解决了从Timer中执行locationrequestupdates的问题,并在Timer I的run方法中将纬度和经度发送到Web服务器。

其他可能的解决方案是不使用计时器。随着

public void requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)

您可以告诉新的更新位置和“onLocationChanged(位置位置)”之间的minTime,您可以发送新的位置。

答案 1 :(得分:1)

从UI线程调用Async任务。任何未调用Looper.prepare()的线程都会导致此问题。

我今天遇到了同样的问题所以发布我的工作,看看这是否是最好的解决方案。

首先在你的代码中不要在运行

中执行此操作
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

而是将其移动到重复启动函数dosomething。 e.g。

    public void dosomethingrepeatedly()
        {
            final Myclass x = new Myclass();
            ..........
        public void run()
        {
            x.somefunction()
        }
       }

替代方法: 找出currentThread

Thread.currentThread().getClass();

如果它是Timer的一个实例,你可以调用Looper.prepare(); 设置一个标志,以便只调用一次Looper.prepare。 e.g。

    boolean looperCalled=false;
    ...
    ...
    ...
    public void dorepeatedly()
    {
        ....
        ....
        public void run()
        {
            if(Thread.currentThread().getName().equals(java.util.Timer$TimerImpl)
            {
                if(looperCalled){//do nothing}
                else {Looper.prepare(); looperCalled=true;}
            }
        }
    }