0

この質問は私の前の質問の続きです。リンクはhttps://stackoverflow.com/questions/12499941/android-getting-wrong-info-on-parsing-json-data#comment16829891_12499941です 私が直面している問題は、非同期タスクの doInBackground で、NearLocation[] にデータを配置できることです。次に、この配列を onPostExecute() に渡しました。そこで、データを NearLocation[] に出力すると、配列に含まれていた結果が得られました。この配列は、SitesOverlay クラスで使用しています。また、アクティビティの onCreate でこの配列を使用して、値が含まれているかどうかを確認しています。そうでない場合は、警告メッセージが表示されます。アプリを実行すると、NearLocation[] が null であることが示され、アラートが表示されました。しかし、その時点で配列に値があったので、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

}
4

1 に答える 1

1

あなたの問題を理解しているかどうかはわかりませんが、コードにいくつかの問題があります。問題が解決するかどうかを確認してください。コード(特にAsyncTask)をセットアップする方法は、場合によっては機能する可能性がありますが、ほとんどの場合は失敗します。メソッドではonCreate、タスクをインスタンス化し、呼び出しexecute()て開始します。この時点で、onCreateメソッド内のコードは引き続き実行されます (タスクも同じように実行されます) が、タスクがデータの取得を完了していない可能性が高いため、nearlocations配列はnull. nearLocationsしたがって、問題は、タスクがデータの取得を完了するのを待たずに、null変数を使用してしまうことです。これを回避する 1 つの方法は、コールバック システムを使用することです。以下に例を示します。

// 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
    }
于 2012-09-20T17:59:15.870 に答える