【问题标题】:How to parse JSON array into an Android list [duplicate]如何将 JSON 数组解析为 Android 列表 [重复]
【发布时间】:2015-06-16 01:19:27
【问题描述】:

我有一个关于 Android 中 JSON 解析的具体问题。

我需要下载一个包含以下格式信息的 JSON 数组,数组中 JSON 对象的数量是可变的。我需要检索数组中的所有 JSON 值,因此每个 JSON 值都必须存储为一个以公共 JSON 键命名的 android 列表,因为每个都有很多实例,例如地名键列表 [place1,place2,place3 = 地名列表],问题键列表等。需要注意的是,我不能使用 android 数组来存储这些 JSON 键值,因为每次我的应用程序运行此下载任务我不知道单个数组中有多少 JSON 对象。用户可以随时向数据库提交任意数量的内容。

[
{
    "placename": "place1",
    "latitude": "50",
    "longitude": "-0.5",
    "question": "place1 existed when?",
    "answer1": "1800",
    "answer2": "1900",
    "answer3": "1950",
    "answer4": "2000",
    "correctanswer": "1900"
},
{
    "placename": "place2",
    "latitude": "51",
    "longitude": "-0.5",
    "question": "place2 existed when?",
    "answer1": "800",
    "answer2": "1000",
    "answer3": "1200",
    "answer4": "1400",
    "correctanswer": "800"
},
{
    "placename": "place3",
    "latitude": "52",
    "longitude": "-1",
    "question": "place 3 was established when?",
    "answer1": "2001",
    "answer2": "2005",
    "answer3": "2007",
    "answer4": "2009",
    "correctanswer": "2009"
}
]

下面是我的 mainactivity 代码,我设法开始工作,但有一个糟糕的时刻,并意识到我只是简单地完成了每个对象中每个 JSON 键的值并将其解析为每个 JSON 键的单个字符串值。由于循环迭代它只是在每个阶段覆盖 - 地名字符串是“place1”,然后是“place2”,然后是循环结束时的“place3”,而不是[“place1”,“place2”,“place3”]这就是我想要的。我现在的问题是我将如何解析 JSONArray 以提取每个 JSON 值的所有实例并输出为每个 JSON 键的字符串列表,列表的长度由对象的数量决定?

我已经获得了用于存储所有 JSON 键值的字符串列表的模板(在下面的代码中已注释掉),但我不确定如何从 JSON 解析过程中填充该字符串列表。

我环顾四周,找不到任何关于 JSON Array to Android List 的具体信息,因此我们将不胜感激。如果我将数据捆绑到不同的活动(例如问答到测验和地名/纬度/经度到 GPS),我还想知道是否有一种方法可以维护每个列表之间的关联(例如特定地名的问题和答案) )。我可以通过引用列表中的相同索引来做到这一点吗?或者我需要将这些列表存储在本地存储中吗? SQL lite 数据库?

感谢您抽出宝贵时间,并为篇幅过长的帖子感到抱歉!

public class MainActivity extends Activity {

// The JSON REST Service I will pull from
static String dlquiz = "http://www.example.php";


// Will hold the values I pull from the JSON 
//static List<String> placename = new ArrayList<String>();
static String placename = "";
static String latitude = "";
static String longitude = "";
static String question = "";
static String answer1 = "";
static String answer2 = "";
static String answer3 = "";
static String answer4 = "";
static String correctanswer = "";

@Override
public void onCreate(Bundle savedInstanceState) {
    // Get any saved data
    super.onCreate(savedInstanceState);

    // Point to the name for the layout xml file used
    setContentView(R.layout.main);

    // Call for doInBackground() in MyAsyncTask to be executed
    new MyAsyncTask().execute();

}
// Use AsyncTask if you need to perform background tasks, but also need
// to change components on the GUI. Put the background operations in
// doInBackground. Put the GUI manipulation code in onPostExecute

private class MyAsyncTask extends AsyncTask<String, String, String> {

    protected String doInBackground(String... arg0) {

        // HTTP Client that supports streaming uploads and downloads
        DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());

        // Define that I want to use the POST method to grab data from
        // the provided URL
        HttpPost httppost = new HttpPost(dlquiz);

