2017-04-02 74 views
1

這個問題困擾了我很長一段時間。我使用了一個名爲bmob的雲數據庫,並且我發現我可以成功獲取我想要的數據。但是,循環中可能會出現一些錯誤,我只能得到最後選擇的項目的信息。Android的東西有錯誤的循環 - 不能把值放入哈希映射

p.s.我使用一個名爲Playlist的數組列表來存儲我將用於在下一個活動中顯示列表視圖的計算數據。

這裏是我的代碼:

public class DestinationActivity extends Activity implements OnClickListener, NumberPicker.OnValueChangeListener { 

private TextView from_place, date, days, start_time, end_time, number, money_view; 
private Button addButton, subButton; 
private ImageView backButton, telephone; 
private ListView listView; 
private Button destinationOk_btn; 
private ShapeLoadingDialog shapeLoadingDialog; 

private Tip startTip; 

private Calendar calendar; 
private DatePickerDialog dialog; 
private TimePickerDialog dialog2; 

private List<Destination> destinationList = new ArrayList<Destination>(); 


private DestinationAdapter adapter; 

private int number_value = 1; 

private String time_start; 
private String time_end; 
private int travel_days; 
double travelTime;//total playing time 
double travel_time; 
private int money; 
private int num = 1; 


private ArrayList<Integer> select_placeID = new ArrayList<Integer>(); 
public Map<Integer,Double> weightMap; 
public List<Plan> planList = new ArrayList<Plan>(); 
int[] selectedID = new int[10]; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.destination_layout); 

    //initialize the cloud database 
    Bmob.initialize(this, BmobConfig.APP_ID); 

    listView = (ListView) findViewById(R.id.list_destination); 

    destinationOk_btn = (Button) findViewById(R.id.okButton); 


    initDestinations(); // initialize the data 


    adapter = new DestinationAdapter(destinationList, DestinationActivity.this); 
    //adapter = new DestinationAdapter(this, destinationList, DestinationAdapter.getIsSelected()); 
    listView.setAdapter(adapter); 

    //....listeners and textviews....... 

    //submit button 
    destinationOk_btn.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      select_placeID.clear(); 

      for (int i = 0; i < destinationList.size(); i++) { 
       if (DestinationAdapter.getIsSelected().get(i)) { 
        select_placeID.add((i + 1)); 
       } 

      } 

      //change to int array 
      selectedID = new int[select_placeID.size()]; 
      for(int i = 0;i<select_placeID.size();i++){ 
       selectedID[i] = select_placeID.get(i); 
      } 

      if (select_placeID.size() == 0) { 
       AlertDialog.Builder builder1 = new AlertDialog.Builder(DestinationActivity.this); 
       builder1.setMessage("no records"); 
       builder1.show(); 
      } 
      else { 
       AlertDialog.Builder builder = new AlertDialog.Builder(DestinationActivity.this); 

       builder.setMessage("waiting for magic..."); 
       builder.show(); 

       /** 
       * calculate the route 
       */ 
       if (validate()) { 
        new calRoute().execute(); 
       } 


      } 
     } 

    }); 
} 



//initialize the data 
private void initDestinations() { 
    //........ 
} 


@Override 
public void onClick(View v) { 
    //....... 
} 


/** 
* asynctask 
*/ 
private class calRoute extends AsyncTask<Void, Void, List<Plan>>{ 


    public calRoute(){ 
     // TODO Auto-generated constructor stub 
    } 


    @Override 
    protected List<Plan> doInBackground(Void... params) { 

     List<Plan> result = calculate(time_start, time_end, travel_days); 

     return result; 
    } 


    @Override 
    protected void onPostExecute(List<Plan> result) { 
     super.onPostExecute(result); 
     if (result != null) { 
      Toast.makeText(DestinationActivity.this, "success", Toast.LENGTH_SHORT).show(); 

      if(planList.size() > 0) { 


       Intent intent = new Intent(); 
       intent.setClass(DestinationActivity.this, ActivityPlan.class); 

       intent.putParcelableArrayListExtra("planInfo", (ArrayList<? extends Parcelable>) planList); 

       startActivity(intent); 
      } 

      else{ 
       Toast.makeText(DestinationActivity.this, "no plan", Toast.LENGTH_SHORT).show(); 
      } 
     } 

    } 
} 


