Frage zu Json, ArrayList, HashMap

  • Antworten:22
A G
  • Forum-Beiträge: 31

09.07.2012, 17:32:59 via Website

Hey,
ich hab folgende ArrayList<String>:
1ArrayList<String> id;
2 ArrayList<String> interpret;
3 ArrayList<String> titel;
4 ArrayList<String> album;
5 ArrayList<String> albumcover;
6 ArrayList<String> uploader;
7 ArrayList<String> likes;

diese werden dann in der onCreate, so zugewiesen:

1id = new ArrayList<String>();
2 interpret = new ArrayList<String>();
3 titel = new ArrayList<String>();
4 album = new ArrayList<String>();
5...

Jetzt hab ich ein jsonArray, dass durch Daten aus einer MySQL Datenbank gefüllt wird, wie folgt:

1JSONArray jArray = new JSONArray(result);
2 for(int i=0;i<jArray.length();i++) {
3 json_data = jArray.getJSONObject(i);
4
5 id.add(json_data.getString("id"));
6 interpret.add(json_data.getString("interpret"));
7 titel.add(json_data.getString("titel"));
8 album.add(json_data.getString("album"));
9 albumcover.add(json_data.getString("albumcover"));
10 //youtube.add(json_data.getString("youtube"));
11 uploader.add(json_data.getString("uploader"));
12 likes.add(json_data.getString("likes"));

Nun möchte ich mir meinen eigenen Adapter machen für eine ListView. Allerdings holt das Tutorial (mit dem ich arbeite) sich seine Daten aus einer xml.

http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/

1public class CustomizedListView extends Activity {
2 // All static variables
3 static final String URL = "http://api.androidhive.info/music/music.xml";
4 // XML node keys
5 static final String KEY_SONG = "song"; // parent node
6 static final String KEY_ID = "id";
7 static final String KEY_TITLE = "title";
8 static final String KEY_ARTIST = "artist";
9 static final String KEY_DURATION = "duration";
10 static final String KEY_THUMB_URL = "thumb_url";
11
12 ListView list;
13 LazyAdapter adapter;
14
15 @Override
16 public void onCreate(Bundle savedInstanceState) {
17 super.onCreate(savedInstanceState);
18 setContentView(R.layout.main);
19
20 ArrayList&lt;HashMap&lt;String, String&gt;&gt; songsList = new ArrayList&lt;HashMap&lt;String, String&gt;&gt;();
21
22 XMLParser parser = new XMLParser();
23 String xml = parser.getXmlFromUrl(URL); // getting XML from URL
24 Document doc = parser.getDomElement(xml); // getting DOM element
25
26 NodeList nl = doc.getElementsByTagName(KEY_SONG);
27 // looping through all song nodes &lt;song&gt;
28 for (int i = 0; i &lt; nl.getLength(); i++) {
29 // creating new HashMap
30 HashMap&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
31 Element e = (Element) nl.item(i);
32 // adding each child node to HashMap key =&gt; value
33 map.put(KEY_ID, parser.getValue(e, KEY_ID));
34 map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
35 map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
36 map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
37 map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));
38
39 // adding HashList to ArrayList
40 songsList.add(map);
41 }
1. Was genau ist mit der ArrayList gemeint? Lege ich für "Id", "Interpret"....jeweils eine Liste an? Und diese Liste wird dann nach und nach mit den Werten aus dem Json gefüllt? Versteh ich das richtig?
Wie bekomme ich die Werte aus meinem jsonArray in ein maphash oder andere Möglichkeiten?

Antworten
A G
  • Forum-Beiträge: 31

09.07.2012, 20:02:14 via Website

1static String id, interpret, titel, album, albumcover, uploader, likes;

1ArrayList<HashMap<String, String>> songslist = new ArrayList<HashMap<String, String>>();
2
3 HashMap<String, String> map = new HashMap<String, String>();
4 JSONArray jArray = new JSONArray(result);
5
6 for(int i=0;i<jArray.length();i++) {
7 JSONObject json_data = jArray.getJSONObject(i);
8
9 map.put(id, json_data.getString("id"));
10 map.put(interpret, json_data.getString("interpret"));
11 map.put(titel, json_data.getString("titel"));
12 map.put(album, json_data.getString("album"));
13 map.put(albumcover, json_data.getString("albumcover"));
14 //map.put("youtube", json_data.getString("youtube"));
15 map.put(uploader, json_data.getString("uploader"));
16 map.put(likes, json_data.getString("likes"));
17
18 songslist.add(map);

Scheint leider nicht ganz so zu klappen! :/

1/*ArrayList<String> id = new ArrayList<String>();
2 ArrayList<String> interpret = new ArrayList<String>();
3 ArrayList<String> titel = new ArrayList<String>();
4 ArrayList<String> album = new ArrayList<String>();
5 ArrayList<String> albumcover = new ArrayList<String>();
6 ArrayList<String> youtube = new ArrayList<String>();
7 ArrayList<String> uploader = new ArrayList<String>();
8 ArrayList<String> likes = new ArrayList<String>();*/

So hatte ich es vorher. Wie krieg ich es hin, dass ich das wieder mit der Arraylist machen kann? Also quasi HashMap<String, Arraylist>> ?

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

09.07.2012, 20:21:20 via Website

Ich verstehe nicht ganz was Du machen willst. Gibt das eine Liste? Wenn ja ...

* Zunächst einmal würde ich eine ListActivity verwenden.

* Wenn Du dann zum Beispiel einen SimpleAdapter verwendest:

1ArrayList<HashMap<String, String>> arrayListHashMap = new ArrayList<HashMap<String, String>>();
2HashMap<String, String> hashMap;
3
4hashMap = new HashMap<String, String>();
5hashMap.put("interpret", "Interpret 1");
6hashMap.put("titel", "Titel 1");
7arrayListHashMap.add(hashMap);
8
9hashMap = new HashMap<String, String>();
10hashMap.put("interpret", "Interpret 2");
11hashMap.put("titel", "Titel 2");
12arrayListHashMap.add(hashMap);
13
14SimpleAdapter adapter = new SimpleAdapter(this,
15 arrayListHashMap,
16 R.layout.ein_row_layout,
17 String[] { "interpret",
18 "titel" },
19 new int[] { R.id.ein_row_layout_interpret,
20 R.id.ein_row_layout_titel } );

Das ist jetzt absolut hässlich und ein Java Spezialist wird mir den Kopf abreißen - aber dieses Konstrukt habe ich noch nie verstanden. Ich bin eher der Datenbank-Junkie. Arrays? Maps? Schüttel - die brauch ich nie ;-) Cursor? Ja!

So geht es aber ;-)

