2013-08-16 64 views
0

我對android開發很陌生。我試圖從sdcard解析json。我幾乎花了一個星期的時間來解決它,但我無法解決這個錯誤。如果有人幫助解決或使其工作,這將是非常有意義的。以下是所需的代碼。抱歉我的英語。從sdcard解析json時出錯 - Android

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> 

country.json

{ "countries":[ 

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

logcat的

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 
+0

是什麼線120'Baby1.java:120' – Raghunandan

+0

建議:使用一個JSON映射器。 –

+0

'SimpleAdapter adapter = new SimpleAdapter(getBaseContext(),countries,R.layout.lv_layout,from,to)''中的'countries'爲null;'。檢查它的原因,並解決您的問題。 – Vikram

回答

3

簡單的JSON文件是不正確的格式。

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

不是json數組格式。正確的是:

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

,或者你只想貨幣是一個JSONObject您可以在原來的職位變化,從[] {}個

+0

我做了更改,但仍無法解決此問題。 – Kabil

+0

按照你的代碼,你應該改變貨幣一個JSONObject像 「貨幣」:{ 「代碼」:「INR」, 「currencyname」:「盧比」 } 或顯示錯誤的logcat。我認爲這個錯誤是不同於以前的 – hieuxit

+0

我改變了我的JSONOject,如你所說。新的logcat發佈在我上面的帖子中 – Kabil