2012-09-20 24 views
0

這個問題是我之前的問題的延續。鏈接是https://stackoverflow.com/questions/12499941/android-getting-wrong-info-on-parsing-json-data#comment16829891_12499941 我面臨的問題是,在異步任務doInBackground中,我能夠將數據放在NearLocation []中。然後,我將這個數組傳遞給onPostExecute()。我在那裏打印了NearLocation []中的數據,它給了我結果,無論它在數組中。這個數組,我在SitesOverlay類中使用。另外,我在onCreate中使用這個數組來檢查它是否包含值。如果不是,它應該給我一個警告消息。當我運行我的應用程序時,它顯示NearLocation []爲空,並提醒我。但是,在那個時候值在數組中,我在onPostExecute中檢查了相同的值。現在,我不理解數組如何在onPostExecute()中有值時變爲null。沒有,我做錯了什麼。我嘗試了很多,但都找不到解決方案。我在下面發佈我的更新代碼以及。Android:在onPostExecute後獲得空值

Activity類

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

我不知道我知道你有這個問題,但這裏有一些問題,你的代碼,看看他們解決問題。他們設置代碼的方式(特別是AsyncTask)可能在某些情況下有效,但在大多數情況下會失敗。在onCreate方法中,您將實例化任務,然後調用​​來啓動它。此時onCreate方法中的代碼將繼續運行(並且任務將執行相同操作),但由於任務很可能尚未完成數據獲取,因此nearlocations陣列將爲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 
    } 
+0

謝謝,它爲我工作。但是,我想知道在哪種情況下我們應該使用回調系統,因爲我不清楚這些概念。 – Nitish

+1

@Nitish當一個特定的事件發生時(如數據加載完成,用戶點擊),當你需要完成一個操作(創建視圖,更新視圖,填充數據,顯示通知等)時,通常會使用這個回調系統東西等),就像一個聽衆。 – Luksprog

相關問題