问题
I want to create a background thread (execute even if my activity dies) that update my data location et send it to my server with an http resquest. But it occurs an exception:
02-01 07:50:18.172: ERROR/Exception1(277): Can't create handler inside thread that has not called Looper.prepare()
My code:
public class Messagerie extends Activity {
private LocationManager locationManager;
private String locationProvider = LocationManager.NETWORK_PROVIDER;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.messagerie);
new UpdateLocation().execute();
}
public void majCoordonnes() {
StringBuilder stringBuilder = new StringBuilder("Fournisseur :");
stringBuilder.append("\n");
stringBuilder.append(locationProvider);
stringBuilder.append(" : ");
Location location = locationManager.getLastKnownLocation(locationProvider);
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
String lat = String.valueOf(latitude);
String lon = String.valueOf(longitude);
stringBuilder.append(latitude);
stringBuilder.append(", ");
stringBuilder.append(longitude);
//Send location to server in an AsyncTask
new sendLocation().execute(lat, lon);
} else {
stringBuilder.append("Non déterminée");
}
Log.d("MaPositionMaj", stringBuilder.toString());
}
/**
* Ecouteur utilisé pour les mises à jour des coordonnées
*/
class MajListener implements android.location.LocationListener {
public void onLocationChanged(Location location) {
majCoordonnes();
}
public void onProviderDisabled(String provider){
}
public void onProviderEnabled(String provider){
}
public void onStatusChanged(String provider, int status, Bundle extras){
}
};
//Requête GET, mise à jour des infos
private class UpdateLocation extends AsyncTask<String, Void, String> {
String resp;
@Override
protected String doInBackground(String... params) {
try {
//Recuperation Location
String locationContext = Context.LOCATION_SERVICE;
locationManager = (LocationManager) getSystemService(locationContext);
if (locationManager != null && locationProvider != null) {
majCoordonnes();
locationManager.requestLocationUpdates(locationProvider, 120000, 500, new MajListener());
}
} catch (Exception e){
Log.e("Exception1", e.getMessage());
}
return resp;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected void onPreExecute() {
// Things to be done before execution of long running operation. For example showing ProgessDialog
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
EDIT: I think I have to use a Service instead of an asyncTask.
回答1:
EDIT: I think I have to use a Service instead of an asyncTask.
Precisely. Creating a separate thread will not ensure that it is not killed when the application / activity exits, or when the operating system needs more resources. A Service
doesn't ensure that either -- it may still be killed if the system is under really heavy load, but it's much less likely. Also (correct me if I'm wrong), Android will restart the Service once the system load softens.
回答2:
Just call (write it down in your code) Looper.prepare()
, before you run your Thread
. (It's a simple solution, but previously made me weird too.)
If you can't call the Handler
which is in your Activity
, then firstly, you should make your activity constructor, for example :
public SampleActivity() {
super();
// TODO Auto-generated constructor stub
}
then in your ASyncTask
, initiate that Activity
:
SampleActivity sampleAct = new SampleActivity();
and the final kick is call your Handler
.
sampleAct.handler.sendMessage(msg);
I hope this clearly explains it to you.
来源:https://stackoverflow.com/questions/4860404/cant-call-handler-in-an-asynctask