简体   繁体   中英

NullPointerException in adapter holding viewholders

ElementAdapter class

package com.example.sierendeelementeninbreda;


import android.content.Context;
import android.view.ViewGroup;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;

public class ElementAdapter extends RecyclerView.Adapter<ElementAdapter.ViewHolder> {
    private static final String TAG = ElementAdapter.class.getSimpleName();

    private List<Element> mElements = new ArrayList<>();
    private final ElementOnClickHandler mElementClickHandler;

    public ElementAdapter(List<Element> mElements, ElementOnClickHandler mElementClickHandler) {
        this.mElements = mElements;
        this.mElementClickHandler = mElementClickHandler;
    }



@NonNull
    @Override
    public ElementAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        Log.v(TAG, "++++++++ onCreateViewHolder - viewGroup-class: " + viewGroup.getClass().getSimpleName());
        Log.v(TAG, "++++++++ onCreateViewHolder - viewGroup-resourceName: " + viewGroup.getContext().getResources().getResourceName(viewGroup.getId()));
        Log.v(TAG, "++++++++ onCreateViewHolder - viewGroup-resourceEntryName: " + viewGroup.getContext().getResources().getResourceEntryName(viewGroup.getId()));

        Context context = viewGroup.getContext();
        LayoutInflater inflator = LayoutInflater.from(context);

        // create a new view
        View elementListItem = inflator.inflate(R.layout.element_item, viewGroup, false);
        ElementAdapter.ViewHolder viewHolder = new ViewHolder(elementListItem);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Log.v(TAG, "++++ onBindViewHolder-type: " + holder.getClass().getSimpleName());
        holder.title.setText(mElements.get(position).getTitle());
        holder.geographicalLocation.setText(mElements.get(position).getGeographicalLocation());
        holder.identificationNumber.setText(mElements.get(position).getIdentificationNumber());
        Picasso.get()
                .load(mElements.get(position).getImage())
                .into(holder.image);

    }

    @Override
    public int getItemCount() {
        return mElements.size();
    }


    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        //one drinkItem has 3 views
        // Provide a reference to each view in the drinkItem

        private ImageView image;
        private TextView title;
        private TextView geographicalLocation;
        private TextView identificationNumber;

        public ViewHolder(View listItemView) {
            super(listItemView);
            title = (TextView) listItemView.findViewById(R.id.element_item_name);
            geographicalLocation = (TextView) listItemView.findViewById(R.id.element_Location);
            identificationNumber = (TextView) listItemView.findViewById(R.id.element_idNumber);
            image  = (ImageView) listItemView.findViewById(R.id.element_item_imageview);

            // image.setOnClickListener(this);
//                name.setOnClickListener(this);
//                description.setOnClickListener(this);
//                listItemView.setOnClickListener(this);
        }


        @Override
        public void onClick(View view) {
            int itemIndex = getAdapterPosition();
            mElementClickHandler.onElementClick(view, itemIndex);
        }
    }
}

NetworkUtils class

package com.example.sierendeelementeninbreda;

import android.os.AsyncTask;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Scanner;

public class NetworkUtils extends AsyncTask<String, Void, String> {
    private static final String TAG = NetworkUtils.class.getSimpleName();
    private OnElementApiListener listener;
    private final static String url = "https://services7.arcgis.com/21GdwfcLrnTpiju8/arcgis/rest/services/Sierende_elementen/FeatureServer/0/query?where=1%3D1&outFields=*&outSR=4326&f=json";

    public NetworkUtils(OnElementApiListener listener) {
        this.listener = listener;
    }

    @Override
    protected String doInBackground(String... input) {
        //De methode begint met een log zodat je kunt zien wat er gebeurt in de run.
        Log.d(TAG, "doInBackground was called");

        String response = null;
        HttpURLConnection httpURLConnection = null;

        // ToDo: Url maken op basis van internet adres

        try {
            URL mUrl = new URL(url);
            URLConnection mConnection = mUrl.openConnection();

            httpURLConnection = (HttpURLConnection) mConnection;
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setRequestProperty("Content-Type", "application/json");

            httpURLConnection.connect();

            int responseCode = httpURLConnection.getResponseCode();
            if(responseCode != HttpURLConnection.HTTP_OK){
                Log.e(TAG, "Aanroep naar de server is mislukt!");
            } else {
                InputStream in = httpURLConnection.getInputStream();

                Scanner scanner = new Scanner(in);
                scanner.useDelimiter("\\A");

                boolean hasInput = scanner.hasNext();
                if (hasInput) {
                    response = scanner.next();
                }
            }
            Log.d(TAG, response);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(httpURLConnection != null)
                httpURLConnection.disconnect();
        }

        return response;


    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.d(TAG, "onPreExecute: ");
    }

