Android app crashing on real device but working on emulator

Viewed 76

I am kinda new to programming, and trying to make a project witch is an android app, but when I try to run it on my device it just crashes.

I get these errors in my logcat:

java.lang.NullPointerException: Attempt to get length of null array
    2020-07-12 19:52:04.128 12417-12417/? E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.temperatura, PID: 12417
        java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
            at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:121)
            at org.json.JSONTokener.nextValue(JSONTokener.java:98)
            at org.json.JSONArray.<init>(JSONArray.java:94)
            at org.json.JSONArray.<init>(JSONArray.java:110)
            at com.example.temperatura.MainActivity.loadIntoListView(MainActivity.java:116)
            at com.example.temperatura.MainActivity.access$200(MainActivity.java:21)
            at com.example.temperatura.MainActivity$1DownloadJSON.onPostExecute(MainActivity.java:68)
            at com.example.temperatura.MainActivity$1DownloadJSON.onPostExecute(MainActivity.java:52)
            at android.os.AsyncTask.finish(AsyncTask.java:755)
            at android.os.AsyncTask.access$900(AsyncTask.java:192)
            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:772)
            at android.os.Handler.dispatchMessage(Handler.java:107)
            at android.os.Looper.loop(Looper.java:224)
            at android.app.ActivityThread.main(ActivityThread.java:7520)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

And this is my main activity.java:

package com.example.temperatura;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {

    ListView listView;
    List<String> sensor = new ArrayList<>();
    ArrayAdapter arrayAdapter;
    boolean needRefresh;        // whether refresh is needed


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

        final SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);

        listView = (ListView) findViewById(R.id.listView);
        downloadJSON("http://pillsmanager.com/temperatura/conn_app.php");

        pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                downloadJSON("http://pillsmanager.com/temperatura/conn_app.php");
                pullToRefresh.setRefreshing(false);
                needRefresh = true;
            }
        });
    }


    private void downloadJSON(final String urlWebService) {

        class DownloadJSON extends AsyncTask<Void, Void, String> {

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }


            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
                try {
                    if (needRefresh) {
                        updateAndLoadIntoListView(s);
                    } else {
                        loadIntoListView(s);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }


            @Override
            protected String doInBackground(Void... voids) {
                try {
                    URL url = new URL(urlWebService);
                    HttpURLConnection con = (HttpURLConnection) url.openConnection();
                    StringBuilder sb = new StringBuilder();
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
                    String json;
                    while ((json = bufferedReader.readLine()) != null) {
                        sb.append(json + "\n");
                    }
                    return sb.toString().trim();
                } catch (Exception e) {
                    return null;
                }
            }
        }
        DownloadJSON getJSON = new DownloadJSON();
        getJSON.execute();

    }

    private void updateAndLoadIntoListView(String json) throws JSONException {
        JSONArray jsonArray = new JSONArray(json);
        sensor.clear();
        for (int i = 0; i < jsonArray.length(); i++) {
            final JSONObject obj = jsonArray.getJSONObject(i);
            sensor.add(obj.getString("temperature") + " " + obj.getString("humidity"));

        }


        arrayAdapter.notifyDataSetChanged();
        needRefresh = false;
    }


    private void loadIntoListView(String json) throws JSONException {


        JSONArray jsonArray = new JSONArray(json);
        for (int i = 0; i < jsonArray.length(); i++) {
            final JSONObject obj = jsonArray.getJSONObject(i);
            sensor.add(obj.getString("temperature") + " " + obj.getString("humidity"));


        }

        arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, sensor);
        listView.setAdapter(arrayAdapter);


    }
}

All the help is much appreciated, I have tried everything but I can't figure out the problem

1 Answers

From the stack trace, it seems that you are passing null to loadIntoListView method.

It can only happen in your code if you are running into exception with your doInBackground method, where you are handling downloading.

There could be many reasons for it to fail on the device and work on the emulator. I recommend switching to some networking library to handle downloads and deal with those edge cases. It can be really annoying. Try using OkHttp

Related