Android 从onPostExecute()更新地图标记位置,旋转设备时应用程序崩溃
我的地图应用程序使用AsynTtask不断地从服务器获取位置数据,并使用handler(每10秒)重复执行。要更新标记位置,我正在使用onPostExecute()。但该应用程序正在旋转设备时崩溃。据我所知,这是因为MainActivity参考已不存在,那么解决方案/最佳实践是什么?? (我正在实现从主活动运行onPostExecute()的接口) 这是半个代码,如果需要更多日志/代码,请告诉我。谢谢 MainActivity.javaAndroid 从onPostExecute()更新地图标记位置,旋转设备时应用程序崩溃,android,android-asynctask,Android,Android Asynctask,我的地图应用程序使用AsynTtask不断地从服务器获取位置数据,并使用handler(每10秒)重复执行。要更新标记位置,我正在使用onPostExecute()。但该应用程序正在旋转设备时崩溃。据我所知,这是因为MainActivity参考已不存在,那么解决方案/最佳实践是什么?? (我正在实现从主活动运行onPostExecute()的接口) 这是半个代码,如果需要更多日志/代码,请告诉我。谢谢 MainActivity.java public class MainActivity ext
public class MainActivity extends Activity implements
OnMapReadyCallback,
TrackLocationTask.AsyncMarkerUpdate {
protected Marker mMarker;
protected Boolean mRequestingLocationUpdates;
protected MapFragment mapFragment;
private Handler mHandler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mHandler = new Handler();
startTrackDevice();
}
Runnable mStatusChecker = new Runnable() {
@Override
public void run() {
String appServerUrl = getResources().getString(R.string.hostname)
+"/track.php?uuid="
+android_id;
TrackLocationTask track = new TrackLocationTask();
track.delegate= MainActivity.this;
track.execute(appServerUrl);
mHandler.postDelayed(mStatusChecker, 10000);
}
};
private void startTrackDevice() {
mStatusChecker.run();
}
public void updateMarker(String result) {
String[] results = result.split(";");
float lat = Float.parseFloat(results[0]);
float lng = Float.parseFloat(results[1]);
mMarker.setPosition(new LatLng(lat,lng));
mapFragment.getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(lat, lng), 18));
}
public class TrackLocationTask extends AsyncTask<String, String, String> {
public interface AsyncMarkerUpdate {
public void updateMarker(String result);
}
public AsyncMarkerUpdate delegate=null;
@Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String locationString = "response";
try {
// bla bla code to handle response and setting result
} else{
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return locationString;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(delegate!=null)
delegate.updateMarker(result);
}
TrackLocationTask.java
public class MainActivity extends Activity implements
OnMapReadyCallback,
TrackLocationTask.AsyncMarkerUpdate {
protected Marker mMarker;
protected Boolean mRequestingLocationUpdates;
protected MapFragment mapFragment;
private Handler mHandler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mHandler = new Handler();
startTrackDevice();
}
Runnable mStatusChecker = new Runnable() {
@Override
public void run() {
String appServerUrl = getResources().getString(R.string.hostname)
+"/track.php?uuid="
+android_id;
TrackLocationTask track = new TrackLocationTask();
track.delegate= MainActivity.this;
track.execute(appServerUrl);
mHandler.postDelayed(mStatusChecker, 10000);
}
};
private void startTrackDevice() {
mStatusChecker.run();
}
public void updateMarker(String result) {
String[] results = result.split(";");
float lat = Float.parseFloat(results[0]);
float lng = Float.parseFloat(results[1]);
mMarker.setPosition(new LatLng(lat,lng));
mapFragment.getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(lat, lng), 18));
}
public class TrackLocationTask extends AsyncTask<String, String, String> {
public interface AsyncMarkerUpdate {
public void updateMarker(String result);
}
public AsyncMarkerUpdate delegate=null;
@Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String locationString = "response";
try {
// bla bla code to handle response and setting result
} else{
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return locationString;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(delegate!=null)
delegate.updateMarker(result);
}
它可能会崩溃,因为您正试图在后台线程中更新UI。尝试:
runOnUiThread(new Runnable(){
public void run() {
// UI code goes here
}
});
其他选择是:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
// UI code goes here
}
});
应用程序崩溃,因为在旋转后,您有两个MainActivity实例。在类TrackLocationTask中,您对MainActivity有硬引用。因此,启动了两个TrackLocationTask任务。要从第一个MainActivity运行方法updateMarker的第一个任务whant。此活动已被破坏,因此将崩溃。 你应该做什么: 您可以在onPostExecute中的TrackLocationTask中将委托引用设置为null,并取消onDestroy()的任务
以上是对您的代码的修改。更好的做法是扩展应用程序类。您可以在应用程序上下文中执行长操作。可以使用EventBus将结果发送到片段/活动 我正在更新onPostExecute()上的ui,在设备方向没有改变之前,它可以正常工作。没有,它仍然在崩溃。您能提供任何参考链接吗?这是用来发送消息的。扩展应用程序类。