引起:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序

时间:2014-02-06 10:24:26

标签: android android-asynctask intentservice locationlistener

我正在编写一个程序,每隔5分钟取出用户当前的纬度和经度。我正在使用AlarmManager,我想运行程序后台,所以我使用IntentService。但是在执行程序时会发生以下错误:

logcat的

02-06 15:40:03.101: W/dalvikvm(17499): threadid=12: thread exiting with uncaught exception (group=0x4203c2a0)
02-06 15:40:03.109: E/AndroidRuntime(17499): java.lang.RuntimeException: An error occured while executing doInBackground()
02-06 15:40:03.109: E/AndroidRuntime(17499):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at java.lang.Thread.run(Thread.java:856)
02-06 15:40:03.109: E/AndroidRuntime(17499): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
02-06 15:40:03.109: E/AndroidRuntime(17499):    at android.os.Handler.<init>(Handler.java:121)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:180)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:180)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at android.location.LocationManager._requestLocationUpdates(LocationManager.java:657)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at android.location.LocationManager.requestLocationUpdates(LocationManager.java:482)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at com.gpsshoppe.LocationFinder$CurrentLocatioFinder.doInBackground(LocationFinder.java:58)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at com.gpsshoppe.LocationFinder$CurrentLocatioFinder.doInBackground(LocationFinder.java:1)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-06 15:40:03.109: E/AndroidRuntime(17499):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-06 15:40:03.109: E/AndroidRuntime(17499):    ... 5 more

这是我的班级

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.android.gms.maps.model.LatLng;

public class LocationFinder extends IntentService {
    private Context mcontext;
    SharedPreferences shprefs;


    public LocationFinder() {
        super("LocationFinder");
        this.mcontext=this;

        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // TODO Auto-generated method stub
        CurrentLocatioFinder lFinder=new CurrentLocatioFinder();
        lFinder.execute();

    }
public class CurrentLocatioFinder extends AsyncTask<String, String, String> implements LocationListener{


    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub

        LocationManager locationManager = (LocationManager) mcontext.getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);

        return null;
    }

    @Override
    public void onLocationChanged(Location location) {
        // TODO Auto-generated method stub
        if(location!=null){
        shprefs=PreferenceManager.getDefaultSharedPreferences(LocationFinder.this);


        double latitude=location.getLatitude();
        Log.i("Inside cLocation", ""+latitude);

        Editor edit=shprefs.edit();  
        edit.putString("Ltd", ""+latitude);
        edit.commit();

        double longitude=location.getLongitude();

        edit.putString("Lngtd", ""+longitude);
        edit.commit();
        LatLng lng=new LatLng(latitude,longitude);
        Log.i("LatLng", ""+lng);

        }
    }

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

    }

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

    }

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

    }
  } 

}

3 个答案:

答案 0 :(得分:0)

您已在AsyncTask实现中为locationservice定义了回调处理程序。处理程序将在创建它的线程中执行,因此在您的情况下,需要从您无法执行的AsyncTask线程执行位置回调。我建议你将locationservice处理程序移动到你的主线程。 让LocationFinder实现LocationListener接口。

答案 1 :(得分:0)

我只是编辑你的课程试试希望这对你有用

public class LocationFinder extends IntentService {
    private Context mcontext;
    SharedPreferences shprefs;

    public LocationFinder() {
        super("LocationFinder");
        this.mcontext = this;

        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        CurrentLocatioFinder mCurrentLocatioFinder = new CurrentLocatioFinder();
        mCurrentLocatioFinder.attach();

    }

    public class CurrentLocatioFinder implements LocationListener {
        LocationManager locationManager;

        public void attach() {
            locationManager = (LocationManager) mcontext.getSystemService(Context.LOCATION_SERVICE);
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
        }

        @Override
        public void onLocationChanged(Location location) {
            // TODO Auto-generated method stub
            if (location != null) {
                shprefs = PreferenceManager.getDefaultSharedPreferences(LocationFinder.this);

                double latitude = location.getLatitude();
                Log.i("Inside cLocation", "" + latitude);

                Editor edit = shprefs.edit();
                edit.putString("Ltd", "" + latitude);
                edit.commit();

                double longitude = location.getLongitude();

                edit.putString("Lngtd", "" + longitude);
                edit.commit();
                LatLng lng = new LatLng(latitude, longitude);
                Log.i("LatLng", "" + lng);

            }
        }

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

        }

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

        }

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

        }
    }

}

答案 2 :(得分:0)

你不能在onHandleIntent中创建AsyncTask,因为它是一个后台线程。

我的建议是忘记IntentService,因为在这种情况下它没有任何添加。您可以直接启动AsyncTask,无需将其包装在IntentService中。

但是,如果你真的想要一个关心位置处理的服务,那么你可以对服务做同样的事情,因为它的onStartCommand方法在主线程中运行。