Reputation: 3
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.
Upvotes: 0
Views: 49
Reputation: 1690
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
Upvotes: 0
Reputation: 3658
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);
}
Upvotes: 1