【问题标题】:How do I combine two separate parsed jsonObjects into a single arraylist?如何将两个单独的已解析 jsonObject 组合成一个数组列表?
【发布时间】:2015-05-19 20:27:51
【问题描述】:

我想将两个单独解析的 jsonObjects 组合成一个数组列表,然后将结果显示为字符串?

我想将summaryJsonObject 和段存储在storylineData 中。当我使用调试器summaryJsonObject 和segment 单步执行代码时,两者都保存原始json。原始 json 数据也显示在 logcat 中,但 storylineData 始终为空且不可用。

这是解析代码。

public class StorylineData {
    private static String date;
    private ArrayList<SummaryData> summary;
    private ArrayList<SegmentData> segments;
    private String caloriesIdle;
    private String lastUpdate;

    public String getDate() {
        return date;
    }

    public ArrayList<SummaryData> getSummary() {
        return summary;
    }

    public ArrayList<SegmentData> getSegments() {
        return segments;
    }

    public String getCaloriesIdle() {
        return caloriesIdle;
    }

    public String getLastUpdate() {
        return lastUpdate;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public void setSummary(ArrayList<SummaryData> summary) {
        this.summary = summary;
    }

    public void setSegments(ArrayList<SegmentData> segments) {
        this.segments = segments;
    }

    public void setCaloriesIdle(String caloriesIdle) {
        this.caloriesIdle = caloriesIdle;
    }

    public void setLastUpdate(String lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public static StorylineData parse(JSONObject jsonObject) {
        if (jsonObject != null) {
            StorylineData storylineData = new StorylineData();
            storylineData.date = jsonObject.optString("date");
            storylineData.caloriesIdle = jsonObject.optString("caloriesIdle");
            storylineData.lastUpdate = jsonObject.optString("lastUpdate");
            storylineData.summary = new ArrayList<SummaryData>();
            storylineData.segments = new ArrayList<SegmentData>();
            JSONArray summariesJsonArray= jsonObject.optJSONArray("summary");
            if (summariesJsonArray != null) {
                for (int i = 0; i < summariesJsonArray.length(); i++) {
                    JSONObject summaryJsonObject = summariesJsonArray.optJSONObject(i);
                    if (summaryJsonObject != null) {
                        storylineData.summary.add(SummaryData.parse(summaryJsonObject));
                        Log.d("storylineHandler", summaryJsonObject.toString());
                    }
                }
            }
            JSONArray segmentsJsonArray = jsonObject.optJSONArray("segments");
            if (segmentsJsonArray != null) {
                for (int i = 0; i < segmentsJsonArray.length(); i++) {
                    JSONObject segment = segmentsJsonArray.optJSONObject(i);
                    if (segment != null) {
                        storylineData.segments.add(SegmentData.parse(segment));
                        Log.d("storylineHandler", segment.toString());
                    }
                }
            }
            return storylineData;
        }
        return null;
    }
}

MainActivity 如下所示: MainActivity

public class MainActivity extends FragmentActivity implements OnClickListener{
    ..other variables here..

List<StorylineData> storylineData;

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

...other ui elements here...

        mEditTextResponse = (TextView) findViewById(R.id.editResponse);
    storylineData = new StorylineData();


MovesAPI.init(this, CLIENT_ID, CLIENT_SECRET, CLIENT_SCOPES.....
    @Override
    public void onClick(View v) {
        toggleProgress(true);
        switch (mSpinnerAPI.getSelectedItemPosition()) {

... other cases here...
            break;
...other cases here...

        case 4: // Get Summary Day
            MovesAPI.getSummary_SingleDay(summaryHandler, "20150418", null);//Date changed to "20150117"
            break;



 Other cases here..
            case 10: // Get Storyline Day
                MovesAPI.getStoryline_SingleDay(storylineHandler, "20150418", null, false);//Date changed to "20150418"
                break;

  ...Other cases here..

    }

}

...   Other MovesHandlers here...

   private JSONObject summaryJsonObject;
    private List<StorylineData> storylineList;
    private JSONObject summariesJsonArray;

private MovesHandler<ArrayList<StorylineData>> storylineHandler = new MovesHandler<ArrayList<StorylineData>>() {
@Override
        public void onSuccess(ArrayList<StorylineData> result) {

        toggleProgress(false);

        storylineList = (List<StorylineData>) StorylineData.parse(summaryJsonObject);

            updateResponse( + storylineData.toString() + "\n" //displays true to layout view
                 result.add(StorylineData.parse(summariesJsonArray))+ "\n"
+Log.d("call result", result.toString()) + "\n" //displays 60 in layout view & com.protogeo.moves.demos.apps.storyline.StorylineData@52824f88, null]
                + Log.d("Log.d storylineHandler", storylineHandler.toString()) + "\n"  ); //returns 78 in layout view  & com.protogeo.moves.demos.apps.Mainactivity@234234 to log cat


            onFailure code here..

    }
};

public void toggleProgress(final boolean isProgrressing) {

 togglePregress code here..
}

public void updateResponse(final String message) {
    runOnUiThread(new Runnable() {

        public List<StorylineData> storylineList;

        @Override
        public void run() {
            mEditTextResponse.setText(message);

  if (storylineData!= null) {
                for (StorylineData storylineData : storylineList) {
                    mEditTextResponse.append(("storylineData" + storylineData.toString()));
                }
}

        }
    });
}


 }

HttpClass

public static void getDailyStorylineList(final MovesHandler<JSONArray> handler,
                                             final String specificSummary,
                                             final String from,
                                             final String to,
                                             final String pastDays,
                                             final String updatedSince,
                                             final boolean needTrackPoints) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    /* Refresh access token if only AuthData.MOVES_REFRESHBEFORE days are there to expire current token */
                    AuthData.refreshAccessTokenIfNeeded();

                    /* Exchange the authorization code we obtained after login to get access token */
                    HashMap<String, String> nameValuePairs = new HashMap<String, String>();
                    nameValuePairs.put("access_token", AuthData.getAuthData().getAccessToken());

                   // if (specificSummary != null && specificSummary.length() > 0) nameValuePairs.put("specificSummary", specificSummary);//att

                    if (from != null && from.length() > 0) nameValuePairs.put("from", from);
                    if (to != null && to.length() > 0) nameValuePairs.put("to", to);
                    if (pastDays != null && pastDays.length() > 0) nameValuePairs.put("pastDays", pastDays);
                    if (updatedSince != null && updatedSince.length() > 0) nameValuePairs.put("updatedSince", updatedSince);
                    if (needTrackPoints) nameValuePairs.put("trackPoints", "true");


                    URL url     = new URL(MovesAPI.API_BASE + MovesAPI.API_PATH_STORYLINE + (specificSummary != null ? specificSummary : "") + "?" + Utilities.encodeUrl(nameValuePairs));
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    urlConnection.setRequestMethod("GET");
                    urlConnection.setDoInput(true);
                    urlConnection.connect();

                    if (urlConnection.getResponseCode() != 200) {
                        /* All other HTTP errors from Moves will fall here */
                        handler.onFailure(getErrorStatus(Utilities.readStream(urlConnection.getErrorStream()), urlConnection.getResponseCode()), "Server not responded with success ("+ urlConnection.getResponseCode() +")");
                        return;
                    }

                    String response = Utilities.readStream(urlConnection.getInputStream());
                    Object object = new JSONTokener(response).nextValue();
                    if (object instanceof JSONArray) {
                        JSONArray jsonArray = (JSONArray) object;
                        ArrayList<StorylineData> storylineData = new ArrayList<StorylineData>();
                        if (jsonArray != null) {
                            for (int i = 0; i < jsonArray.length(); i++) {
                                JSONObject storylineJsonObject = jsonArray.optJSONObject(i);
                                if (storylineJsonObject != null) {
                                    storylineData.add(StorylineData.parse(storylineJsonObject));
                                }
                            }
                        }
                        handler.onSuccess(storylineData);
                    } else {
                        handler.onFailure(MovesStatus.INVALID_RESPONSE, "Expected a JSONArray from server, but failed");
                    }

                } catch (Exception ex) {
                    ex.printStackTrace();
                    handler.onFailure(MovesStatus.UNEXPECTED_ERROR, "An unexpected error occured, please check logcat");
                }
          }
        }).start();
    }