Wenn einer weiß wie das geschickter geht dessen Post werde ich auch dankbar mitlesen.

— geändert am 09.07.2012, 20:21:40

Antworten
A G
  • Forum-Beiträge: 31

09.07.2012, 20:38:34 via Website

Ok, mein Beitrag war etwas unstrukturiert. Also die Daten werden aus einer Datenbank ausgelesen und in ein json Array gepackt. Diese Daten würde ich gerne in eine HashMap packen.
Allerdings übergibt der wie ich das gemacht habe scheinbar keine Werte. Zudem erstelle ich mir meinen eigenen Adapter.

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

09.07.2012, 21:43:21 via Website

* Die Zeilen (HashMaps) kannst Du beliebig um weitere Spalten erweitern. Z.B. hashMap.put("weiterespalte", "Wert der weiteren Spalte").

* Pro Schleifendurchlauf (Zeile) in Deinem JSON-Array erzeugst Du eine dieser HashMaps und hängst das an das ArrayListHashMap an.

* Das Besorgen der Daten wirst Du sicherlich in Deiner ListActivity in einem AsyncTask machen und die Sammliung dem Adapter im onPostExecute() des AsyncTasks übergeben.

* Der Adapter kümmert sich um die Interpretation und Darstellung der Daten. Sollte die Darstellung mit nur geringer Komplexität behaftet sein, dann reicht ggfs. schon ein <Adapter>.ViewBinder. Nehmen wir mal an Du willst in einer Zeile x Texte anzeigen und abhängig von einem Boolean Wert ein entsprechendes Drawable. Dann brauchst Du keinen voll aufgeblasenen Adapter. In solchen Fällen reicht der ViewBinder völlig aus. Das nimmt man aber wirklich nur in ganz einfachen Fällen.

