-1

我对android开发很陌生。我正在尝试从 sdcard 解析 json。我几乎花了一个星期来解决它,但我无法解决错误。如果有人帮助解决或使其工作,那就太好了。以下是所需的代码。对不起我的英语。

Baby1.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import org.json.JSONObject;

import com.kabelash.salesgossip02.util.ExternalStorage;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class Baby1 extends Activity {
    private final String JSON_file = "country.json";
    File jsonFile;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.baby1_1);

        /** Getting Cache Directory */
        File cDir = ExternalStorage.getSDCacheDir( this, "json_files" );

        /** Getting a reference to temporary file, if created earlier */
        jsonFile = new File(cDir.getPath() + "/" + JSON_file) ;

        String strLine="";
        StringBuilder strJson = new StringBuilder();

        /** Reading contents of the temporary file, if already exists */
        try {
            FileReader fReader = new FileReader(jsonFile);
            BufferedReader bReader = new BufferedReader(fReader);

            /** Reading the contents of the file , line by line */
            while( (strLine=bReader.readLine()) != null  ){
                strJson.append(strLine);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }


     System.out.println(strLine);


        /** The parsing of the xml data is done in a non-ui thread */
       // ListViewLoaderTask listViewLoaderTask = new ListViewLoaderTask();

        /** Start parsing xml data */
        new ListViewLoaderTask().execute(strLine);

    }


    private class ListViewLoaderTask extends AsyncTask<String, Void, SimpleAdapter>{

        JSONObject jObject;
        /** Doing the parsing of xml data in a non-ui thread */
        @Override
        protected SimpleAdapter doInBackground(String... strJson) {
            try{
                jObject = new JSONObject(strJson[0]);
                CountryJSONParser countryJsonParser = new CountryJSONParser();
                countryJsonParser.parse(jObject);
            }catch(Exception e){
                Log.d("JSON Exception1",e.toString());
            }

            CountryJSONParser countryJsonParser = new CountryJSONParser();

            List<HashMap<String, String>> countries = null;

            try{
                /** Getting the parsed data as a List construct */
                countries = countryJsonParser.parse(jObject);
            }catch(Exception e){
                Log.d("Exception",e.toString());
            }

            /** Keys used in Hashmap */
            String[] from = { "country","flag","details"};

            /** Ids of views in listview_layout */
            int[] to = { R.id.tv_country,R.id.iv_flag,R.id.tv_country_details};

            /** Instantiating an adapter to store each items
            *  R.layout.listview_layout defines the layout of each item
            */
            SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), countries, R.layout.lv_layout, from, to);

            return adapter;
        }

        /** Invoked by the Android system on "doInBackground" is executed completely */
        /** This will be executed in ui thread */
        @Override
        protected void onPostExecute(SimpleAdapter adapter) {

            /** Getting a reference to listview of main.xml layout file */
            ListView listView = ( ListView ) findViewById(R.id.lv_countries);

            /** Setting the adapter containing the country list to listview */
            listView.setAdapter(adapter);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

countryJSONParser.java

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class CountryJSONParser {

    /** Receives a JSONObject and returns a list */
    public List<HashMap<String,String>> parse(JSONObject jObject){      

        JSONArray jCountries = null;
        try {           
            /** Retrieves all the elements in the 'countries' array */
            jCountries = jObject.getJSONArray("countries");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        /** Invoking getCountries with the array of json object
         * where each json object represent a country
         */
        return getCountries(jCountries);
    }


    private List<HashMap<String, String>> getCountries(JSONArray jCountries){
        int countryCount = jCountries.length();
        List<HashMap<String, String>> countryList = new ArrayList<HashMap<String,String>>();
        HashMap<String, String> country = null; 

        /** Taking each country, parses and adds to list object */
        for(int i=0; i<countryCount;i++){
            try {
                /** Call getCountry with country JSON object to parse the country */
                country = getCountry((JSONObject)jCountries.get(i));
                countryList.add(country);

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        return countryList;
    }

    /** Parsing the Country JSON object */
    private HashMap<String, String> getCountry(JSONObject jCountry){

        HashMap<String, String> country = new HashMap<String, String>();
        String countryName = "";
        String flag="";
        String language = "";
        String capital = "";
        String currencyCode = "";
        String currencyName = "";       

        try {
            countryName = jCountry.getString("countryname");
            flag = jCountry.getString("flag");
            language = jCountry.getString("language");
            capital = jCountry.getString("capital");
            currencyCode = jCountry.getJSONObject("currency").getString("code");
            currencyName = jCountry.getJSONObject("currency").getString("currencyname");

            String details =        "Language : " + language + "\n" +
                    "Capital : " + capital + "\n" +
                    "Currency : " + currencyName + "(" + currencyCode + ")";

            country.put("country", countryName);
            country.put("flag", flag);
            country.put("details", details);

        } catch (JSONException e) {         
            e.printStackTrace();
        }       
        return country;
    }
}

baby1_1.xml

<RelativeLayout 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" >

<ListView
        android:id="@+id/lv_countries"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"        
        tools:context=".Baby1" />
</RelativeLayout>

lv_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView 
        android:id="@+id/tv_country"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"        
        android:textSize="20dp"   
        android:textStyle="bold"

        />

    <ImageView 
        android:id="@+id/iv_flag"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_country"
        android:layout_centerVertical="true"
        android:padding="4dp"
        android:contentDescription="@string/str_iv_flag" />

    <TextView 
        android:id="@+id/tv_country_details"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/iv_flag"
        android:layout_below="@id/tv_country"        
        />
</RelativeLayout>

国家.json

{ "countries":[                             
    { 
        "countryname": "India",
        "flag": "R.drawable.sample_0",
        "language": "Hindi",
        "capital": "New Delhi",
        "currency": [
            "code": "INR",
            "currencyname": "Rupee"
        ]  
    }
]}  

日志猫

08-16 11:43:27.852: D/JSON Exception1(1667): org.json.JSONException: End of input at character 0 of 
08-16 11:43:27.863: D/Exception(1667): java.lang.NullPointerException
08-16 11:43:27.952: D/AndroidRuntime(1667): Shutting down VM
08-16 11:43:27.962: W/dalvikvm(1667): threadid=1: thread exiting with uncaught exception (group=0x414c4700)
08-16 11:43:28.022: E/AndroidRuntime(1667): FATAL EXCEPTION: main
08-16 11:43:28.022: E/AndroidRuntime(1667): java.lang.NullPointerException
08-16 11:43:28.022: E/AndroidRuntime(1667):     at android.widget.SimpleAdapter.getCount(SimpleAdapter.java:93)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at android.widget.ListView.setAdapter(ListView.java:463)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at com.kabelash.sg02.Baby1$ListViewLoaderTask.onPostExecute(Baby1.java:120)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at com.kabelash.sg02.Baby1$ListViewLoaderTask.onPostExecute(Baby1.java:1)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at android.os.AsyncTask.finish(AsyncTask.java:631)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at android.os.Looper.loop(Looper.java:137)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at android.app.ActivityThread.main(ActivityThread.java:5103)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at java.lang.reflect.Method.invokeNative(Native Method)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at java.lang.reflect.Method.invoke(Method.java:525)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-16 11:43:28.022: E/AndroidRuntime(1667):     at dalvik.system.NativeStart.main(Native Method)
08-16 11:43:31.892: I/Process(1667): Sending signal. PID: 1667 SIG: 9

新的Logcat:

08-17 18:25:04.815: D/AndroidRuntime(14216): Shutting down VM
08-17 18:25:04.815: W/dalvikvm(14216): threadid=1: thread exiting with uncaught exception (group=0x40ee22a0)
08-17 18:25:04.875: E/AndroidRuntime(14216): FATAL EXCEPTION: main
08-17 18:25:04.875: E/AndroidRuntime(14216): java.lang.NullPointerException
08-17 18:25:04.875: E/AndroidRuntime(14216):    at android.widget.SimpleAdapter.getCount(SimpleAdapter.java:93)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at android.widget.ListView.setAdapter(ListView.java:466)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at com.kabelash.sg02.Jeans$ListViewLoaderTask.onPostExecute(Jeans.java:119)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at com.kabelash.sg02.Jeans$ListViewLoaderTask.onPostExecute(Jeans.java:1)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at android.os.AsyncTask.finish(AsyncTask.java:631)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at android.os.Looper.loop(Looper.java:137)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at android.app.ActivityThread.main(ActivityThread.java:4898)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at java.lang.reflect.Method.invokeNative(Native Method)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at java.lang.reflect.Method.invoke(Method.java:511)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
08-17 18:25:04.875: E/AndroidRuntime(14216):    at dalvik.system.NativeStart.main(Native Method)
08-17 18:25:04.940: I/Process(14216): Sending signal. PID: 14216 SIG: 9
4

1 回答 1

3

很简单,您的 json 文件格式不正确。

"currency": [
        "code": "INR",
        "currencyname": "Rupee"
        ] 

不是 json 数组格式。正确的是:

"currency": [
              {
               "code": "INR",
               "currencyname": "Rupee"
              }
            ] 

或者您只希望货币是 jsonObject 您可以将原始帖子从 [] 更改为 {}

于 2013-08-16T17:39:58.310 回答