java - 持有 View 持有者的适配器中出现 NullPointerException

标签 java android

ElementAdapter类

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 类

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类

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) {

    }
}

错误

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)

这是我运行应用程序时遇到的错误,我尝试通过查找内容来解决此问题,但它不起作用。 NullPointerException 发生在我的适配器类的第 64 行。该应用程序基本上使用 API 从网站获取数据,然后在 recyclerView 中展示它。

最佳答案

在传递给适配器之前您没有初始化mElementList,因此当适配器调用 size 方法时 将抛出空指针

在此处编辑您的代码

 @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);

    }

关于java - 持有 View 持有者的适配器中出现 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60131143/

相关文章:

java - JSP 下拉列表的选定值

具有依赖项的项目的 java ant 构建文件

android - 建立Android项目失败与gradle

java - Android 中的 HashMap 反序列化问题

android - Amazon S3 问题 - 无法解析符号 AmazonS3Client

java - 需要帮助解决遗传算法问题

java - 在回收 View 中绘制直线和圆圈的最佳方法是什么?

android - 导航 Activity 中 addBackStack 方法的嵌套 fragment 问题,无法完成后台 fragment 的工作,直接关闭应用程序问题

android - 改造:失败状态代码返回空指针。

java - 如何在Android Studio中添加延迟?