— geändert am 09.07.2012, 21:44:24

Antworten
A G
  • Forum-Beiträge: 31

09.07.2012, 21:52:29 via Website

Das besorgen der Daten geschieht ber php. Das Problem ist aber scheinbar, dass der die Daten aus dem jsonArray nicht in die Map packt..

— geändert am 09.07.2012, 21:53:18

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

09.07.2012, 23:29:17 via Website

PHP? Aiuf einem Android Device? Da muss ich passen.

Das ist ganz schön wirr was Du schreibst. Du besorgst Dir innerhalb einer ListActivity, und dort innerhalb eines AsyncTask, die Daten. In einem Schleifendurchlauf packst Du die Daten in die von mir gezeigte Struktur- eine ArrayList aus HashMaps. Diese ArrayList übergibst Du einem Adapter.

— geändert am 09.07.2012, 23:34:33

Antworten
A G
  • Forum-Beiträge: 31

10.07.2012, 00:03:38 via Website

1public void onCreate(Bundle savedInstanceState) {
2 super.onCreate(savedInstanceState);
3 setContentView(R.layout.charts);
4
5 String result = "";
6 ArrayList<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
7
8 try{
9 HttpClient httpClient = new DefaultHttpClient();
10 HttpPost httpPost = new HttpPost("http://www.url.de/datei.php");
11 httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
12 HttpResponse response = httpClient.execute(httpPost);
13 HttpEntity entity = response.getEntity();
14 is = entity.getContent();
15 }
16 catch(Exception e){
17 Log.e("log-tag","Fehler"+e.toString());
18 }
19
20 try{
21 BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
22 StringBuilder sb = new StringBuilder();
23 String line = "";
24
25 while((line= reader.readLine())!=null)
26 {
27 sb.append(line+"n");
28 }
29 is.close();
30 result = sb.toString();
31 result.trim();
32 }catch(Exception e)
33 {
34 Log.e("log-tag","Error"+e.toString());
35 }

So ruf ich die Daten ab...

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

10.07.2012, 08:02:03 via Website

Den Teil hinter der Entity kannst Du komplett durch das ersetzen:

1String content = EntityUtils.toString(entity, HTTP.UTF_8);


Ich wiederhole mich nur ungern so oft:

* Pro Schleifendurchlauf (Zeile) in Deinem JSON-Array erzeugst Du eine dieser in einem vorherigen Post gezeigten HashMaps und hängst das an das ArrayListHashMap an. Auch das wurde schon gezeigt. Die Schleife muss ich Dir nicht erklären, oder?

Mach es einfach:

1ArrayList<HashMap<String, String>> arrayListHashMap = new ArrayList<HashMap<String, String>>();
2<Schleife>
3HashMap<String, String> hashMap = new HashMap<String, String>();
4hashMap.put("interpret", "Interpret 1");
5hashMap.put("titel", "Titel 1");
6...
7arrayListHashMap.add(hashMap);
8</Schleife>

— geändert am 10.07.2012, 08:05:03

Antworten
A G
  • Forum-Beiträge: 31

10.07.2012, 12:54:04 via Website

Tschuldigung, aber das habe ich doch bereits getan oder nicht?
1for(int i=0;i<jArray.length();i++) {
2 JSONObject json_data = jArray.getJSONObject(i);
3 HashMap<String, String> map = new HashMap<String, String>();
4
5 map.put(id, json_data.getString("id"));
6 map.put(interpret, json_data.getString("interpret"));
7 map.put(titel, json_data.getString("titel"));
8 map.put(album, json_data.getString("album"));
9 map.put(albumcover, json_data.getString("albumcover"));
10 //map.put("youtube", json_data.getString("youtube"));
11 map.put(uploader, json_data.getString("uploader"));
12 map.put(likes, json_data.getString("likes"));
13
14 songslist.add(map);
15
16 }
und was ganu sollte ich durch:
1String content = EntityUtils.toString(entity, HTTP.UTF_8);

ersetzen?

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

10.07.2012, 15:25:24 via Website

und was ganu sollte ich durch:

String content = EntityUtils.toString(entity, HTTP.UTF_8);

ersetzen?

Den ganzen Teil hinter der Entity - wie ich schrieb. Also BufferedReader, StringBuilder etc. etc. Nach diesen beiden Zeilen - die erste ist von Dir, die zweite ist mein Vorschlag, hast Du den ganzen Kram in einem String.

1HttpEntity entity = response.getEntity();
2String content = EntityUtils.toString(entity, HTTP.UTF_8);

Wie sieht der Adapteraufruf aus, wie sieht der Adapter aus, welche Fehlermeldung bekommst Du, hast Du mittlerweile auf eine ListActivity umgestellt, heißt die ListView auch list, bekommst Du überhaupt Daten, ist das Array auch wirklich aufgebaut, was sagt der LogCat, hast Du mal "gedebugged"?

Ich schmeiss an dieser Stelle das Handtuch. Ich bin nicht gut im Raten ...

Antworten
A G
  • Forum-Beiträge: 31

10.07.2012, 20:37:52 via Website

Hab jetzt folgendes
1BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
2 StringBuilder sb = new StringBuilder();
3 String line = "";
4
5 while((line= reader.readLine())!=null)
6 {
7 sb.append(line+"n");
8 }
9 is.close();
10 result = sb.toString();
11 result.trim();

durch das:
1HttpEntity entity = response.getEntity();
2 content = EntityUtils.toString(entity, HTTP.UTF_8);

ersetzt. "extends ListActivity" hatte ich schon immer. Die ListView heißt list:

1list = getListView();
2 adapter = new LazyAdapter(this, songslist);
3 list.setAdapter(adapter);

Nein ich bekomme keine Daten mehr in das Array.
LogCat sagt: "Content has been consumed" und danach "NullPointerException".
Wie soll das Array denn "nicht wirklich" aufgebaut sein? Wie "debugge" ich das ganze mit Eclipse? Noch nie (bewusst) gemacht.

Antworten
A G
  • Forum-Beiträge: 31

10.07.2012, 21:47:41 via Website

1HttpClient httpClient = new DefaultHttpClient();
2 HttpPost httpPost = new HttpPost("http://www.deejay-nd.de/android_charts_read.php");
3 httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
4 HttpResponse response = httpClient.execute(httpPost);
5 HttpEntity entity = response.getEntity();
6 is = entity.getContent();
7 content = EntityUtils.toString(entity, HTTP.UTF_8);
8
9 bla = (TextView)findViewById(R.id.textView1);
10 bla.setText(content);

Müsste er mir theoretisch den Inhalt ausgeben. Tut er allerdings auch nicht!
1is = entity.getContent();

Diese Zeile behebt den "Content has been consumend" Fehler...Daten werden aber leider immer noch nciht abgerufen =/
1ArrayList<HashMap<String, String>> songslist = new ArrayList<HashMap<String, String>>();
2 JSONArray jArray = new JSONArray(content);
3
4 for(int i=0;i<jArray.length();i++) {
5 JSONObject json_data = jArray.getJSONObject(i);
6 HashMap<String, String> map = new HashMap<String, String>();
7
8 map.put(id, json_data.getString("id"));
9 map.put(interpret, json_data.getString("interpret"));
10 map.put(titel, json_data.getString("titel"));
11 map.put(album, json_data.getString("album"));
12 map.put(albumcover, json_data.getString("albumcover"));
13 //map.put("youtube", json_data.getString("youtube"));
14 map.put(uploader, json_data.getString("uploader"));
15 map.put(likes, json_data.getString("likes"));
16
17 songslist.add(map);
18
19 }
20
21 list = getListView();
22 adapter = new LazyAdapter(this, songslist);
23 list.setAdapter(adapter);

Ich weiß beim besten Willen nicht, wo der Fehler leigt!!

— geändert am 10.07.2012, 21:56:28

Antworten
A G
  • Forum-Beiträge: 31

10.07.2012, 22:17:53 via Website

Ok, es läuft jetzt.

— geändert am 10.07.2012, 23:10:39

Antworten
A G
  • Forum-Beiträge: 31

12.07.2012, 18:40:19 via Website

Ich bins wieder. Diesmal sogar imt Debugger gearbeitet - unglaublich aber wahr.
1DefaultHttpClient httpClient = new DefaultHttpClient();
2 HttpPost httpPost = new HttpPost(url);
3 httpPost.setEntity(new UrlEncodedFormEntity(params));
4
5 HttpResponse httpResponse = httpClient.execute(httpPost);
6 HttpEntity httpEntity = httpResponse.getEntity();
7 content = EntityUtils.toString(httpEntity, HTTP.UTF_8);

die Variable content bekommt nicht den richtigen Wert zugewiesen, obwohl diese per "params" definitiv übergeben werden. Ich bekomme immer folgende Ausgabe:

1{"success":0,"message":"Entschuldigung. Ein Fehler ist aufgetreten."}

Meine PHP Datei sieht so aus:
1<?php
2 $response = array();
3
4 if (isset($_POST['interpret']) && isset($_POST['titel']) && isset($_POST['album']) && isset($_POST['albumcover'])) {
5
6 $interpret = $_POST['interpret'];;
7 $titel = $_POST['titel'];
8 $album = $_POST['album'];
9 $albumcover = $_POST['albumcover'];
10
11
12 //$db = new DB_CONNECT();
13 define ('DB_USER', "a");
14 define ('DB_PASSWORD', "b");
15 define ('DB_DATABASE', "c");
16 define ('DB_SERVER', "d");
17 mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD) or die(mysql_error());
18 $db = mysql_select_db(DB_DATABASE) or die(mysql_error()) or die(mysql_error());
19
20 $result = mysql_query("INSERT INTO Charts (interpret, titel, album, albumcover) VALUES ($interpret, $titel, $album, $albumcover)");
21 if ($result) {
22 // successfully inserted into database
23 $response["success"] = 1;
24 $response["message"] = "Charteintrag erfolgreich!";
25
26 echo json_encode($response);
27 } else {
28 // failed to insert row
29 $response["success"] = 0;
30 $response["message"] = "Entschuldigung. Ein Fehler ist aufgetreten.";
31 echo json_encode($response);
32 }
33 } else {
34 // required field is missing
35 $response["success"] = 0;
36 $response["message"] = "Es wurden nich alle Felder ausgefüllt!";
37 echo json_encode($response);
38 }
39?>

