循环通过JSONArray将字符串转换为对象

时间:2016-03-01 13:03:28

标签: android arrays loops arraylist fragment

我目前有一个从用户输入创建URL的方法,发送HTTP请求以获取JSONArray,然后将JSONArray转换为ArrayList。由于某些原因,用于添加每个JSONObject之一的循环仅复制相同的10次,尽管循环计数器并不告诉它这样做。显然我错过了一些东西,但下面是代码:

MainActivity

public ArrayList<Eatery> fillArray(String url) {


    String line;
    Eatery eatery = new Eatery("null","null","null","null","null",
            "null","null","null","null","null");
    ArrayList<Eatery> eateryList = new ArrayList<>();

    if (getConnection() == true) {
        try {

            URL urlFinal = createURL(url);
            HttpURLConnection postcodeConnection = (HttpURLConnection) urlFinal.openConnection();
            InputStreamReader isr = new InputStreamReader(postcodeConnection.getInputStream());
            BufferedReader bf = new BufferedReader(isr);

            while ((line = bf.readLine()) != null) {
                JSONArray ja = new JSONArray(line);
                for (int i = 0; i < ja.length(); i++) {

                    JSONObject jo = ja.getJSONObject(i);
                    String id = jo.getString("id");
                    String businessName = jo.getString("BusinessName");
                    String addressLine1 = jo.getString("AddressLine1");
                    String addressLine2 = jo.getString("AddressLine2");
                    String addressLine3 = jo.getString("AddressLine3");
                    String postcode = jo.getString("PostCode");
                    String ratingValue = jo.getString("RatingValue");
                    String ratingDate = jo.getString("RatingDate");
                    String lati = jo.getString("Latitude");
                    String longi = jo.getString("Longitude");
                    eatery.setId(id);
                    eatery.setBusinessName(businessName);
                    eatery.setAddressLine1(addressLine1);
                    eatery.setAddressLine2(addressLine2);
                    eatery.setAddressLine3(addressLine3);
                    eatery.setPostcode(postcode);
                    eatery.setRatingValue(ratingValue);
                    eatery.setRatingDate(ratingDate);
                    eatery.setLati(lati);
                    eatery.setLati(longi);
                    eateryList.add(eatery);
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }catch (IndexOutOfBoundsException e){
            Toast nameToast = Toast.makeText(getApplicationContext(), "Invalid search", Toast.LENGTH_LONG);
            nameToast.show();
        }
    } else {
        Toast nameToast = Toast.makeText(getApplicationContext(), "Error: No Active Connection", Toast.LENGTH_LONG);
        nameToast.show();
    }

    return (eateryList);
}

内部方法:

public boolean getConnection(){

    conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    networkInfo = conMgr.getActiveNetworkInfo();
    boolean connected;
    if(networkInfo != null && networkInfo.isConnected())
    {
        connected = true;
    }
    else
    {
        connected = false;
    }
    return connected;
}

public URL createURL(String searchType) {

    String URLstart = "http://sandbox.kriswelsh.com/hygieneapi/hygiene.php?op=";
    searchType = searchType.replace(" ", "%20");
    String finalURL = URLstart.concat(searchType);
    URL nameURL = null;
    try {
        nameURL = new URL(finalURL);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    return nameURL;
}

以上是在ActivityMain中,目前正在从一个片段中调用,该片段从EditText框中获取用户输入,将其添加到fillArray方法,然后将结果返回到Fragment上实例化的另一个ArrayList。

下面的片段代码:

public class NameFragment extends Fragment {

EditText enterName;
Button searchNameButton;
TableLayout nameTableLayout;
TextView testTextView, tv;
TableRow tr;
ArrayList<Eatery> nameEateryList;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.name_search_fragment, container, false);

    enterName = (EditText) rootView.findViewById(R.id.enterNameText);
    searchNameButton = (Button)rootView.findViewById(R.id.searchNameButton);
    testTextView = (TextView)rootView.findViewById(R.id.testTextView);
    nameTableLayout = (TableLayout)rootView.findViewById(R.id.NameTableLayout);

    searchNameButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            String nameSearch = enterName.getText().toString().trim();
            String nameURLKey = "s_name&name=";
            nameURLKey = nameURLKey.concat(nameSearch);

            //Grab ArrayList
            nameEateryList = ((MainActivity)getActivity()).fillArray(nameURLKey);

            for(int i = 0; i < nameEateryList.size(); i++) {

                tv = new TextView(getActivity().getApplicationContext());
                tr = new TableRow(getActivity().getApplicationContext());

                //Create Table Counter
                int turn = nameTableLayout.getChildCount();
                turn += 1;
                String turnString = turn + "";

                //Add TextView
                tv.setText(nameEateryList.get(i).eateryToString());
                tv.setPadding(15, 15, 15, 15);
                tr.setPadding(5,5,5,5);
                tv.setBackgroundColor(Color.parseColor("#557788"));
                tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
                tr.addView(tv);
                nameTableLayout.addView(tr);
            }
        }
    });
    return rootView;
   }

出于某种原因,当这循环通过ArrayList并将结果复制到我的片段中时,所有结果都是相同的。代码运行并且ArrayList被填充但似乎无法遍历ArrayList。已经坚持了一段时间,但我无法弄清楚是什么导致ArrayList重复复制同一个对象而不是循环遍历所有结果。我希望这是有道理的。如果需要任何进一步的信息,那么我当然可以提供更多的代码。这是一个非常具体的问题,我无法确定另一个有这个问题的线程,如果这个答案存在于其他地方,我会道歉。

1 个答案:

答案 0 :(得分:0)

为for循环的每次迭代创建一个新的Eatery对象,如下所示:

for (int i = 0; i < ja.length(); i++) {
    Eatery eatery = new Eatery("null","null","null","null","null",
        "null","null","null","null","null");

    JSONObject jo = ja.getJSONObject(i);
    String id = jo.getString("id");
    String businessName = jo.getString("BusinessName");
    String addressLine1 = jo.getString("AddressLine1");
    String addressLine2 = jo.getString("AddressLine2");
    String addressLine3 = jo.getString("AddressLine3");
    String postcode = jo.getString("PostCode");
    String ratingValue = jo.getString("RatingValue");
    String ratingDate = jo.getString("RatingDate");
    String lati = jo.getString("Latitude");
    String longi = jo.getString("Longitude");
    eatery.setId(id);
    eatery.setBusinessName(businessName);
    eatery.setAddressLine1(addressLine1);
    eatery.setAddressLine2(addressLine2);
    eatery.setAddressLine3(addressLine3);
    eatery.setPostcode(postcode);
    eatery.setRatingValue(ratingValue);
    eatery.setRatingDate(ratingDate);
    eatery.setLati(lati);
    eatery.setLati(longi);
    eateryList.add(eatery);
}

您面临的问题是因为您为每个循环迭代仅向列表中添加一个对象,该对象的值将是您为Eatery对象设置的最后一个值。

希望这有帮助!