这个问题是我上一个问题的延续。链接是https://stackoverflow.com/questions/12499941/android-getting-wrong-info-on-parsing-json-data#comment16829891_12499941 我面临的问题是,在异步任务的doInBackground中,我能够将数据放入NearLocation []。然后,我将此数组传递给onPostExecute()。在那里我打印了NearLocation []中的数据,它给了我结果,无论它在数组中有什么。这个数组,我在SitesOverlay类中使用。另外,我在onCreate of activity中使用此数组来检查它是否包含值。如果没有,它应该给我一个警告信息。当我运行我的应用程序时,它显示NearLocation []为空并给了我警报。但是,当时数组中存在值,我在onPostExecute中检查了相同的值。现在,我不理解,当数组在onPostExecute()中具有值时,数组如何变为null。是的,我做错了什么。我经常尝试和搜索,但无法提出解决方案。我在下面发布我的更新代码。
活动类
public class TrackDriverActivity extends MapActivity {
Button btnCurrLoc;
EditText txtPickAddress;
MapView map;
MapController mc;
GeoPoint p;
boolean foundValidLocation = true;
public NearLocation[] nearLocations;
public String driverLatitude;
public String driverLongitude;
private MyLocationOverlay me=null;
private static final String TAG = "TrackDriverActivity";
String tripstatus;
/**
* Nitish
* Tue 11 Sep 2012 06:57 PM
* */
private final String url = "http://towncarapp.com/android/near_driver.php?email="+ UserProfile.email;
JSONObject jsonObject;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.trackdriver);
Log.v(TAG,"Inside Pick Location Activity");
new LoadDriverDetailsAsyncTask(TrackDriverActivity.this, url).execute();
map = (MapView) findViewById(R.id.mapLocation);
if(nearLocations!=null && nearLocations.length !=0)
{
for(int i = 0; i < nearLocations.length; i++)
{
NearLocation driverLocation = nearLocations[i];
driverLatitude = driverLocation.lat;
driverLatitude = driverLocation.lon;
Log.d(TAG, "Latitude = " +driverLatitude);
Log.d(TAG, "Latitude = " +driverLongitude);
}//for
Log.d(TAG, "onCreate nearLocation if");
}//if
else
{
TownCarDialogManager.showOkOnlyDialog(TrackDriverActivity.this, "Message", "No Driver assigned yet.");
map.getController().setCenter(getPoint(39.83,-98.58));
map.setBuiltInZoomControls(true);
Log.d(TAG, "onCreate nearLocation else");
}//else
// First Get the current location
Location currentLocation = getCurrentLocation();
Log.v(TAG,"Till Current Location");
if (currentLocation != null)
{
map.getController().setCenter(getPoint(currentLocation.getLatitude(), currentLocation.getLongitude()));
Drawable marker=getResources().getDrawable(R.drawable.marker);
marker.setBounds(0, 0, marker.getIntrinsicWidth(),
marker.getIntrinsicHeight());
try {
map.getOverlays().add(new SitesOverlay(marker, getPoint(currentLocation.getLatitude(), currentLocation.getLongitude())));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
map.invalidate();
}//if
else
{
Log.v("","No Current Location Found");
}//else
Drawable marker=getResources().getDrawable(R.drawable.marker2); //Driver Marker
marker.setBounds(0, 0, marker.getIntrinsicWidth(),
marker.getIntrinsicHeight());
try {
map.getOverlays().add(new SitesOverlay(marker, null));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
map.getController().setZoom(17);
map.setBuiltInZoomControls(true);
map.invalidate();
/***/
if (nearLocations == null || nearLocations.length <= 0)
{
//showDialog("Sorry!!!","No driver has been assigned yet.",this);
TownCarDialogManager.showOkOnlyPostProcessingDialog(TrackDriverActivity.this, "Message", "No Driver assigned yet.", 3);
map.getController().setCenter(getPoint(39.83,-98.58));
//map.getController().zoomToSpan(Integer.parseInt(nearLocations[0].lat),Integer.parseInt(nearLocations[0].lon));
map.setBuiltInZoomControls(true);
}//if
}//onCreate
@Override
protected boolean isRouteDisplayed()
{
// TODO Auto-generated method stub
return false;
}//isRouteDisplayed
public Location getCurrentLocation()
{
LocationManager locationManager = (LocationManager) TrackDriverActivity.this.getSystemService(Context.LOCATION_SERVICE);
Criteria locCriteria = new Criteria();
locCriteria.setAccuracy(Criteria.ACCURACY_FINE);
Location lastLocation = locationManager.getLastKnownLocation(locationManager.getBestProvider(locCriteria, true));
return lastLocation;
}//getCurrentLocation
public String getCurrentLocationAddess()
{
Location currentLocation = getCurrentLocation();
String addressString = null;
if(currentLocation!=null)
{
Geocoder gc = new Geocoder(TrackDriverActivity.this, Locale.getDefault());
try
{
List<Address> addresses = gc.getFromLocation(currentLocation.getLatitude(), currentLocation.getLongitude(), 1);
StringBuilder sb = new StringBuilder();
if (addresses.size() > 0)
{
Address address = addresses.get(0);
for (int i = 0; i < address.getMaxAddressLineIndex(); i++)
sb.append(address.getAddressLine(i)).append("\n");
sb.append(address.getCountryName());
}//if
addressString = sb.toString();
}//try
catch (IOException e)
{
Log.v("SelectPickupLocation","getCurrentLocationAddress::IOException ");
}//catch
}//if
return addressString;
}//getCurrentLocationAddress
private double getDouble(String dbl){
Double d;
try{
d = Double.valueOf(dbl);
} catch (Exception e) {
return 0;
}
System.out.println("***"+d);
return d.doubleValue();
}
private GeoPoint getPoint(double lat, double lon) {
return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0)));
}
private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
private List<OverlayItem> items = new ArrayList<OverlayItem>();
public SitesOverlay(Drawable marker, GeoPoint center) throws InterruptedException, ExecutionException {
super(marker);
boundCenterBottom(marker);
if (center != null){
items.add(new OverlayItem(center, "" , ""+getCurrentLocationAddess()));
} else {
//nearLocations = getNearLocations(jsonObject);
if (nearLocations != null && nearLocations.length > 0 ) {
Log.v("","+"+nearLocations.length);
for (int i = 0; i < nearLocations.length; i++){
NearLocation loc = nearLocations[i];
Log.v(TAG,"*"+loc.lat+"*"+loc.lon);
items.add(new OverlayItem(getPoint(getDouble(driverLatitude), getDouble(driverLongitude)),"", "Driver Location"));
}
}
}
populate();
}
@Override
protected OverlayItem createItem(int i) {
return (items.get(i));
}
@Override
protected boolean onTap(int i) {
Toast.makeText(TrackDriverActivity.this, items.get(i).getSnippet(),
Toast.LENGTH_SHORT).show();
return (true);
}
@Override
public int size() {
return (items.size());
}
}
private class LoadDriverDetailsAsyncTask extends AsyncTask<String, Void, NearLocation[]>
{
private ProgressDialog pd;
Context ctx;
String url;
public LoadDriverDetailsAsyncTask(Context ctx, String url)
{
this.ctx = ctx;
this.url = url;
}//Constructor
protected void onPreExecute()
{
super.onPreExecute();
pd=new ProgressDialog(ctx);
pd.setMessage("Please Wait...");
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
}//onPreExecute
protected NearLocation[] doInBackground(String... params)
{
JSONObject jObject = JSONParser.getJSONObjectDataFromURL(url);
nearLocations = getNearLocations(jObject);
return nearLocations;
}//doInBackground
protected void onPostExecute(NearLocation[] nearLocations)
{
for(int i = 0; i < nearLocations.length; i++){
NearLocation loc = nearLocations[i];
Log.d("LoadDriverAsyncTaskDriverlATITUDE", loc.lat);
Log.d("LoadDriverAsyncTaskDriverlongitude", loc.lon);
}
pd.dismiss();
}//onPostExecute
}//LoadMapAsyncTask
public NearLocation[] getNearLocations(JSONObject jObject)
{
NearLocation[] nearLocation = null;
try
{
if(jObject!=null)
{
JSONArray jsonArray = jObject.getJSONArray("statement");
if (jsonArray != null)
{
nearLocation = new NearLocation[jsonArray.length()];
Log.v(TAG, "::::::&&&&&&&&&&&&&::::::NearLocations "
+ nearLocation.length);
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject e = jsonArray.getJSONObject(i);
NearLocation loc = new NearLocation(
e.getString("latitude"),
e.getString("longitude"));
nearLocation[i] = loc;
Log.v("Driver latitude:", loc.lat);
Log.v("Driver longitude:", loc.lon);
}//for
}//if
}//if
else
{
TownCarDialogManager.showOkOnlyDialog(TrackDriverActivity.this, "Sorry", "There is problem in internet connection");
}//else
}//try
catch (JSONException e)
{
e.printStackTrace();
}//catch
return nearLocation;
}//getNearLocations
}
答案 0 :(得分:1)
我不确定我是否理解您遇到的问题,但是您的代码存在一些问题,看看他们是否解决了问题。他们设置代码的方式(尤其是AsyncTask
)在某些情况下可能会起作用,但在大多数情况下都会失败。在onCreate
方法中,您实例化任务,然后调用execute()
启动它。此时,onCreate
方法中的代码将继续运行(并且任务将执行相同的操作),但由于任务很可能尚未完成获取数据,nearlocations
数组将是null
。所以问题是你不要等到让任务完成数据的获取,所以你最终使用了null nearLocations
变量。避免这种情况的一种方法是使用回调系统。以下是一个例子:
// this is an interface that the TrackDriverActivity will implement
interface OnLoadDriverDetails {
onLoadDriverDetails(NearLocation[] data);
}
当完成加载数据时,将从AsyncTask
调用此回调:
private class LoadDriverDetailsAsyncTask extends AsyncTask<String, Void, NearLocation[]> {
OnLoadDriverDetails mListener;
public LoadDriverDetailsAsyncTask(Context ctx, String url) {
this.ctx = ctx;
this.url = url;
mListener = (OnLoadDriverDetails) ctx;
}
protected NearLocation[] doInBackground(String... params) {
JSONObject jObject = JSONParser.getJSONObjectDataFromURL(url);
return getNearLocations(jObject);
}
protected void onPostExecute(NearLocation[] nearLocations) {
mListener.onLoadDriverDetails(newrLocations);
}
// the rest of the task's code
在活动中,您将移动onCreate
中需要nearLocations
回调中有效onLoadDriverDetails
数组的代码:
public class TrackDriverActivity extends MapActivity implements OnLoadDriverDetails {
// ...
public void onLoadDriverDetails(NearLocation[] data) {
nearLocations = data;
// here do the things you do in the onCreate method like setting those SitesOverlay items on the map
}