2017-12-31 244 views
-3

私はアンドロイドアプリケーションを作ろうとしますが、私はタイトルの例外を取得します。私の最初の目標は、TextViewでjsonの1文字を表示することです。その後、ボタンをクリックした後に次のキャラクターに行きたいと思っています。コードは学校のプロジェクトのためのものです。何がうまくいかないのか何時間も試してみるが、私はエラーを見つけることができない。私は多くのstackoverflow質問とその答えを読んだが、答えはすべてのコードに対して洗練されている。org.json.JSONException:データの値がありません

package com.example.pirama3.pirama3; 

import android.content.res.Resources; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.ScaleGestureDetector; 
import android.view.View; 
import android.widget.TextView; 

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

import java.io.InputStream; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Scanner; 

public class MainActivity extends AppCompatActivity { 
    public List<String> list =new ArrayList<String>(); 
    public String[] ls= new String[3998]; 




    public void loadGrades(View view){ 
     Resources res = getResources(); 
     InputStream is = res.openRawResource(R.raw.test02); 
     Scanner scanner = new Scanner(is); 
     StringBuilder builder = new StringBuilder(); 
     while(scanner.hasNextLine()){ 
      builder.append(scanner.nextLine()); 
     } 

     parseJson(builder.toString()); 
    } 

    private void parseJson(String s) { 
     TextView txt = (TextView) findViewById(R.id.abc); 

     StringBuilder builder = new StringBuilder(); 

     try{ 
      JSONObject root = new JSONObject(s); 
      JSONArray dt = root.getJSONArray("data"); 
      for(int i=0;i<3999;i++){ 
       JSONObject chara = dt.getJSONObject(i); 
       Log.d("aaa",chara.getString("character")); 
       ls[i]=chara.optString("character"); 
      } 
     }catch (JSONException e){ 
      e.printStackTrace(); 
     } 
     //Log.d("abcc",list.get(0)); 
     //txt.setText(s); 
     txt.setText(ls[1]); 
    } 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     TextView txt = (TextView) findViewById(R.id.abc); 

     //Log.d("abcc",list.get(0)); 
     //System.out.println(list.get(0));Resources res = getResources(); 
     Resources res = getResources(); 
     InputStream is = res.openRawResource(R.raw.test02); 
     Scanner scanner = new Scanner(is); 
     StringBuilder builder = new StringBuilder(); 
     while(scanner.hasNextLine()){ 
      builder.append(scanner.nextLine()); 
     } 
     try { 
      JSONObject root = new JSONObject(builder.toString()); 
      JSONArray dt = root.getJSONArray("data"); 
      //ls = new String[dt.length()]; 
     }catch (JSONException ab){ 
      ab.printStackTrace(); 
     } 
     txt.setText(ls[1]); 

    } 

} 

私のJSONファイルが

{ 
data:[ 
{ 
character:"a", 
pronunciation:"a" 
}, 
{ 
character:"b", 
"pronunciation:"b" 
} 
] 
} 

これは私がここにすべてのコード(あなたの割り当てを行うことはありません宿題であるので、これは私のactivity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context="com.example.pirama3.pirama3.MainActivity"> 
    <Button 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:onClick="loadGrades" 
     android:text="@string/button_load_grades"/> 
    <TextView 
     android:id="@+id/abc" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:textSize="20dp" 
     android:text="@string/text_student_info" /> 

</LinearLayout> 
+1

本当にあなたのリストに3998の要素がありますか?または、配列に十分なスペースを確保しようとしていますか? – Barns

+0

ここにあなたのjsonレスポンスを追加してください。 –

+0

私のリストには本当に3999の要素があります –

答えて

1

で以下のようなものです何かには良いはずです)。 一般的に、ここでコードの冗長性がいくつかあります。つまり、ボタンをクリックするたびにリソースファイルを何度も解析しています。そのコードを独自のメソッドにパックし、一度だけ呼び出す - 恐らくonCreateから最高です。

配列に3999個の要素があることがわかっても、public String[] ls= new String[3998];(なぜならpublicなぜなら)を使用しないことをお勧めします。ArrayListは必要に応じて展開されます。したがって、このような何かを:だから今

private ArrayList<String> list; 

private void parseJson(String s) { 
    list = new ArrayList<>(); 
    try{ 
     JSONObject root = new JSONObject(s); 
     JSONArray dt = root.getJSONArray("data"); 
     int len = dt.length(); 
     for(int i=0; i<len; i++){ 
      JSONObject chara = dt.getJSONObject(i); 
      String s = chara.optString("character", ""); 
      if(!s.isEmpty()){ 
       list.add(s); 
      } 
    } 
    }catch (JSONException e){ 
     e.printStackTrace(); 
    } 
} 

を、あなたのリソースからあなたのデータをロードしている(つまり、一度だけ行います)。あなたのリソースからの文字をArrayListにロードします(1回だけ行います)。 TextViewの初期値を設定します。

現在、表示中のArrayList「リスト」の値の配列位置のインデックスを保持する変数を保持します。

private int currentIndex = 0; 

今、あなたがボタンをクリックするたびにちょうどcurrentIndexの値をインクリメントし、あなたのTextView

public void loadGrades(View view){ 
    currentIndex++; 
    String s = list.get(currentIndex); 
    txt.setText(s); 
} 

免責事項にそのArrayList値を表示::私はそこに、テキストエディタでこれをやりましたメソッドや構文エラーのスペルミスがあります。しかし、あなたはその考えを得るべきです。

その他の注釈:リソースファイルをバックグラウンドスレッドでロードし、非同期にデータをロードすることができます。

関連する問題