Wo liegt das Problem?

— geändert am 12.07.2012, 18:42:22

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

12.07.2012, 19:24:52 via Website

Geh mir weg mit PHP ;-)

Ist doch klar wo der Fehler ist - der Message Text ist doch wohl eindeutig:

1$result = mysql_query("INSERT INTO Charts (interpret, titel, album, albumcover) VALUES ($interpret, $titel, $album, $albumcover)");
2 if ($result) {
3 // successfully inserted into database
4 $response["success"] = 1;
5 $response["message"] = "Charteintrag erfolgreich!";
6
7 echo json_encode($response);
8 } else {
9 // failed to insert row
10 $response["success"] = 0;
11 $response["message"] = "Entschuldigung. Ein Fehler ist aufgetreten.";
12 echo json_encode($response);
13 }

Antworten
A G
  • Forum-Beiträge: 31

12.07.2012, 19:35:26 via Website

Ok, wo der Fehler ist weiß ich auch. Ich frags anders, wo liegt die Ursache des Problems?
Weswegen erscheint nicht der erste Fall? Jetzt sag mir bitte nicht, "weil er nicht jede Spalte füllen kann" :grin: das weiß ich auch so.

Lösung:
1$result = mysql_query("INSERT INTO Charts (interpret, titel, album, albumcover) VALUES ('$interpret', '$titel', '$album', '$albumcover')");

