Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从onPostExecute()更新地图标记位置,旋转设备时应用程序崩溃_Android_Android Asynctask - Fatal编程技术网

Android 从onPostExecute()更新地图标记位置,旋转设备时应用程序崩溃

Android 从onPostExecute()更新地图标记位置,旋转设备时应用程序崩溃,android,android-asynctask,Android,Android Asynctask,我的地图应用程序使用AsynTtask不断地从服务器获取位置数据,并使用handler(每10秒)重复执行。要更新标记位置,我正在使用onPostExecute()。但该应用程序正在旋转设备时崩溃。据我所知,这是因为MainActivity参考已不存在,那么解决方案/最佳实践是什么?? (我正在实现从主活动运行onPostExecute()的接口) 这是半个代码,如果需要更多日志/代码,请告诉我。谢谢 MainActivity.java public class MainActivity ext

我的地图应用程序使用AsynTtask不断地从服务器获取位置数据,并使用handler(每10秒)重复执行。要更新标记位置,我正在使用onPostExecute()。但该应用程序正在旋转设备时崩溃。据我所知,这是因为MainActivity参考已不存在,那么解决方案/最佳实践是什么?? (我正在实现从主活动运行onPostExecute()的接口) 这是半个代码,如果需要更多日志/代码,请告诉我。谢谢

MainActivity.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);
}
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,在设备方向没有改变之前,它可以正常工作。没有,它仍然在崩溃。您能提供任何参考链接吗?这是用来发送消息的。扩展应用程序类。