了解如何使用我的Android JSON Parser

时间:2013-02-11 22:41:20

标签: java android json

您好,我很难理解如何使用我的JSON解析器做我想做的事情。我正在解析位于http://api.pathofexile.com/leagues?type=all的数据以取出联盟ID(目前它们是“默认”,“Hardcore”,“2月12日Solo HC Race”等)。我的解析器目前将这些ID放入列表视图。

我遇到的问题是这些ID会随着时间而改变。他们也有自己的JSON网址,我需要根据联盟ID进行解析。例如,如果联盟ID是“默认”,我需要获取该ID并将其放入网址:

“api.pathofexile.com/leagues /”+ id +“?ladder = 1& ladderOffset = 1& ladderLimit = 2”获取http://api.pathofexile.com/leagues/Default?ladder=1&ladderOffset=1&ladderLimit=2

基本上,我希望能够点击listview中的id并让它更新url并将新数据解析为单独的列表。

以下是我的JSON解析器的内容:

public class Leagues extends ListActivity {
    public static String url = "http://api.pathofexile.com/leagues?type=all";

    private static final String TAG_ID = "id";
    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    JSONArray leagues = null;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.list_item);
        new GetJSONTask().execute("");
    }

    protected class GetJSONTask extends AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> {
        protected ArrayList<HashMap<String, String>> leaguesList;

        private final ProgressDialog dialog = new ProgressDialog(Leagues.this);

        // onPreExecute method
        protected void onPreExecute() {
            this.dialog.setMessage("Loading, Please Wait..");
            this.dialog.setCancelable(false);
            this.dialog.show();
        }

        // doInBackground method
        @Override
        protected ArrayList<HashMap<String, String>> doInBackground(String... params) {
            leaguesList = new ArrayList<HashMap<String, String>>();

            // defaultHttpClient
            try {
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpGet HttpGet = new HttpGet(url);

                HttpResponse httpResponse = httpClient.execute(HttpGet);
                json = EntityUtils.toString(httpResponse.getEntity());

                // getting array of entries
                JSONArray leagues = new JSONArray(json);

                // looping through entries
                for (int i = 0; i < leagues.length(); i++) {
                    JSONObject league = leagues.getJSONObject(i);

                    String id = league.getString(TAG_ID);

                    // creating new HashMap
                    HashMap<String, String> map = new HashMap<String, String>();

                    // adding each child node to HashMap key => value
                    map.put(TAG_ID, id);
                    //map.put(TAG_EVENT, event);

                    // adding HashList to ArrayList
                    leaguesList.add(map);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return leaguesList;
        }

        // onPostExecute method
        protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
            ListAdapter adapter = new SimpleAdapter(getApplicationContext(), leaguesList, R.layout.league, new String[] { TAG_ID }, new int[] { R.id.id });
            // selecting single ListView item
            ListView lv = getListView();
            lv.setAdapter(adapter);

            if (this.dialog.isShowing()) {
                this.dialog.dismiss();
            }

        }
    }

}

此时我很丢失。即使我现在设置解析器,我正在努力做什么?任何人都可以指出我正确的方向吗?

感谢。

编辑以进一步澄清:

现在我的解析器会将联盟ID从网址“api.pathofexile.com/leagues?type=all”放入ListView,如下所示:

  1. 默认
  2. 性交
  3. 2月12日Solo HC Race
  4. (这些项目会随着时间的推移而改变)

    我希望能够点击“默认”,这会将网址更改为“api.pathofexile.com/leagues/Default?ladder=1&ladderOffset=1&ladderLimit=2”并将其解析为新的的ListView。

    更新 使用Darwind提供的项目,我改变它(使用我的一些其他代码)来显示我在点击联盟ID后想要的JSON数据。

    public class LeagueView extends ListActivity {
        //private TextView leagueId, leagueDescription;
        private static final String TAG_LADDER = "ladder";
        private static final String TAG_ENTRIES = "entries";
        private static final String TAG_ONLINE = "online";
        private static final String TAG_RANK = "rank";
        private static final String TAG_CHARACTER = "character";
        private static final String TAG_CHARNAME = "name";
        private static final String TAG_LEVEL = "level";
        private static final String TAG_CLASS = "class";
        private static final String TAG_EXPERIENCE = "experience";
        private static final String TAG_ACCOUNT = "account";
        private static final String TAG_ACCNAME = "name";
        private static final String TAG_ACCNAME2 = "name2";
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.league_layout);
    
        //leagueId = (TextView) findViewById(R.id.leagueId);
        //leagueDescription = (TextView) findViewById(R.id.leagueDescription);
    
        String urlToJson = getIntent().getExtras().getString("leagueUrl");
    
        if (urlToJson == null) {
            Toast.makeText(this, "Url was null!", Toast.LENGTH_LONG).show();
        } else {
            new LeagueTask().execute(urlToJson.replaceAll(" ", "%20"));
        }
    }
    
    protected class LeagueTask extends AsyncTask<String, Integer, League> {
        private final ProgressDialog dialog = new ProgressDialog(LeagueView.this);
        protected ArrayList<HashMap<String, String>> entriesList;
    
        // onPreExecute method
        protected void onPreExecute() {
            this.dialog.setMessage("Retrieving Ladder Information...");
            this.dialog.setCancelable(false);
            this.dialog.show();
        }
    
        // doInBackground method
        @Override
        protected League doInBackground(String... params) {
            League aLeague = new League();
            entriesList = new ArrayList<HashMap<String, String>>();
    
            // defaultHttpClient
            try {
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpGet HttpGet = new HttpGet(params[0]);
    
                HttpResponse httpResponse = httpClient.execute(HttpGet);
                String json = EntityUtils.toString(httpResponse.getEntity());
    
                // Getting a JSONObject filled.
                JSONObject leagueObject = new JSONObject(json);
    
                //String id = leagueObject.getString("id");
                //String description = leagueObject.getString("description");
    
                JSONObject ladder = leagueObject.getJSONObject(TAG_LADDER);
                JSONArray entries = ladder.getJSONArray(TAG_ENTRIES);
    
                // looping through entries
                for (int i = 0; i < entries.length(); i++) {
                    JSONObject ent = entries.getJSONObject(i);
    
                    // storing each JSON item in a variable
                    String online = ent.getString(TAG_ONLINE);
                    if (online == "false")
                        online = "Offline";
                    else online = "Online";
                    String rank = ent.getString(TAG_RANK);
    
                    // pull out character object
                    JSONObject character = ent.getJSONObject(TAG_CHARACTER);
                    String chName = character.getString(TAG_CHARNAME);
                    String lvl = character.getString(TAG_LEVEL);
                    String cl = character.getString(TAG_CLASS);
                    String xp = character.getString(TAG_EXPERIENCE);
    
                    // pull out account object
                    JSONObject account = ent.getJSONObject(TAG_ACCOUNT);
                    String accName = account.getString(TAG_ACCNAME);
    
                    // creating new HashMap
                    HashMap<String, String> map = new HashMap<String, String>();
    
                    // adding each child node to HashMap key => value
                    map.put(TAG_ONLINE, online);
                    map.put(TAG_CHARNAME, chName);
                    map.put(TAG_ACCNAME2, accName);
                    map.put(TAG_RANK, rank);
                    map.put(TAG_LEVEL, lvl);
                    map.put(TAG_EXPERIENCE, xp);
                    map.put(TAG_CLASS, cl);
    
                    entriesList.add(map);
                }
    
                // creating a league to display
                aLeague = new League();
                //aLeague.setLeagueId(id);
                //aLeague.setDescription(description);
    
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return aLeague;
        }
    
        // onPostExecute method
        protected void onPostExecute(League result) {
            //leagueId.setText(result.getLeagueId());
            //leagueDescription.setText(result.getDescription());
    
            ListAdapter adapter = new SimpleAdapter(getApplicationContext(), entriesList, R.layout.league_layout, new String[] { TAG_RANK, TAG_CHARNAME, TAG_LEVEL, TAG_EXPERIENCE, TAG_CLASS }, new int[] { R.id.rank, R.id.chName, R.id.lvl, R.id.experience, R.id.cl });
            // selecting single ListView item
            ListView lv = getListView();
            lv.setAdapter(adapter);
    
            if (this.dialog.isShowing()) {
                this.dialog.dismiss();
            }
        }
    }
    }
    

