Android:在onPostExecute之后获取null值

时间:2012-09-20 17:11:39

标签: android json android-asynctask

这个问题是我上一个问题的延续。链接是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

}

1 个答案:

答案 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
    }