我正在尝试使用JSON从mysql数据库中获取数据并将其显示在RecyclerView中。应用程序使用JSON字符串很好地接收了数据。但是,当我试图将数据片段片段传递到回收器视图时,它给了我一个"Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged()' on a null object reference"
错误。
该错误是由BackgroundTask.java中的adapter.notifyDataSetChanged();
方法引起的。谁能帮我。
我的代码如下:
showRequestsFragment.java
package com.bloodconnect.Fragments;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.bloodconnect.Database.SharedPrefManager;
import com.bloodconnect.Model.Request;
import com.bloodconnect.R;
import java.util.ArrayList;
/**
* A simple {@link Fragment} subclass.
*/
public class ShowRequestsFragment extends Fragment {
Context ctx;
Activity activity;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<Request> arrayList = new ArrayList<>();
public ShowRequestsFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_show_requests, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.listRecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity() ));
recyclerView.setHasFixedSize(true);
adapter = new RecyclerAdapter(arrayList);
recyclerView.setAdapter(adapter);
BackgroundTask backgroundTask = new BackgroundTask(getActivity());
backgroundTask.execute();
return rootView;
}
}
Request.java
package com.bloodconnect.Model;
import java.lang.reflect.Array;
import java.util.Arrays;
public class Request {
private String name;
private String blood_group;
private String date_of_request;
private String lat_lng;
private String address;
public Request(String name, String blood_group, String date_of_request, String lat_lng, String address) {
this.name = name;
this.blood_group = blood_group;
this.date_of_request = date_of_request;
this.lat_lng = lat_lng;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBlood_group() {
return blood_group;
}
public void setBlood_group(String blood_group) {
this.blood_group = blood_group;
}
public String getDate_of_request() {
return date_of_request;
}
public void setDate_of_request(String date_of_request) {
this.date_of_request = date_of_request;
}
public String getLat_lng() {
return lat_lng;
}
public void setLat_lng(String lat_lng) {
this.lat_lng = lat_lng;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
RecyclerAdapter.java
package com.bloodconnect.Fragments;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.bloodconnect.Model.Request;
import com.bloodconnect.R;
import java.util.ArrayList;
public class RecyclerAdapter extends RecyclerView.Adapter <RecyclerAdapter.RecyclerViewHolder> {
ArrayList<Request> arrayList;
public RecyclerAdapter(ArrayList<Request> arrayList){
this.arrayList = arrayList;
}
@NonNull
@Override
public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.show_request_template, parent, false);
RecyclerViewHolder recyclerViewHolder = new RecyclerViewHolder(view);
return recyclerViewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
Request request = arrayList.get(position);
holder.name.setText(request.getName());
holder.blood_group.setText(request.getBlood_group());
holder.date_of_request.setText(request.getDate_of_request());
holder.lat_lng.setText(request.getLat_lng());
holder.address.setText(request.getAddress());
}
@Override
public int getItemCount() {
return arrayList.size();
}
public static class RecyclerViewHolder extends RecyclerView.ViewHolder {
TextView name, blood_group, date_of_request, lat_lng, address;
public RecyclerViewHolder(View view){
super(view);
name = (TextView) view.findViewById(R.id.show_request_name);
blood_group = (TextView) view.findViewById(R.id.show_request_bloodgroup);
date_of_request = (TextView) view.findViewById(R.id.show_request_date);
lat_lng = (TextView) view.findViewById(R.id.show_request_location);
address = (TextView) view.findViewById(R.id.show_request_address);
}
}
}
BackgroundTask.java
package com.bloodconnect.Fragments;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.bloodconnect.Model.Request;
import com.bloodconnect.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class BackgroundTask extends AsyncTask<Void, Request, Void> {
Context ctx;
Activity activity;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
RecyclerView.LayoutManager layoutManager;
LayoutInflater inflater;
ViewGroup container;
ArrayList<Request> arrayList = new ArrayList<>();
public BackgroundTask(Context ctx){
this.ctx = ctx;
activity = (Activity) ctx;
}
String json_url = "http://142.93.216.24/android/api.php?apicall=get_requests";
@Override
protected void onPreExecute() {
recyclerView = (RecyclerView) activity.findViewById(R.id.listRecyclerView);
layoutManager = new LinearLayoutManager(ctx);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
adapter = new RecyclerAdapter(arrayList);
recyclerView.setAdapter(adapter);
}
@Override
protected Void doInBackground(Void... voids) {
try {
URL url = new URL(json_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null){
stringBuilder.append(line + "\n");
}
httpURLConnection.disconnect();
String json_url = stringBuilder.toString().trim();
Log.d("JSON STRING", json_url);
JSONObject jsonObject = new JSONObject(json_url);
JSONArray jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
while (count < jsonArray.length()){
JSONObject JO = jsonArray.getJSONObject(count);
count++;
Request request = new Request(JO.getString("name"), JO.getString("blood_group"),
JO.getString("date_of_request"), JO.getString("lat_lng"), JO.getString("address"));
publishProgress(request);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Request... values) {
arrayList.add(values[0]);
adapter.notifyDataSetChanged();
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
答案 0 :(得分:0)
在这种情况下,您在后台类中使用的适配器将始终为空。
启动后台进程时
BackgroundTask backgroundTask = new BackgroundTask(getActivity(),adapter,arrayList);
backgroundTask.execute();
,然后在BackgroundTask类中,构造函数将为:
public BackgroundTask(Context ctx, RecyclerView.Adapter adapter, ArrayList<Request> arrayList){
this.ctx = ctx;
this.adapter = adapter;
this.arrayList = arrayList;
activity = (Activity) ctx;
}
答案 1 :(得分:0)
您正在将数据添加到arraylist中,需要在执行后设置适配器,然后使用adapter.notifyDataSetChanged();
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//set your adapter after loads complete and notify your adapter to data set changed
adapter.notifyDataSetChanged();
}