        // Web service used is defined
        httppost.setHeader("Content-type", "application/json");

        // Used to read data from the URL
        InputStream inputStream = null;

        // Will hold the whole all the data gathered from the URL
        String result = null;

        try {

            // Get a response if any from the web service
            HttpResponse response = httpclient.execute(httppost);        

            // The content from the requested URL along with headers, etc.
            HttpEntity entity = response.getEntity();

            // Get the main content from the URL
            inputStream = entity.getContent();

            // JSON is UTF-8 by default
            // BufferedReader reads data from the InputStream until the Buffer is full
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);

            // Will store the data
            StringBuilder theStringBuilder = new StringBuilder();

            String line = null;

            // Read in the data from the Buffer untilnothing is left
            while ((line = reader.readLine()) != null)
            {

                // Add data from the buffer to the StringBuilder
                theStringBuilder.append(line + "\n");
            }

            // Store the complete data in result
            result = theStringBuilder.toString();

        } catch (Exception e) { 
            e.printStackTrace();
        }
        finally {

            // Close the InputStream when you're done with it
            try{if(inputStream != null)inputStream.close();}
            catch(Exception e){}
        }


        //Log.v("JSONParser RESULT ", result);

        try {               
            JSONArray array = new JSONArray(result);

            for(int i = 0; i < array.length(); i++)
            {
                JSONObject obj = array.getJSONObject(i);

                //now, get whatever value you need from the object:
                placename = obj.getString("placename");
                latitude = obj.getString("latitude");
                longitude = obj.getString("longitude");
                question = obj.getString("question");
                answer1 = obj.getString("answer1");
                answer2 = obj.getString("answer2");
                answer3 = obj.getString("answer3");
                answer4 = obj.getString("answer4");
                correctanswer = obj.getString("correctanswer");    
            }               
            } catch (JSONException e){
                e.printStackTrace();
            }
        return result;

    }

    protected void onPostExecute(String result){

        // Gain access so I can change the TextViews
        TextView line1 = (TextView)findViewById(R.id.line1); 
        TextView line2 = (TextView)findViewById(R.id.line2); 
        TextView line3 = (TextView)findViewById(R.id.line3); 

        // Change the values for all the TextViews
        line1.setText("Place Name: " + placename); 
        line2.setText("Question: " + question); 
        line3.setText("Correct Answer: " + correctanswer);

    }

}

}

【问题讨论】:

  • 你快到了。您只需要一个 ArrayList 即可在其中添加值。最好的方法是为所有 Json 项目创建一个 pojo 类,然后通过它添加值。
  • 检查here。也许你会受到启发。

标签: java android json arraylist


【解决方案1】:

而不是保留变量:

static String placename = "";
static String latitude = "";
static String longitude = "";
static String question = "";
static String answer1 = "";
static String answer2 = "";
static String answer3 = "";
static String answer4 = "";
static String correctanswer = "";

使 Bean 类具有所有这些变量。制作bean的数组列表,并在解析过程中制作bean对象并添加到列表中。

豆类:

public class ModelClass{
private String latitude = "";
private String longitude = "";
private String question = "";
private String answer1 = "";
private String answer2 = "";
private String answer3 = "";
private String answer4 = "";
private String correctanswer = "";
// ....
// Getter Setters and constructors
// .......
}


ArrayList<ModelClass> mList=new ArrayList<ModelClass>();

在json解析的for循环中:

 JSONObject obj = array.getJSONObject(i);
 ModelObject object=new ModelObject();
 // parse and make ModelObject
 list.add(object);

尝试使用这种方法。它会起作用的。

【讨论】:

  • 我想将我的值收集为静态 List placename = new ArrayList();而不是静态字符串 placename = "";这仍然将它们收集为字符串,然后从所有不同的对象中列出一个列表?我想列出每个对象的所有实例(所有地名的列表、所有纬度的列表等)。你的回答能让我这样做吗?
  • 您将获得模型对象列表,每个模型对象将具有地名、纬度等
【解决方案2】:

您应该将您的对象划分为类,并使用 GSON json 解析器。

查看这个关于如何将 json 数组解析为对象的答案:

JSON parsing using Gson for Java

