Синтаксический анализ JSON и указатель нуля

#java #android #json

#java #Android #json

Вопрос:

Я пытаюсь проанализировать объект JSON, но сталкиваюсь с ошибкой nullpointer, и значение не может иметь тип java.lang.Строка не может быть преобразована в ошибку JSONObject. Мой код приведен ниже. Я был бы признателен за любую помощь.

 06-30 14:48:18.151: E/JSON Parser(10231): Error parsing data org.json.JSONException: Value Cannot of type java.lang.String cannot be converted to JSONObject
06-30 14:48:18.156: E/AndroidRuntime(10231): FATAL EXCEPTION: main
06-30 14:48:18.156: E/AndroidRuntime(10231): Process: rafa.weatherapp, PID: 10231
06-30 14:48:18.156: E/AndroidRuntime(10231): java.lang.NullPointerException
06-30 14:48:18.156: E/AndroidRuntime(10231):    at rafa.weatherapp.MainActivity$AsyncTaskParseJson.onPostExecute(MainActivity.java:72)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at rafa.weatherapp.MainActivity$AsyncTaskParseJson.onPostExecute(MainActivity.java:1)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at android.os.AsyncTask.finish(AsyncTask.java:632)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at android.os.Handler.dispatchMessage(Handler.java:102)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at android.os.Looper.loop(Looper.java:146)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at android.app.ActivityThread.main(ActivityThread.java:5602)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at java.lang.reflect.Method.invokeNative(Native Method)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at java.lang.reflect.Method.invoke(Method.java:515)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
06-30 14:48:18.156: E/AndroidRuntime(10231):    at dalvik.system.NativeStart.main(Native Method)
  

