org.json.JSONException:数据没有值



我尝试制作一个安卓应用程序,但我得到了标题的异常。我的第一个目标是在 TextView 中显示 json 中的一个字符。之后,我想在单击按钮后转到下一个角色。该代码适用于学校项目。我尝试了几个小时来找出问题所在,但找不到错误。我已经阅读了很多堆栈溢出问题及其答案,但每一段代码的答案都很复杂。

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>

由于这是一项家庭作业,我不会在这里做所有的编码(你的作业应该对某事有好处)。 一般来说,你在这里有一些代码冗余 - 即你多次解析你的资源文件(每次你点击按钮)。因此,将该代码打包到自己的方法中,并且只调用一次 - 可能最好从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中(仅执行一次)。 设置TextView的初始值。

现在保留一个变量来保存当前显示的ArrayList"列表"中值的数组位置的索引。

private int currentIndex = 0;

现在,每次单击该按钮时,只需增加当前索引的值,并在TextView中显示该值ArrayList

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

免责声明::我在文本编辑器中执行此操作,因此可能存在一些方法拼写错误或语法错误。但你应该明白这个想法。

附加说明:您可能希望在后台线程中加载资源文件并异步加载数据。

最新更新