man beachte die ' (hochkomma).

— geändert am 12.07.2012, 19:46:10

Antworten
A G
  • Forum-Beiträge: 31

12.07.2012, 19:55:47 via Website

Ich poste hier mal rein, weil ich nicht unbedingt für jedes bisschen ein neuen Thread aufmachen möchte!
1public class ShowCharts extends ListActivity{
2
3 @Override
4 public void onCreate(Bundle savedInstanceState) {
5 super.onCreate(savedInstanceState);
6 setContentView(R.layout.charts);
7
8 try{
9 songslist = new ArrayList<HashMap<String, String>>();
10
11 new LoadCharts().execute();
12 list.setOnItemClickListener(new OnItemClickListener() {
13
14 @Override
15 public void onItemClick(AdapterView<?> parent, View v,
16 int position, long id) {
17 // getting values from selected ListItem
18 String id_item = ((TextView)findViewById(R.id._id)).getText().toString();
19
20 // Starting new intent
21 Intent in = new Intent(getApplicationContext(),
22 EditSong.class);
23 // sending pid to next activity
24 in.putExtra(TAG_ID, id_item);
25
26 // starting new activity and expecting some response back
27 startActivityForResult(in, 100);
28 }
29 });
30
31
32 }catch(Exception e)
33 {
34 Log.e("log-tag","Error2"+e.toString());
35 }
36
37}
38 @Override
39 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
40 super.onActivityResult(requestCode, resultCode, data);
41 // if result code 100
42 if (resultCode == 100) {
43 // if result code 100 is received
44 // means user edited/deleted product
45 // reload this screen again
46 Intent intent = getIntent();
47 finish();
48 startActivity(intent);
49 }
50
51 }
52
53 public class LoadCharts extends AsyncTask<String, String, String> {
54 [...]
55 /**
56 * After completing background task Dismiss the progress dialog
57 * **/
58 public void onPostExecute(String file_url) {
59 // dismiss the dialog after getting all products
60 pDialog.dismiss();
61 // updating UI from Background Thread
62
63 runOnUiThread(new Runnable() {
64 public void run() {
65 /**
66 * Updating parsed JSON data into ListView
67 * */
68 list = getListView();
69 adapter = new LazyAdapter(this, songslist);
70 list.setAdapter(adapter);
71 }
72 });
73
74 }
75
76 }
77
78}