MovesHandler

public interface MovesHandler<T> {//T stands for generic type

    /**
     * Implement this method to get success notifications along with the result
     * @param result : Result of the operation completed with this handler
     */
    public void onSuccess(ProfileData result);

    /**
     * Implement this method to get failure notifications along with the {@link MovesStatus} code and a brief message
     * @param status : Status code of the failure
     * @param message : A brief message about the reason behind failure
     */
    public void onFailure(MovesStatus status, String message);
}

【问题讨论】:

  • 所以你的解析函数返回null?您是仅单步执行此功能还是SummaryData.parse() 和SegmentData.parse()?
  • 谢谢汉克,我不确定我是否理解(android 新手)。穿过SummaryData 和SegmentData 似乎一切都好?在上面添加了 MainActivity 并认为 MainActivity 的内部类 private MovesHandler&lt;ArrayList&lt;StorylineData&gt;&gt; storylineHandler = new MovesHandler&lt;ArrayList&lt;StorylineData&gt;&gt;() 尝试将 SumaryData.parse() 和 SegmentData.parse() 存储在 ArrayList&lt;StorylineData&gt; 中?所以我想结合jsonObjects然后传递给MainActivity的result变量并用updateResponse显示。但是调试显示 storylineData & summaryJsonObject 为 null 而 logcat 显示原始 json?
  • 在您的 MainActivity 中,我没有看到 storylineData 被更新或传递到初始构造函数之外的任何函数中。
  • 每次我尝试更新 storylineData 或将其传递给 MainActivity 中的任何函数时,都会收到消息“storylineData 从未使用过”或“storylineData 已被分配”。我想我只需要看看一个如何做到这一点的例子,它将我的 MainActivity 与我的 StorylineData 类 & 以及其中解析的数据结合起来?
  • 我没有看到你在 MainActivity 的任何地方打电话给 StorylineData.parse()

