传递上下文以调用“getSystemService”

时间:2011-11-15 01:18:24

标签: android multithreading android-context locationmanager

在访问Thread中调用的方法中的位置服务时,我的应用程序崩溃。我从运行线程的服务中传递上下文,但它不起作用。

这是对服务中创建的线程内LocationService的调用。

class MyService extends Service {

  @Override 
  public int onStartCommand(Intent intent, int flags, int startId) {

  Thread thread = new Thread(){
    @Override
    public void run() {

      try{
        geofix = new GeoFixer(getApplicationContext());
        geofix.startLocationObserver(); 
        ...
      }catch (....){}....

GeoFixer的构造函数获取上下文并将其保存在Context context

现在在方法startLocationObserver()内部,我使用此上下文调用getSystemService,这会导致应用程序崩溃。

public class GeoFixer {
  ... 
  private Context context;

  GeoFixer(Context context){
    this.context = context; 
  }

  public void startLocationObserver(){
     LocationManager locationManager = (LocationManager)     
     context.getSystemService(Context.LOCATION_SERVICE);
  // This is where it crashes
  ... }

我做错了什么?

编辑:现在是LogCat。

ERROR/AndroidRuntime(8824): FATAL EXCEPTION: Thread-10
ERROR/AndroidRuntime(8824): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
ERROR/AndroidRuntime(8824): at android.os.Handler.<init>(Handler.java:121)
ERROR/AndroidRuntime(8824): at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:173)
ERROR/AndroidRuntime(8824): at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:173)
ERROR/AndroidRuntime(8824): at android.location.LocationManager._requestLocationUpdates(LocationManager.java:579)
ERROR/AndroidRuntime(8824): at android.location.LocationManager.requestLocationUpdates(LocationManager.java:446)
ERROR/AndroidRuntime(8824): at de.theapplication.GeoFixer.getNetworkLocation(GeoFixer.java:64)
ERROR/AndroidRuntime(8824): at de.theapplication.GeoFixer.startLocationObserver(GeoFixer.java:27)
ERROR/AndroidRuntime(8824): at de.theapplication.Fadenzieher$1.run(Fadenzieher.java:36)

3 个答案:

答案 0 :(得分:0)

通过在Google上的快速搜索,工作线程似乎没有与之关联的Looper,因此您的Runnable可能会尝试在无法处理它们的线程上发布消息。尝试将相同的Runnable发布到UI线程,看看是否仍然出现错误。

来源:

Can't create handler inside thread which has not called Looper.prepare()

答案 1 :(得分:0)

查看堆栈跟踪,看起来您的startLocationObserver()方法调用了LocationManager的requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)方法(没有Looper参数的方法)。

查看是否可以使用Looper参数调用requestLocationUpdates()版本,并传递Looper.getMainLooper()

或者,请参阅此blog post,其中解决方案是调用Looper.myLooper().prepare()

答案 2 :(得分:0)

onStartCommand()(主/ UI线程)中获取对LocationService的引用,并将其传递给您的线程。

为什么你不想使用IntentService?它负责在单独的线程上运行代码,并在完成后自行关闭。