Dort zeigt er mir an, dass der Constructor undefiened ist.
Der Constructor ist: ...(Activity, ArrayList<HashMap<String, String>>) aber ich habe mit dem this nun ein Constructor : ...(Runnable, ArrayList<HashMap<String, String>>).

Wenn ich das ganze in die OnCreate Methode packe gibt er mir zwar keinen Fehler aus, aber er zeigt die Liste nicht an. Schreibe ich statt this einfach ShowCharts.this geht das auch, aber wie gesagt bei beidem keine Liste.
Ja die Werte werden übergeben!

Antworten
Gelöschter Account
  • Forum-Beiträge: 694

12.07.2012, 20:13:21 via Website

Ja Himmel, was weiß denn ich? Dein mysql Statement produziert einen Fehler. Woher soll ich denn wissen warum? Guck Dir doch mal im PHP die Werte in den Spalten an. Und guck Dir den Rückgabewert der mysql Datenbank an.

1.) Der erste Fall, lesen von Werten aus der mysql und füllen des Adapters.

2.) Der zweite Fall, schreiben von Werten in die mysql.

Worüber reden wir denn jetzt? Der mysql Fehler ist Fall #2., oder?

— geändert am 12.07.2012, 20:16:59

Antworten
A G
  • Forum-Beiträge: 31

13.07.2012, 13:35:39 via Website

Ne, reden von Fehler 1. Er liest die Daten aus der Datenbank (macht er), packt sie in ein JsonArray (macht er), aber er füllt sie nicht in "songslist".

— geändert am 13.07.2012, 14:09:04

Antworten