标签: java android json arraylist string-parsing


【解决方案1】:

如果您想要一个ArrayList 来存储SummaryData 和SegmentData,您可以创建一个对象数组列表ArrayList&lt;Object&gt;。这将是更通用的解决方案。

替代方法是让SummaryData 和SegmentData 继承相同的类或实现相同的接口。

使用扩展类,您可以:

class Data {
}

class SegmentData extends Data {
}

class SummaryData extends Data {
}

然后您可以拥有一个 ArrayList,它可以同时添加 SegmentData 和 SummaryData 对象。

如果您想将每个项目显示为字符串,则需要遍历列表并调用每个项目的 toString() 函数

ArrayList<Data> dataList;
for (Data d : dataList) {
    Log.d("data", d.toString())
} 

只需确保覆盖SegmentData 和SummaryData 中的toString() 函数

编辑:展示如何打印JsonArray

如果您只想打印 JsonArrays,您可以:

public class StorylineData {
    private static String date;
    private JSONArray summary;
    private JSONArray segments;
    private String caloriesIdle;
    private String lastUpdate;

    public String getDate() {
        return date;
    }

    public JSONArray getSummary() {
        return summary;
    }

    public JSONArray getSegments() {
        return segments;
    }

    public String getCaloriesIdle() {
        return caloriesIdle;
    }

    public String getLastUpdate() {
        return lastUpdate;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public void setSummary(JSONArray summary) {
        this.summary = summary;
    }

    public void setSegments(JSONArray segments) {
        this.segments = segments;
    }

    public void setCaloriesIdle(String caloriesIdle) {
        this.caloriesIdle = caloriesIdle;
    }

    public void setLastUpdate(String lastUpdate) {
        this.lastUpdate = lastUpdate;
    }

    public static StorylineData parse(JSONObject jsonObject) {
        if (jsonObject != null) {
            StorylineData storylineData = new StorylineData();
            storylineData.date = jsonObject.optString("date");
            storylineData.caloriesIdle = jsonObject.optString("caloriesIdle");
            storylineData.lastUpdate = jsonObject.optString("lastUpdate");
            storylineData.summary = jsonObject.optJSONArray("summary");
            storylineData.segments = jsonObject.optJSONArray("segments");
            return storylineData;
        }
        return null;
    }

    @Override
    public String toString() {
        JSONArray combined = new JSONArray(summary);
        combined.put(segment);
        return combined.toString();
    }
}

在你的 MainActivity

private StorylineData storylineData;

private MovesHandler<JSONArray> storylineHandler = new MovesHandler<JSONArray>() {
    @Override
    public void onSuccess(JSONArray result) {
        toggleProgress(false);
        storylineData = StorylineData.parse(summaryJsonObject);

        updateResponse(storylineData.toString()) //displays true to layout view
        result.add(storylineData.getSummary());
        Log.d("call result", result.toString());
        Log.d("Log.d storylineHandler", storylineHandler.toString()); 
    }
};

【讨论】:

  • 谢谢,不确定如何覆盖toString 或将您的建议实施到我的代码中?我正在尝试调整现有代码,以便我更容易理解和实施你能否使用我的代码、变量、类名等显示你的答案和示例以及它们适合我的代码的位置。由于您提供的数据和数据列表示例对我来说有点难以理解如何作为初学者来实现。希望我上面包含的 MainActivity 有所帮助,再次感谢。
  • 您可以通过在SegmentData 和SummaryData 中实现该功能来覆盖toString。您应该查看 Java 中的继承以了解我提供的数据示例。继承在 Java 和面向对象编程中很常见。
  • 我已经阅读了继承并且对子类如何从父类继承有了一些了解。但是我仍然看不到如何将其应用于我现有的代码,或者如果我根据您的 Data 类示例编写新类,我看不到如何将它与我现有的其他链接的类集成?
  • 如果我根据您的Data 示例编写一个类,我看不到如何将它与我的其他链接类集成?我对 JsonObjects/Arrays 有点困惑,所以确定如何在新类中同时添加 SegmentData 和 SummaryData 对象。我相信MainActivity's 内部类或StorylinData 类可能已经为初学者提供了添加SegmentData 和SummaryData 而不编写新类的机会,这对新手来说可能很难?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
  • 1970-01-01
  • 2014-06-04
  • 2023-04-06
  • 2015-09-10
  • 1970-01-01
相关资源
最近更新 更多