我是一名PHP程序员,正在尝试学习JAVA。我在尝试解析json文件时遇到问题。已经三天了..对此感到头疼。我正在创建一个Android应用程序(使用JAVA)来解析json文件。这是示例json数据(http://metalgearrisingguide.com/samplejson.json)以及如何显示图像?
当我尝试时,我的logcat出现以下错误,模拟器上没有任何显示
Error parsing data org.json.JSONException: Value {"product":[{"summary":"Speak a word and the knob will turn by itself","state":"good","image":"http:\/\/upload.wikimedia.org\/wikipedia\/commons\/e\/e9\/Door_Knob_with_Lock_USA.jpg","title":"Special Door knob requires no holding just music","address":[{"address":"Merchant address 1"},{"address":"merchant address 2"}],"url":"http:\/\/merchantwebsite.com"},{"summary":"This door bell will detect faces of known people and change music if unknown","state":"good","image":"http:\/\/www.thedoorbell.net\/images\/DoorbellHeader.jpg","title":"Special Door Bell that uses face recognition technology","address":[{"address":"Merchant address 1"},{"address":"merchant address 2"}],"url":"http:\/\/merchantwebsite2.com"},{"summary":"Can't wake up in the morning?\r\nWill you be awake for party? Listen to your favourite song that will awake you!","state":"refurnished","image":"http:\/\/jgrundig.wpengine.netdna-cdn.com\/wp-content\/uploads\/2011\/08\/RCA-Alarm-Clock-with-Charging-Cord-RC107.jpg","title":"The only alarm clock that plays your favourite song from your smartphone","address":[{"address":"Merchant address 1"},{"address":"merchant address 2"}],"url":"http:\/\/merchantwebsite3.com"}],"site":{"sitename":"Simple Product Find","imgprefix":"http:\/\/mydomain.com\/","urlprefix":"http:\/\/mydomain.com\/"}} at data of type org.json.JSONObject cannot be converted to JSONArray
这是我的JSONfunctions类:
public class JSONfunctions { public static JSONObject getJSONfromURL(String url){ InputStream is = null; String result = ""; JSONObject jArray = null; //http post try{ HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); is = entity.getContent(); }catch(Exception e){ Log.e("log_tag", "Error in http connection "+e.toString()); } //convert response to string try{ BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); result=sb.toString(); }catch(Exception e){ Log.e("log_tag", "Error converting result "+e.toString()); } try{ jArray = new JSONObject(result); }catch(JSONException e){ Log.e("log_tag", "Error parsing data "+e.toString()); } return jArray; //return result; } }
这是我的代码:
public class Main extends ListActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listplaceholder); ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>(); JSONObject json = JSONfunctions.getJSONfromURL("http://metalgearrisingguide.com/samplejson.json"); try{ JSONArray data = json.getJSONArray("data"); JSONArray products = data.getJSONArray(1); for(int i=0;i<products.length();i++){ HashMap<String, String> map = new HashMap<String, String>(); JSONObject e = products.getJSONObject(i); map.put("id", String.valueOf(i)); map.put("title", "Product name:" + e.getString("title")); map.put("state", "Condition:" + e.getString("state")); map.put("summary", "Description: " + e.getString("summary")); mylist.add(map); Set set = map.entrySet(); // Get an iterator Iterator o = set.iterator(); // Display elements while(o.hasNext()) { Map.Entry me = (Map.Entry)o.next(); System.out.print(me.getKey() + ": "); System.out.println(me.getValue()); } System.out.println(); } }catch(JSONException e) { Log.e("log_tag", "Error parsing data "+e.toString()); } ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.main, new String[] { "state", "summary" }, new int[] { R.id.item_title, R.id.item_subtitle }); setListAdapter(adapter); final ListView lv = getListView(); lv.setTextFilterEnabled(true); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { @SuppressWarnings("unchecked") HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position); Toast.makeText(Main.this, "ID '" + o.get("id") + "' was clicked.", Toast.LENGTH_SHORT).show(); } }); } }
您有两个问题,第一个是如何解析sub json;第二个是如何解析sub json。第二,如何从网上显示图像;我通过您的示例json网址成功进行了演示,如下所示:
首先,定义一个数据类:Data.java
package com.example.jsonparser; import java.util.ArrayList; public class Data { private String mState; private String mImageUrl; private String mTitle; private String mSummary; private ArrayList<String> mAddList; private String mUrl; public Data(String mState, String mImageUrl, String mTitle, String mSummary, ArrayList<String> addList, String mUrl) { super(); this.mState = mState; this.mImageUrl = mImageUrl; this.mTitle = mTitle; this.mSummary = mSummary; this.mAddList = addList; this.mUrl = mUrl; } public String getmState() { return mState; } public void setmState(String mState) { this.mState = mState; } public String getmImageUrl() { return mImageUrl; } public void setmImageUrl(String mImageUrl) { this.mImageUrl = mImageUrl; } public String getmTitle() { return mTitle; } public void setmTitle(String mTitle) { this.mTitle = mTitle; } public String getmSummary() { return mSummary; } public void setmSummary(String mSummary) { this.mSummary = mSummary; } public ArrayList<String> getmAddress1() { return mAddList; } public void setmAddress1(ArrayList<String> mAddress1) { this.mAddList = mAddress1; } public String getmUrl() { return mUrl; } public void setmUrl(String mUrl) { this.mUrl = mUrl; } }
其次,定义用于解析json字符串的解析器类:Parser.java
package com.example.jsonparser; import java.util.ArrayList; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; public class Parser { private ArrayList<Data> mDataSource = new ArrayList<Data>(); public Parser(String json) { jsonParser(json); } private void jsonParser(String json) { try { JSONObject obj = new JSONObject(json); JSONObject var = obj.getJSONObject("data"); JSONArray list = var.getJSONArray("product"); int len = list.length(); for (int i = 0; i < len; i++) { try { JSONObject data = list.getJSONObject(i); String state = data.getString("state"); String image = data.getString("image"); String title = data.getString("title"); String summary = data.getString("summary"); String url = data.getString("url"); ArrayList<String> addList = new ArrayList<String>(); JSONArray addArray = data.getJSONArray("address"); int size = addArray.length(); /** * parser sub json */ for(int j = 0; j < size; j++) { addList.add(addArray.getJSONObject(j).getString("address")); } mDataSource.add(new Data(state, image, title, summary, addList, url)); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public ArrayList<Data> getSource() { return mDataSource; } }
第三,通过URL定义任务下载图像:DownloadImageTask.java
package com.example.jsonparser; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.widget.ImageView; public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> { private String mUrl; private ImageView mImageView = null; public DownloadImageTask(String Url, ImageView imageView) { mUrl = Url; this.mImageView = imageView; } protected void onPostExecute(Bitmap result) { super.onPostExecute(result); if (result != null) { mImageView.setImageBitmap(result); } } protected Bitmap doInBackground(Void... params) { Bitmap bitmap = getBitmap(mUrl); return bitmap; } public Bitmap getBitmap(String imageUrl) { Bitmap mBitmap = null; try { URL url = new URL(imageUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); InputStream is = conn.getInputStream(); mBitmap = BitmapFactory.decodeStream(is); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return mBitmap; } }
第四,定义一个适配器扩展BaseAdapter来显示数据和图像:Adapter.java
package com.example.jsonparser; import java.util.ArrayList; import android.app.Activity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.RecyclerListener; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class Adapter extends BaseAdapter { private static final String TAG = "Adapter"; private Activity mActivity; public ArrayList<Data> mObjects; static class ViewHolder { ImageView icon; TextView title; DownloadImageTask mTask; } public Adapter(Activity activity, ArrayList<Data> mObjects) { this.mActivity = (Activity) activity; this.mObjects = mObjects; } public void setObjects(ArrayList<Data> mObjects) { this.mObjects = mObjects; } @Override public View getView(int position, View convertView, ViewGroup parent) { Data item = mObjects.get(position); View rowView = convertView; if (rowView == null) { LayoutInflater inflater = mActivity.getLayoutInflater(); rowView = inflater.inflate(R.layout.item, parent, false); ViewHolder viewHolder = new ViewHolder(); viewHolder.icon = (ImageView) rowView.findViewById(R.id.image); viewHolder.title = (TextView) rowView.findViewById(R.id.title); rowView.setTag(viewHolder); } ViewHolder holder = (ViewHolder) rowView.getTag(); holder.title.setText(item.getmTitle()); holder.icon.setBackgroundResource(R.drawable.ic_launcher); holder.mTask = new DownloadImageTask(item.getmImageUrl(), holder.icon); if (!holder.mTask.isCancelled()) { holder.mTask.execute(); } return rowView; } @Override public int getCount() { return (this.mObjects.size()); } @Override public Object getItem(int position) { return (this.mObjects.get(position)); } @Override public long getItemId(int position) { return (position); } public AbsListView.RecyclerListener mRecyclerListener = new RecyclerListener( ){ public void onMovedToScrapHeap(View view) { ViewHolder viewHolder = (ViewHolder) view.getTag(); DownloadImageTask imagetask = viewHolder.mTask; if (imagetask != null) { imagetask.cancel(true); } } }; }
最后,在活动中使用以下类:MainActivity.java
package com.example.jsonparser; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.ListView; public class MainActivity extends Activity { private ListView mListView; private Adapter mAdapter; private ArrayList<Data> mSource = new ArrayList<Data>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(android.R.id.list); mAdapter = new Adapter(this, mSource); mListView.setAdapter(mAdapter); mListView.setRecyclerListener(mAdapter.mRecyclerListener); final String url = "http://metalgearrisingguide.com/samplejson.json"; new Thread(new Runnable() { @Override public void run() { Parser parser = new Parser(getJSONfromURL(url)); mSource = parser.getSource(); Message msg = mHandler.obtainMessage(); mHandler.sendMessage(msg); } }).start(); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { mAdapter.setObjects(mSource); mAdapter.notifyDataSetChanged(); } }; public String getJSONfromURL(String url) { InputStream is = null; String result = ""; // http post try { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); is = entity.getContent(); } catch (Exception e) { Log.e("log_tag", "Error in http connection " + e.toString()); } // convert response to string try { BufferedReader reader = new BufferedReader(new InputStreamReader( is, "iso-8859-1"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); result = sb.toString(); } catch (Exception e) { Log.e("log_tag", "Error converting result " + e.toString()); } return result; } }
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="@android:color/transparent" /> </LinearLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:id="@+id/image" android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="left|top" android:layout_marginBottom="10dp" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:gravity="left|top" android:lineSpacingExtra="3.0dp" android:textColor="#ffffff" android:textSize="15sp" /> </LinearLayout>
就这样。