3 个答案:

答案 0 :(得分:0)

我建议不要自己编写解析器但使用JSON开发的解析器http://json.org/java/

答案 1 :(得分:0)

乔普斯,我正在编辑我的答案。

所以我嘲笑你的代码并在本地运行它。现在我明白你要做什么了。你的问题分为两部分。我认为问题描述名称不详,您的描述似乎集中在可点击的列表视图项目上,但您的摘要似乎是围绕解析json。

还要注意http://api.pathofexile.com/leagues/Hardcore?ladder=1&ladderOffset=1&ladderLimit=2没有给出格式正确的json文本,缺少开头和结尾的方括号。这不正确,它返回的是单个JSONObject而不是数组

第一部分:使列表视图项可单击,使用ListView.setOnItemClickListener使项目可单击。例如请参阅本教程:http://www.ezzylearning.com/tutorial.aspx?tid=1351248

第二部分单击时应该发生什么。其中一部分将用于setOnItemClickListener的实现,第二部分是构建新链接并单击并返回内容的JSON。您正在返回ArrayList&lt; HashMap&lt; String,String&gt;&gt; leaguesList;这看起来非常有限,你为什么不返回JSONArray本身或者ArrayList&lt; HashMap&lt; String,JSONObject&gt;&gt;其中地图有ID作为关键字以及JSONObject中您以后可以使用的所有元素,除非ID是您唯一感兴趣的内容?

我没有Android模拟器,但如果你需要任何有关JSON解析器的帮助,请告诉我。

这就是我想象它的工作方式,onclick事件将构建一个来自

的新网址
        public static String PATTERN =
          "http://api.pathofexile.com/leagues/" + ID_TOKEN +
          "?ladder=1&ladderOffset=1&ladderLimit=2";

使用传入的Url编码ID,例如默认情况下,2月15日Solo HC Race并将调用GetJSONTask.doInBackGround任务以获取新的JSON数组。

答案 2 :(得分:0)

好的,基本上因为vsnyc指出你的头衔可能有点误导。

我看到它的方式是:

  1. 从解析JSON数组中获取所有联赛的列表
  2. 能够点击列表中的联赛并通过解析JSON对象获得提供所选联赛信息的视图。
  3. 我基本上把你所有的代码都搞定了并改了一下。例如,我在评论中提到,您应该使用一个类来表示每个联盟,然后覆盖这种新类型对象的toString方法,以便可以在ListView中直接使用此类

    作为您使用的第一个网址:http://api.pathofexile.com/leagues?type=all返回一个JSON数组而不是单个对象,此数组中的对象与选择特定联盟时返回的数据不同,我不会# 39;建议使用相同的AsyncTask获取联赛列表和单个联赛。

    相反,在您使用联盟填充第一个ListView后,我会创建第二个视图,通过从特定联盟获取数据来填充。

    要进入代表一个联盟的第二个视图,您需要为第一个视图的OnItemClickListener实施ListView。在OnItemClickListener中,您将获得所选的联赛名称并将其传递给下一个视图,然后该视图将联系服务器并获取代表给定联盟的JSON对象并解析数据。

    我已经创建了一个小项目,因为这里有很多代码要添加到答案中,我需要花费更多时间来删除所有不必要的代码,而不仅仅是为了给你一个完整的工作项目。 ; - )

    这是拉链文件中的项目:

    https://dl.dropbox.com/u/27724371/AndroidListViews.zip

    如果这不是您想要的,请告诉我。