org.json.JSONException:没有数据值(对于带按钮的简单应用程序)

时间:2018-01-01 15:19:37

标签: java android json

新年快乐!我正在尝试创建一个显示带有来自json文件的字符的TextView的按钮。但我得到JSONException没有数据的值。我是新手,在java中使用JSON。你能帮我解决问题吗?谢谢。

MainActivity.java

package com.example.pirama4.pirama4;

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

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

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

public class MainActivity extends AppCompatActivity {
    private ArrayList<String> list;
    private int currentIndex=0;


    public void loadGrades1(View view){
        TextView txt = (TextView) findViewById(R.id.acc);
        currentIndex++;
        String s = list.get(currentIndex);
        txt.setText(s);
    }

    private void parseJson(String s){
        TextView mala = (TextView) findViewById(R.id.acc);
        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);
                s = chara.optString("character", "");
                if (!s.isEmpty()) {
                    list.add(s);
                }
            }
            mala.setText(list.get(1));
        }catch (JSONException e){
            e.printStackTrace();
        }
    }

    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());
    }



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
}

我的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"
    tools:context="com.example.pirama4.pirama4.MainActivity"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="press me"
        android:id="@+id/abc"
        android:layout_gravity="center"
        android:onClick="loadGrades"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="press after press me"
        android:id="@+id/abcc"
        android:layout_gravity="center"
        android:onClick="loadGrades1"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="20dp"
        android:id="@+id/acc"
        />

</LinearLayout>

Logcat错误

01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err: org.json.JSONException: No value for data
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at org.json.JSONObject.get(JSONObject.java:389)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at org.json.JSONObject.getJSONArray(JSONObject.java:584)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at com.example.pirama4.pirama4.MainActivity.parseJson(MainActivity.java:33)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at com.example.pirama4.pirama4.MainActivity.loadGrades(MainActivity.java:58)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at android.view.View.performClick(View.java:5610)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at android.view.View$PerformClick.run(View.java:22265)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at android.os.Looper.loop(Looper.java:154)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6077)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
01-01 16:46:15.366 15585-15585/com.example.pirama4.pirama4 W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
01-01 16:46:15.368 15585-15585/com.example.pirama4.pirama4 I/Choreographer: Skipped 39 frames!  The application may be doing too much work on its main thread.
01-01 16:46:17.186 15585-15601/com.example.pirama4.pirama4 D/EGL_emulation: eglMakeCurrent: 0x76f9165b3060: ver 2 0 (tinfo 0x76f9165bba20)

1 个答案:

答案 0 :(得分:0)

您似乎越来越接近项目的解决方案,但每次单击Button时仍在加载数据。

从您的错误消息中看起来好像您要返回的数据为空,而JSONObject对空字符串的效果不佳。

这样做:

private static final TAG = "TheNameOfYourActivity";

private void loadDataFromResourceFile(){
    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());
    }

    String result = builder.toString();
    if(!result.isEmpty()){
        parseJson(result);
        // Just show the first 250 characters of the string!! 3999 "character" elements is quite a bit
        Log.e(TAG, "The contents of my resource file = "  + result.substring(0,250));
    }
    else{
        Log.e(TAG, "My resource file  is empty");
    }
}

在您的onCreate方法中加载数据并获取TextView的实例:

private TextView mTvAcc;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // you only need to do this once since we are making the object a instance variable!
    mTvAcc = (TextView) findViewById(R.id.acc);

    // With this we load the data when the Activity is created 
    // This happens only once -- But with a large resource file you might want to 
    // do load the data in an AsyncTask (more advanced)
    loadDataFromResourceFile();
}

parseJson方法中有点错误。 ArrayList&#34;列表尚未初始化,因为我们现在将TextView对象作为实例变量,我们可以摆脱不需要的&#34; mala&#34;对象

private void parseJson(String jsonString){
    // now we initialize the ArrayList
    list = new ArrayList<>();
    try {
        JSONObject root = new JSONObject(jsonString);
        JSONArray dt = root.getJSONArray("data");
        int len = dt.length();

        // Check the length of the JSONArray object!
        Log.e(TAG, "Number of data objects = " + len);
        for (int i = 0; i < len; i++) {
            JSONObject chara = dt.getJSONObject(i);
            String s = chara.optString("character", "");
            if (!s.isEmpty()) {
                list.add(s);
            }
        }
        // The first value in the ArrayList start with the index value 0!!
        currentIndex = 0;
        String sText = list.get(currentIndex)
        Log.e(TAG, "First Value = " + sText);
        mTvAcc.setText(sText);
    }catch (JSONException e){
        Log.e(TAG, getMessage());
    }
}

现在摆脱&#34; loadGrades&#34;方法并重命名&#34; loadGrades1&#34;方法和实现如下:

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

你也可以摆脱这个:

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="press after press me"
        android:id="@+id/abcc"
        android:layout_gravity="center"
        android:onClick="loadGrades1"/>

现在,如果一切顺利并且数据读取成功,您应该会看到TextView中的第一个文字。

免责声明 ::我在文本编辑器中执行了此操作,因此可能会出现一些拼写错误的方法或语法错误。