и вот мой MainActivity

     package rafa.weatherapp;

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

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity {

    TextView textview = null;
    JSONObject currentTemperature = null;

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

        textview = (TextView) findViewById(R.id.textview);
        // we will using AsyncTask during parsing 
        new AsyncTaskParseJson().execute();
    }

    // you can make this class as another java file so it will be separated from your main activity.
    public class AsyncTaskParseJson extends AsyncTask<String, String, String> {

        final String TAG = "AsyncTaskParseJson.java";

        // set your json string url here
       String yourJsonStringUrl = "https://api.forecast.io/forecast/5530508d3568e57848d53bf10cfade1f/37.8267,-122.42";

        @Override
        protected void onPreExecute() {}

        @Override
        protected String doInBackground(String... arg0) {

            try {

                // instantiate our json parser
                JSONParser jParser = new JSONParser();

                // get json string from url
                JSONObject json = jParser.getJSONFromUrl(yourJsonStringUrl);

                JSONObject weatherData = new JSONObject();


                currentTemperature = weatherData.getJSONObject("currently");
                currentTemperature.getString("temperature").toString();

                textview = (TextView) findViewById(R.id.textview);
                textview.setText((CharSequence) currentTemperature);
                Toast.makeText(MainActivity.this, "Text set", Toast.LENGTH_LONG);




            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(String strFromDoInBg) {
            currentTemperature.toString();
             textview.setText((CharSequence) (currentTemperature));
        }
    }
}
  

Комментарии:

1. Просто потому, что вы приводите a JSONObject к a CharSequence , это не делает его CharSequence .

2. Действительно ли это говорит Value Cannot of type java.lang.String cannot be converted to JSONObject ?

3. @SotiriosDelimanolis Это было решение, предложенное eclipse, когда я получал сообщение об ошибке перед его приведением.

4. Eclipse недальновиден. Он видит, что ваши типы неверны, и пытается вам помочь.

5. примечание: вы должны получать исключение JSON, иначе вы получите другое исключение с этими двумя строками textview.setText((CharSequence) currentTemperature); Toast.makeText(MainActivity.this, "Text set", Toast.LENGTH_LONG); Не удается обновить пользовательский интерфейс в фоновом потоке. Используйте один из других методов.

Ответ №1:

Я вижу несколько проблем:

  • Прежде всего, вы получаете нулевой указатель, потому что ваш return null из doInBackground()
  • Вы пытаетесь отобразить всплывающее окно в doInBackground, которое не разрешено в фоновом потоке
  • Вы должны инициализировать свой TextView в onCreate методе.
  • Вы пытаетесь получить данные, из weatherData которых вы никогда не инициализировали с помощью json.

 public class AsyncTaskParseJson extends AsyncTask<String, String, String> {
    String yourJsonStringUrl = "https://api.forecast.io/forecast/5530508d3568e57848d53bf10cfade1f/37.8267,-122.42";
    @Override
    protected String doInBackground(String... url) {
      String temperature = "";
        try {

            // instantiate our json parser
            JSONParser jParser = new JSONParser();
            // get json string from url
            JSONObject json = jParser.getJSONFromUrl(yourJsonStringUrl);
            JSONObject currentData = json.getJSONObject("currently");
            temperature = currentTemperature.getString("temperature");    

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return temperature;
    }

    @Override
    protected void onPostExecute(String currentTemp) {
         textview.setText((CharSequence) (currentTemp));
    }
}
  

Когда я снова прочитал ошибку:

Ошибка при разборе данных org.json.JSONException: Значение не может иметь тип java.lang.Строка не может быть преобразована в JSONObject

Похоже, что jParser.getJSONFromUrl() возвращает не a JSONObject , а вместо этого строку, в этом случае вы должны передать строку в JSONObject конструктор:

  String jsonString = jParser.getJSONFromUrl(yourJsonStringUrl);
 JSONObject json = new JSONObject(jsonString);
  

Но вы написали эту функцию, только вы знаете, что она возвращает.

Комментарии:

1. С вашим предложением я получаю ту же ошибку синтаксического анализа, но без ошибки nullpointer. Есть какие-либо подсказки, почему это может быть?

2. зарегистрировав JSON, вы должны показать мне, какая строка выдает ошибку синтаксического анализа. Я бы удостоверился, что получу фактический json и смогу распечатать его на консоли, прежде чем пытаться отобразить его в textview

3. @ralphie9224 Я расширил свой ответ

4. В моем классе JsonParser я возвращаю JSONObject

5. Опять же … какая строка выдает ошибку, можете ли вы зарегистрировать json

Ответ №2:

Сохраняем текущую температуру JSONObject.getString(«температура»).Для преобразования в правильный строковый тип отправьте этот аргумент в textview, который вы хотите отобразить.

Когда вы вызываете

 currentTemperature.getString("temperature").toString();
  

вы не преобразуете currentTemperature в строку, вы просто вызываете метод и нигде его не присваиваете

Кроме того, вы должны создать модель для этого объекта JSON, например

 public class CurrentTime{
String temperature;
String humidity;
}
  

И так далее, затем сохраните все значения JSON в объекте этого класса, и вы можете делать с ним что угодно, создавать установщики и геттеры, и это более чистый код

Комментарии:

1. Я превращаю его в // instantiate our json parser JSONParser jParser = new JSONParser // get json string from JSONObject json = jParser.getJSONFromUrl(yourJsonStringUrl); JSONObject currentTemperature = json.getJSONObject("currently"); temperature = currentTemperature.getString("temperature"); , но он по-прежнему выдает ошибку нулевого указателя

2. Изменили ли вы аргументы, полученные при onPostExecute вашей asynctask? @Override protected void onPostExecute(String currentTemp) { textview.setText((CharSequence) (currentTemp)); }

Ответ №3:

На самом деле вы получаете данные json в переменной «json», используя следующий код :

  JSONObject json = jParser.getJSONFromUrl(yourJsonStringUrl);
  

но после этого вы нигде не использовали эту переменную, вместо нее вы используете переменную «wheatherData», у которой нет данных. пожалуйста, проверьте это один раз.

Ответ №4:

Вам нужно сохранить строку в какой-либо переменной, замените эту строку:

 currentTemperature.getString("temperature").toString();
  

С:

 String myRealTemperature = currentTemperature.getString("temperature");
  

И используйте myRealTemperature для настройки Textview.

Комментарии:

1. У меня это установлено как сейчас, но я все еще получаю ошибку // instantiate our json parser JSONParser jParser = new JSONParser(); // get json string from url JSONObject json = jParser.getJSONFromUrl(yourJsonStringUrl); JSONObject currentTemperature = json.getJSONObject("currently"); temperature = currentTemperature.getString("temperature");