'An error occurred while executing doInBackground() Caused by: java.util.NoSuchElementException

I'm building an android app where in this section it pulls data from sql database as per the logged in userId(memberNo) which is passed through Bundle and shows it on a RecyclerView but i get this error:

2022-03-31 14:09:41.027 9620-9667/com.dennisky.kofee E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
    Process: com.dennisky.kofee, PID: 9620
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:353)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.util.NoSuchElementException
        at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:759)
        at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:780)
        at com.dennisky.kofee.MedicalFeesReports$RepData.packReportData(MedicalFeesReports.java:76)
        at com.dennisky.kofee.MedicalFeesReports$MedicalReportDownloader.reportData(MedicalFeesReports.java:153)
        at com.dennisky.kofee.MedicalFeesReports$MedicalReportDownloader.doInBackground(MedicalFeesReports.java:126)
        at com.dennisky.kofee.MedicalFeesReports$MedicalReportDownloader.doInBackground(MedicalFeesReports.java:98)
        at android.os.AsyncTask$2.call(AsyncTask.java:333)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) 
        at java.lang.Thread.run(Thread.java:764) 

The Code that is executed when the error occurs is:


import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.dennisky.kofee.MedicalFeesReport.Parser;

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

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.Iterator;

public class MedicalFeesReports extends AppCompatActivity {

    RecyclerView recyclerView;
    String ulrAddress = "http://10.0.2.2/important/loan_statements";


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

        recyclerView = findViewById(R.id.recycler_view);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        new MedicalReportDownloader(MedicalFeesReports.this, ulrAddress, recyclerView).execute();
    }

    public String reportNumber() {

        String member = null;
        Bundle extra = getIntent().getExtras();
        if (extra != null) {
            member = extra.getString("memberNo");
        }
        return member;
    }

    public class RepData {

        public String packReportData() {

            JSONObject jo = new JSONObject();
            StringBuffer jsonData = new StringBuffer();
            try {
                jo.put("MEMBER_NO", reportNumber());
                Boolean isFirstValue = true;
                Iterator it = jo.keys();
                do {

                    String keys = it.next().toString();
                    String values = jo.get(keys).toString();
                    if (isFirstValue)
                        isFirstValue = false;
                    else
                        jsonData.append("&");

                    jsonData.append(URLEncoder.encode(keys, "UTF-8"));
                    jsonData.append("=");
                    jsonData.append(URLEncoder.encode(values, "UTF-8"));
                } while (it.hasNext());
                return jsonData.toString();
            } catch (JSONException e) {
                e.printStackTrace();
                return "ERROR: DATA ERROR";
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return "ERROR: ERROR ENCODING DATA";
            }
        }
    }

    public class MedicalReportDownloader extends AsyncTask<Void, Void, String> {

        Context context;
        String urlAddress;
        RecyclerView recyclerView;

        ProgressDialog dialog;

        public MedicalReportDownloader(Context context, String urlAddress, RecyclerView recyclerView) {
            this.context = context;
            this.urlAddress = urlAddress;
            this.recyclerView = recyclerView;
        }

        @Override
        protected void onPreExecute() {

            super.onPreExecute();
            dialog = new ProgressDialog(context);
            dialog.setTitle("Loading");
            dialog.setMessage("fetching data, please wait...");
            if (isFinishing() && dialog != null)
                dialog.show();
        }

        @Override
        protected String doInBackground(Void... voids) {

            return this.repData();
        }

        @Override
        protected void onPostExecute(String s) {

            super.onPostExecute(s);
            dialog.dismiss();
            if (s != null) {

                Parser parser = new Parser(s, context, recyclerView);
                parser.execute();
            } else {
                Toast.makeText(context, "No loan data found", Toast.LENGTH_SHORT).show();
            }
        }

        private String repData() {

            Object connection = Connector.connect(urlAddress);
            if (connection.toString().startsWith("Error"))
                return connection.toString();
            try {

                HttpURLConnection con = (HttpURLConnection) connection;
                OutputStream stream = new BufferedOutputStream(con.getOutputStream());
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream));
                String kiloData = new RepData().packReportData();
                if (kiloData.startsWith("ERROR"))
                    return "ERROR: DATA ERROR";
                writer.write(kiloData);
                writer.flush();
                writer.close();

                InputStream inputStream = new BufferedInputStream(con.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                StringBuffer buffer = new StringBuffer();
                if (bufferedReader != null) {
                    while ((line = bufferedReader.readLine()) != null)
                        buffer.append(line + "\n");
                } else
                    return null;
                return buffer.toString();

            } catch (IOException e) {
                e.printStackTrace();
            }
            return "ERROR: IO ERROR";
        }
    }

}

the mentioned parser class:


import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;

import androidx.recyclerview.widget.RecyclerView;

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

import java.util.ArrayList;

public class Parser extends AsyncTask<Void, Void, Integer> {

    String data;
    Context context;
    RecyclerView recyclerView;

    ProgressDialog dialog;
    ArrayList<ReportData> reportData = new ArrayList<>();
    MyAdapterMedicalReport adapter;

    public Parser(String data, Context context, RecyclerView recyclerView) {
        this.data = data;
        this.context = context;
        this.recyclerView = recyclerView;
    }

    @Override
    protected void onPreExecute() {

        super.onPreExecute();
        dialog = new ProgressDialog(context);
        dialog.setTitle("Parsing data");
        dialog.setMessage("Data parsing, please wait...");
        dialog.show();
    }

    @Override
    protected Integer doInBackground(Void... voids) {

        return this.parse();
    }

    @Override
    protected void onPostExecute(Integer integer) {

        super.onPostExecute(integer);
        if (dialog != null && dialog.isShowing()){
            dialog.dismiss();
            dialog = null;
        }
        if (integer == 1){
            adapter = new MyAdapterMedicalReport(context, reportData);
            recyclerView.setAdapter(adapter);
        }else
            Toast.makeText(context, "No Loan data found.", Toast.LENGTH_LONG).show();
    }

    private int parse(){

        try {

            JSONArray jsonArray = new JSONArray(data);
            JSONObject jsonObject = null;
            reportData.clear();
            ReportData data = null;

            for (int i = 0; i<jsonArray.length(); i++){
                jsonObject = jsonArray.getJSONObject(i);
                String loan_type = jsonObject.getString("loan_type");
                String amount = jsonObject.getString("amount");
                String data_approved = jsonObject.getString("date_approved");
                String loan_status = jsonObject.getString("loan_status");

                data = new ReportData();
                data.setLoanType(loan_type);
                data.setAmount(amount);
                data.setDateApproved(data_approved);
                data.setLoanStatus(loan_status);

                reportData.add(data);
            }
            return 1;

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

How can i get through this error?



Solution 1:[1]

In your "packReportData()" method you're doing a "do..while" but you need to check if "it.hasNext() == true" BEFORE "it.next()" or it will crash as you saw.

Please convert "do...while" in a "while(it.hasNext()) {...}"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 emandt