/** 
*plan 
**/ 
public List<Plan> calculate(String time_start, String time_end, int travel_days) { 


    SimpleDateFormat df = new SimpleDateFormat(("HH:mm")); 

    Date starttime = new Date(); 
    Date endtime = new Date(); 
    try { 
     starttime = df.parse(time_start); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 
    try { 
     endtime = df.parse(time_end); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 

    double l = endtime.getTime() - starttime.getTime(); 
    double hour = (l/(60 * 60 * 1000)); 
    double min = ((l/(60 * 1000)) - hour * 60); 

    if(min == 0){ 
     min = 60; 
    } 
    else { 
     travel_time = ((1.0 * travel_days * hour) * (min/60)); 
     DecimalFormat decimalFormat = new DecimalFormat("#.0"); 
     travelTime = Double.parseDouble(decimalFormat.format(travel_time)); 
    } 


    weightMap = new LinkedHashMap<Integer, Double>(); //store weight 
    int totalPriority = 0;//total priority 

    final Destination start = new Destination(116.32133, 39.92269); 


    final HashMap<Integer, Integer> pMap = new HashMap<Integer, Integer>(); 
    final HashMap<Integer, String> nameMap = new HashMap<Integer, String>(); 
    final HashMap<Integer, Destination> objectMap = new LinkedHashMap<Integer, Destination>(); 
    /** 
    * get the data from cloud database 
    */ 
      BmobQuery<Destination> query = new BmobQuery<Destination>(); 
      for (int sid: selectedID) { 

       query.addWhereEqualTo("id", sid); 


       query.findObjects(new FindListener<Destination>() { 

        @Override 
        public void done(List<Destination> list, BmobException e) { 
         if (e == null) { 
          System.out.println("success:total" + list.size() + "items。"); 
          for (Destination destination : list) { 


           int p = destination.getPriority(); 

           int id = destination.getId(); 

           String name = destination.getName(); 

           double longitude = destination.getLongitude(); 
           double latitude = destination.getLatitude(); 

           objectMap.put(id, new Destination(longitude, latitude)); 

           System.out.println(id); 


           double dis = DistanceUtil.distance(start.getLongitude(), start.getLatitude(), 
             longitude, latitude); 

           pMap.put(id, p); 
           weightMap.put(id, new Double(dis)); 
           nameMap.put(id, name); 

          } 
         } else { 
          Log.i("bmob", "error:" + e.getMessage() + "," + e.getErrorCode()); 
         } 
        } 
       }); 
      } 


    for (Integer key : pMap.keySet()) { 
     int p = pMap.get(key).intValue(); 
     totalPriority = totalPriority + p; 
    } 


    double weight = 0.0; 
    for (Map.Entry<Integer, Double> hm : weightMap.entrySet()) { 
     double hm2Value = pMap.get(hm.getKey()); 
     weight = totalPriority/hm.getValue() * hm2Value; 

     weightMap.put(hm.getKey(), weight); 
    } 


    /** 
    * 按照weight值來排序 
    * 判斷是否傳遞數據給plan_activity 
    */ 
    MapUtil.sortByValue(weightMap); 

    //排好序後計算距離 
    Iterator it = weightMap.entrySet().iterator(); 
    int order = 0; 
    while (it.hasNext()) { 
     order++; 
     Map.Entry entry = (Map.Entry) it.next(); 
     objectMap.put(new Integer(order), objectMap.get(entry.getKey())); 
    } 


    PlanTask planTask = new PlanTask();//封裝了每個plan計算的方法 


    for (Map.Entry<Integer, Double> entry : weightMap.entrySet()) { 
     System.out.println("id= " + entry.getKey()); 


     double play_time = planTask.calPlay_time(weightMap.size(), 
       weightMap.get(entry.getKey()), travelTime); 

     double driving_time = planTask.calDrive_time(DistanceUtil.distance(
       objectMap.get(entry.getKey()).getLatitude(), 
       objectMap.get(entry.getKey()).getLongitude(), 
       objectMap.get(entry.getKey() + 1).getLatitude(), 
       objectMap.get(entry.getKey() + 1).getLongitude() 
     )); 

     String arrive_time = "hello world";//未完待續 

     String place_name = nameMap.get(entry.getKey()); 

     Plan plan = new Plan(place_name, arrive_time, driving_time, play_time); 

     //傳遞plan對象list 
     planList.add(entry.getKey(), plan); 
    } 

    return planList; 

} 

}

當我調試它,我發現,在計算()函數的

BmobQuery<Destination> query = new BmobQuery<Destination>(); 
      for (int sid: selectedID) { 

       query.addWhereEqualTo("id", sid); 


query.findObjects(new FindListener<Destination>() { 

        @Override 
        public void done(List<Destination> list, BmobException e) { 
         if (e == null) { 
          System.out.println("success:total" + list.size() + "items。"); 
          for (Destination destination : list) { 

           int p = destination.getPriority(); 

           int id = destination.getId(); 

           String name = destination.getName(); 


           double longitude = destination.getLongitude(); 
           double latitude = destination.getLatitude(); 

           objectMap.put(id, new Destination(longitude, latitude)); 

           System.out.println(id); 

           //calculate the distance 
           double dis = DistanceUtil.distance(start.getLongitude(), start.getLatitude(), 
             longitude, latitude); 

           pMap.put(id, p); 
           weightMap.put(id, new Double(dis)); 
           nameMap.put(id, name); 

          } 
         } else { 
          Log.i("bmob", "error:" + e.getMessage() + "," + e.getErrorCode()); 
         } 
        } 
       }); 

輸出爲「成功:總1項。「並且在循環之後,如果我已經選擇了3個項目,那將是「成功:總共1項」。 3次,只有最後一個項目的信息被捕獲。 AND三個哈希映射的大小:pMap,nameMap和objectMap都是零。爲什麼???這很奇怪......

LogCAT中沒有錯誤,但是,有序的列表視圖不能顯示在第二個活動中。請幫助我,它困擾了我很長一段時間。 謝謝!!!

回答

0

我想不出太多不幸的是,因爲我真的不舒服的反應式編程但作爲平臺使用了大量的一般rxjava的,但這裏的東西,將提高代碼有點

final HashMap<Integer, Integer> pMap = new HashMap<Integer, Integer>(); 
final HashMap<Integer, String> nameMap = new HashMap<Integer, String>(); 
final HashMap<Integer, Destination> objectMap = new LinkedHashMap<Integer, Destination>(); 

/** 
* get the data from cloud database 
*/ 
BmobQuery<Destination> query = new BmobQuery<Destination>(); 

// this time only one list of three elements is added instead of three lists of one element each 
query.addWhereContainedIn("id", Arrays.asList(selectedID)); 

query.findObjects(new FindListener<Destination>() { 
       @Override 
       public void done(List<Destination> list, BmobException e) { 
        if (e == null) { 
         System.out.println("success:total" + list.size() + "items。"); 
         for (Destination destination : list) { 

          int p = destination.getPriority(); 

          int id = destination.getId(); 

          String name = destination.getName(); 


          double longitude = destination.getLongitude(); 
          double latitude = destination.getLatitude(); 

          objectMap.put(id, new Destination(longitude, latitude)); 

          System.out.println(id); 

          //calculate the distance 
          double dis = DistanceUtil.distance(start.getLongitude(), start.getLatitude(), 
            longitude, latitude); 

          pMap.put(id, p); 
          weightMap.put(id, new Double(dis)); 
          nameMap.put(id, name); 

         } 
         // continue execution here though you won't be able to return a list of plans here 
        } else { 
         Log.i("bmob", "error:" + e.getMessage() + "," + e.getErrorCode()); 
        } 
       } 
}); 

希望這有助於:)

+0

感謝了很多幫助!我正在嘗試這種方法,但findObject()方法是由雲平臺編寫的。其實我是一個多線程初學者,我不知道該怎麼做。我試圖添加synchronized(this){... findObject().........},但這不起作用... –

+0

不幸的是,事實證明,沒有同步的方式,因爲它是不是由框架提供的。但代碼需要一些修改才能正常工作,我將很快編輯答案 –

+0

thx很多!我會等待答案〜 –

0
List<HashMap<Integer, Destination>> listmap=new ArrayList<>; 
    final HashMap<Integer, Destination> objectMap; 

    /** 
    * get the data from cloud database 
    */ 
    BmobQuery<Destination> query = new BmobQuery<Destination>(); 

    // this time only one list of three elements is added instead of three lists of one element each 
    query.addWhereContainedIn("id", Arrays.asList(selectedID)); 

    query.findObjects(new FindListener<Destination>() { 
        @Override 
        public void done(List<Destination> list, BmobException e) { 
         if (e == null) { 
          System.out.println("success:total" + list.size() + "items。"); 
          for (Destination destination : list) { 
           objectMap = new LinkedHashMap<Integer, Destination>(); 
int id = destination.getId(); 
           objectMap.put(id, destination); 
           listmap.add(objectMap); 

          } 
          // continue execution here though you won't be able to return a list of plans here 
         } else { 
          Log.i("bmob", "error:" + e.getMessage() + "," + e.getErrorCode()); 
         } 
        } 

試試這個