    @Override
    protected void onPostExecute(String response) {
        super.onPostExecute(response);
        Log.i(TAG, "createElementFromJson called");
        ArrayList<Element> elements = new ArrayList<>();
        if (response == null || response.equals("")) {
            Log.e(TAG, "onPostExecute: empty response!");
            return;
        }
        try {
            JSONObject jsonResults = new JSONObject(response);
            JSONArray elementList = jsonResults.getJSONArray("features");
            Log.d(TAG, "onPostExecute: " + jsonResults);
            Log.i(TAG, "elementArray length = " + elementList.length());
            for(int i = 0; i < elementList.length(); i++) {
                JSONObject element = elementList.getJSONObject(i);
                //all info
                JSONObject elementAttributes = element.getJSONObject("attributes");
                String image = elementAttributes.getString("URL");
                String title = elementAttributes.getString("AANDUIDINGOBJECT");
                String geographicalLocation = elementAttributes.getString("GEOGRAFISCHELIGGING");
                String identificationNumber = elementAttributes.getString("IDENTIFICATIE");

                Element element_item = new Element(title, geographicalLocation, identificationNumber);
                element_item.setImage(image);
                elements.add(element_item);
                Log.i(TAG, String.valueOf(elements.size()));


            }
            listener.onElementAvailable(elements);

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

    }

    public interface OnElementApiListener {
        void onElementAvailable(ArrayList<Element> elements);
    }

MainActivity class

package com.example.sierendeelementeninbreda;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity
        implements View.OnClickListener,NetworkUtils.OnElementApiListener,
        ElementOnClickHandler{

    private static String TAG = MainActivity.class.getName();

private final static String url = "https://services7.arcgis.com/21GdwfcLrnTpiju8/arcgis/rest/services/Sierende_elementen/FeatureServer/0/query?where=1=1&outFields=&outSR=4326&f=json";

    private ArrayList<Element> mElementList;
    private RecyclerView elementRecyclerView;
    private ElementAdapter mElementAdapter;


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

        elementRecyclerView= findViewById(R.id.recyclerView_element_list);
        elementRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mElementAdapter = new ElementAdapter(mElementList,this);
        elementRecyclerView.setAdapter(mElementAdapter);

        // Start background task
        NetworkUtils networkingTask = new NetworkUtils(this);
        networkingTask.execute(url);

    }


    @Override
    public void onElementAvailable(ArrayList<Element> elements) {
        Log.i(TAG, "elements = " + elements.size());
        this.mElementList = new ArrayList<>();

        mElementList.clear();
        mElementList.addAll(elements);
        mElementAdapter.notifyDataSetChanged();
        Log.i(TAG, "new elements = " + mElementList.size());

    }



    @Override
    public void onElementClick(View view, int itemIndex) {
        Log.v(TAG, "clicked on " + view.getClass().getSimpleName());
        int viewId = view.getId();
        Context context = this;
        String toastMessage = "";
//        if (viewId == R.id.product_imageview) {
//            toastMessage = "clicked on image of drink item";
//        } else if (viewId == R.id.product_item_name || viewId == R.id.product_item_description) {
//            toastMessage = "clicked on name or description of drink item";
//        } else if (viewId == R.id.product_list_item) {
//            toastMessage = "clicked on drink list-item nr: " + itemIndex;
//        }
        Toast.makeText(context, toastMessage, Toast.LENGTH_LONG)
                .show();
    }

    @Override
    public void onClick(View v) {

    }
}

Error

 D/NetworkUtils: onPreExecute: D/NetworkUtils: doInBackground was called D/HostConnection: HostConnection::get() New Host Connection established 0xd4a13c30, tid 27630 D/HostConnection: HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_host_composition_v1 ANDROID_EMU_host_composition_v2 ANDROID_EMU_YUV420_888_to_NV21 ANDROID_EMU_YUV_Cache ANDROID_EMU_async_unmap_buffer GL_OES_EGL_image_external_essl3 GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_gles_max_version_3_0 D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.sierendeelementeninbreda, PID: 27595 java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference at com.example.sierendeelementeninbreda.ElementAdapter.getItemCount(ElementAdapter.java:64) at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4044) at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3849) at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404) at android.view.View.layout(View.java:21912) at android.view.ViewGroup.layout(ViewGroup.java:6260)

That is the error I get when I run the app, I have tried solving this by looking things up but it is not working. The NullPointerException happens in line 64 of my adapter class. The app basically uses an API to get data from a site and then showcases it in a recylerView.

your not init mElementList before passed to adapter so when adapter call size method will throw null pointer

edit your code here

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

        elementRecyclerView= findViewById(R.id.recyclerView_element_list);
        elementRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        // init mElementList  here
        mElementList = new ArrayList<>();
        mElementAdapter = new ElementAdapter(mElementList,this);
        elementRecyclerView.setAdapter(mElementAdapter);

        // Start background task
        NetworkUtils networkingTask = new NetworkUtils(this);
        networkingTask.execute(url);

    }

It is always better to do null check

@Override public int getItemCount() { if(mElements!=null) return mElements.size(); else return 0 }

and initialize mElements in constructor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM