2017-12-31 89 views
-3

나는 안드로이드 응용 프로그램을 만들려고 노력하지만 제목이 없습니다. 내 첫 번째 목표는 TextView에서 json의 한 문자를 표시하는 것입니다. 그 후 버튼을 클릭하면 다음 캐릭터로 가고 싶습니다. 코드는 학교 프로젝트 용입니다. 나는 몇 시간 동안 잘못되었지만 오류를 발견 할 수 없다. 나는 많은 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 파일은이 내가 여기있는 모든 코딩을하지 않을 숙제이기 때문에이 내 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

입니다

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

이하 (과제 등 뭔가 좋은 것이어야한다.) 일반적으로 여기에 몇 가지 코드 중복성이 있습니다. 즉, 리소스 파일을 여러 번 구문 분석합니다 (버튼을 누를 때마다). 그래서 그 코드를 자체 메소드에 넣고 한 번만 호출하십시오. 아마 onCreate에서 가장 좋습니다.

당신이 public String[] ls= new String[3998];을 사용하지 않는 것이 가장 좋습니다 배열에서 3999 개 요소가있을 것이라는 점을 알고있다하더라도 (왜 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으로로드하십시오 (한 번만 수행하십시오). TextView의 초기 값을 설정하십시오.

지금 표시하고있는 ArrayList "목록"에있는 값의 배열 위치 인덱스를 보유하는 변수를 유지하십시오.

private int currentIndex = 0; 

지금 때마다 당신은 너무 거기에, 단지 currentIndex의 값을 증가 버튼을 클릭하고 TextView

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

면책 조항에서 ArrayList 값이 : 나는 텍스트 편집기에서 이런 짓을 보여 메소드 또는 구문 오류의 오자가있을 수 있습니다. 그러나 당신은 아이디어를 얻어야합니다.

추가 참고 : 리소스 파일을 백그라운드 스레드에로드하고 데이터를 비동기 적으로로드 할 수 있습니다.

관련 문제