一个好的方法是一个类问题,其中包含一个称为可能答案的子类列表,这些子类有一个布尔属性(正确:真,不正确:假)来检查用户是否点击了正确的。

如果您想存储数据,则必须使用 sqllite 或 ActiveAndroid 等众多库中的任何一个。

【讨论】:

  • 感谢您的回复。我已经有了一种方法来确定用户使用单选按钮提供的问题和答案。它将未检查或已检查的每个可能答案发送回服务器,然后在用户点击提交后将正确答案回显给用户。将所有对象放入类中会带来什么样的优势?
  • 简单的数据处理,正确性(当它们有上下文时将它们保存在变量中是很脏的),当然还有在搜索时使用数组列表和对象的可能性......
【解决方案3】:

我看到您正在通过远程服务访问此 JSON 文件。在此基础上,您需要以一种可以解决物理 JSON 文件中有多少实例的方式来构建代码。

您的问题在这里:

 JSONArray array = new JSONArray(result);

            for(int i = 0; i < array.length(); i++)
            {
                JSONObject obj = array.getJSONObject(i);

您告诉它整个 JSON 文件有一个数组,其中包含一个长度,这是不正确的。

花括号(“{”)表示 JSONObject,方括号(“[”)表示 JSON 数组。

根据您的 JSON 文件:

[
{
    "placename": "place1",
    "latitude": "50",
    "longitude": "-0.5",
    "question": "place1 existed when?",
    "answer1": "1800",
    "answer2": "1900",
    "answer3": "1950",
    "answer4": "2000",
    "correctanswer": "1900"
},

你正在处理一个 JSONArray,并且这个数组没有引用名称,而是一个位置索引。

以下是您需要尝试的:


public class ListCreator{

    private List<String> placename;

    public ListCreator() {
         placename = new ArrayList<String>();
    }

    public void addPlaceName(String s)
    {
        answers.add(s);
    }

    public String[] getAnswers()
    {
        return placename.toArray(new String[1]);
    }
}

请记住,这只是“地名”字段的类的外观。

现在是你的 JSON:


您需要为要创建的每个列表初始化一个向量变量:

private Vector<ListCreator> placeNameVec;

接下来您需要为 JSONArray 的每个部分设置一个方法:

public Vector getPlaceNames(){
    return placeNameVector;
}

JSONArray array = new JSONArray(result);

for(int x = 0; x < 3; x++){
    JSONObject thisSet = array.getJSONObject(x);
    ListCreator placeNames = new ListCreator();
    placeNames.addPlaceName(thisSet.getString("placename"));

}
placeNameVec.add(placeNames);

这应该让你继续你想要回答的问题。

所以基本上请记住,您不能指定“array.length()”。

希望这会有所帮助!

请告诉我结果:)

如果您遇到任何进一步的困难,这个Tutorial on JSONParsing 确实在我感到困惑时帮助了我。

一切顺利

【讨论】:

  • 好吧,在我意识到之后,我可以看到您的解决方案有效,但我的问题表述有误。您的代码将三个示例对象中的每一个的 JSON 值(地名等)输出为字符串,但在循环的每次迭代中,下一组 JSON 值会覆盖先前的值,因此在循环结束时,所有字符串都用于第三个对象,以 {"placename":"place3"...} 开头。我认为我解释得不是很清楚,但我想将所有相同类型的 JSON 值(地名、纬度等)保存在一个单独的列表中,所以 (place1, place2, place3) = placenamelist, (50,51 ,52) = 纬度列表
  • 感谢您对问题的更正,我现在了解您需要做什么。我最近完全按照您的要求做了,但是使用了 Vectors。让我快速计算出清单之一,我会为您发布有效的答案。澄清一下,您希望能够将所有地名(例如)存储到一个列表中,然后将所有问题存储到一个列表中,然后将 answer1 存储到它自己的列表中,将 answer2 存储到它自己的列表中,等等?
  • 是的,简而言之,这正是我正在使用的。感谢您的帮助。
  • 我刚刚编辑了我的答案,请看看我是如何为您的问题构建可能的解决方案的。请告诉我结果:) 祝你好运!
猜你喜欢
  • 2015-10-16
  • 2021-09-05
  • 1970-01-01
  • 2023-04-11
  • 2018-07-22
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
相关资源
最近更新 更多