首页 > 解决方案 > RecyclerView 不显示从本地主机发送的 JSON 只是空白屏幕

问题描述

大家好,我对 AsyncTask 没有太多经验,这是我第一次使用 RecyclerView,除了我为了解它而完成的几个教程之外。

如果我在 EventActivity 中使用虚拟数据,一切正常,屏幕上会显示一个列表。但是当我创建一个 EventItems 的 ArrayList 并将其传递给适配器时,它只是一个空白屏幕。来自 localhost 的 JSON 正在被解析并发送到 EventItem 类。我已经尝试了几件事来让它工作,但由于我对 AsyncTask 和 RecyclerView 的经验有限,我最终只是让应用程序崩溃并得到一个空指针异常。

我认为 RecyclerView 是在从本地主机检索 JSON 之前创建的,这就是导致空白屏幕或空指针异常的原因,但我不是 100% 确定,如果我是正确的,也不知道如何解决这个问题。

任何帮助表示赞赏。

事件活动

public class EventActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);
        fetchEvents();//call EventBackgroundWorker

        //ArrayList<EventItem> eventList = new EventItem().getRecyclerList();//causes java null pointer exception
        ArrayList<EventItem> eventList = new ArrayList<>();


        //Dummie data
       // eventList.add(new EventItem (1, "Title1", "Date", "endDate", "Location1", 5, 1111));
       // eventList.add(new EventItem (R.drawable.ic_favourite, "Title2", "11/07/2018", "11/07/2018", "Wales", 10, 5));
       // eventList.add(new EventItem (R.drawable.ramspeed_custom, "Title3", "11/01/2018", "11/09/2018", "Paris, France", 0, 90));
       // eventList.add(new EventItem (R.drawable.ramspeed_custom, "Title4", "12/01/2018", "11/09/2018", "New York", 20, 500));
       // eventList.add(new EventItem (R.drawable.ic_favourite, "Title5", "Mon 11/05/2015", "11/09/2018", "London, England", 5, 500));
       // eventList.add(new EventItem (R.drawable.biker, "Title6", "Mon 11/05/2018", "20/07/2018", "Swords Dublin", 0, 500));

        mRecyclerView = (RecyclerView) findViewById(R.id.event_recycler_view);
        mRecyclerView.setHasFixedSize(true);//increase performance of app if recyclerView does not increase in size
        mLayoutManager = new LinearLayoutManager(this);
        // mAdapter = new EventAdapter(eventList);
        mAdapter = new EventAdapter(eventList);//context added for testing //////////////////////////////
        // mAdapter = new EventAdapter(new ArrayList<EventItem>(0));
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mAdapter);


       // buildRecyclerView();
    }


//run  background thread
    private void fetchEvents(){
       // String username = "user";
       // String userPassword = "password";
        String startConnectionCondition = "event";
        //this passes the context
        EventBackgroundWorker backgroundWorker = new EventBackgroundWorker(this);
        backgroundWorker.execute(startConnectionCondition, null);
    }

 /*   private void buildRecyclerView(){
        ArrayList<EventItem> eventList = new EventItem().getRecyclerList();

        mRecyclerView = (RecyclerView) findViewById(R.id.event_recycler_view);
        mRecyclerView.setHasFixedSize(true);//increase performance of app if recyclerView does not increase in size
        mLayoutManager = new LinearLayoutManager(this);
        // mAdapter = new EventAdapter(eventList);
        mAdapter = new EventAdapter(eventList);//context added for testing 
        // mAdapter = new EventAdapter(new ArrayList<EventItem>(0));
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mAdapter);
    }
*/
   /* public void showEventList(boolean b){
        ArrayList<EventItem> eventList = new ArrayList<>();
        for(int i =0; i< eventList.size(); i++){
            eventList.get(i);
            Log.d("tag","eventList from main " + eventList);
        }

        mAdapter = new EventAdapter(eventList);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mAdapter);
    }*/
}//MainActivity

事件适配器

public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
    private ArrayList<EventItem> mEventList;
    Context context;

    //constructor for EventAdapter
    public EventAdapter(ArrayList<EventItem> eventList){
        // context =c;
        mEventList = eventList;
        Log.d("tag","EventAdapter eventlist variable called from constructor " + eventList);
    }


    public static class EventViewHolder extends RecyclerView.ViewHolder{
        public ImageView mPromoImage;
        public TextView mTitle;
        public TextView mStartDate;
        public TextView mEndDate;
        public TextView mLocation;
        public TextView mFee;
        public ImageView mFavourite;

        //constructor for EventViewHolder class
        public EventViewHolder(View itemView) {
            super(itemView);
          //  mPromoImage = (ImageView) itemView.findViewById(R.id.event_promotional_image);
            mTitle = (TextView) itemView.findViewById(R.id.event_title_textView);
            mStartDate = (TextView) itemView.findViewById(R.id.event_start_textView);
            mEndDate = (TextView) itemView.findViewById(R.id.event_end_textView);
            mLocation = (TextView) itemView.findViewById(R.id.event_location_textView);
            mFee = (TextView) itemView.findViewById(R.id.event_fee_textView);
         //   mFavourite = (ImageView) itemView.findViewById(R.id.event_favourite_image);
            Log.d("tag", "EventViewHolder being called");
        }
    }//EventViewHolder class



    @Override
    public EventViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_event, parent, false);
        //create view holder
        EventViewHolder viewHolder = new EventViewHolder(v);
        return viewHolder;
    }

    //pass values to inflated XML Views in item_event.xml
    @Override
    public void onBindViewHolder(EventViewHolder holder, int position) {
        EventItem currentEvent = mEventList.get(position);
      //  holder.mPromoImage.setImageResource(currentEvent.getEventPromoImage());
        holder.mTitle.setText(currentEvent.getEventTitle());
        holder.mStartDate.setText(currentEvent.getEventStartDate());
        holder.mEndDate.setText(currentEvent.getEventEndDate());
        holder.mLocation.setText(currentEvent.getEventLocation());
        holder.mFee.setText(String.valueOf(currentEvent.getEventFee()));//int value passed
      //  holder.mFavourite.setImageResource(currentEvent.getEventFavourite());
        //Log.d("tag", "position" + position );
        Log.d("tag","eventAdapter " + currentEvent.getEventTitle());
    }

    //how many items there will be
    @Override
    public int getItemCount() {
        return mEventList.size();
    }
}

事件项

public class EventItem {
    private int mEventPromoImage;
    private int mId;
    private String mEventTitle;
    private String mEventStartDate;
    private String mEventEndDate;
    private String mEventLocation;
    private int mEventFee;
    private int mEventViews;


   // public EventItem(){}

    public EventItem(int id, String eventTitle, String eventStartDate,
                     String eventEndDate, String eventLocation, int eventFee, int eventViews){
       // mEventPromoImage = eventPromoImage;
        mId = id;
        mEventTitle = eventTitle;
        mEventStartDate = eventStartDate;
        mEventEndDate = eventEndDate;
        mEventLocation = eventLocation;
        mEventFee = eventFee;
        mEventViews = eventViews;
        Log.d("tag","EVENTITEM title EventItem" + mEventTitle);
      //  Log.d("tag","EVENTITEM startDate EventItem" + mEventStartDate );
      //  Log.d("tag","EVENTITEM endDate EventItem" + mEventEndDate );
      //  Log.d("tag","EVENTITEM address EventItem" + mEventLocation);
      //  Log.d("tag","EVENTITEM fee EventItem" + mEventFee);
    }



    public int getEventPromoImage() {
        return mEventPromoImage;
    }

    public void setEventPromoImage(int mEventPromoImage) {
        this.mEventPromoImage = mEventPromoImage;
    }

    public int getEventId() {
        return mId;
    }

    public void setEventId(int mId){
        this.mId = mId;
    }

    public String getEventTitle() {
        Log.d("tag","getEventTitle() " + mEventTitle);
        return mEventTitle;
    }

    public void setEventTitle(String mEventTitle) {
        this.mEventTitle = mEventTitle;
    }

    public String getEventStartDate() {
        return mEventStartDate;
    }

    public void setEventStartDate(String mEventStartDate) {
        this.mEventStartDate = mEventStartDate;
    }

    public String getEventEndDate(){
        return mEventEndDate;
    }

    public void setEventEndDate(String mEventEndDate){
        this.mEventEndDate = mEventEndDate;
    }

    public String getEventLocation() {
        return mEventLocation;
    }

    public void setEventLocation(String mEventLocation) {
        this.mEventLocation = mEventLocation;
    }

    public int getEventFee() {
        return mEventFee;
    }

    public void setEventFee(int mEventFee) {
        this.mEventFee = mEventFee;
    }

    public int getEventViews(){
        return mEventViews;
    }

    public void getEventViews(int mEventViews) {
        this.mEventViews = mEventViews;
    }

    public ArrayList<EventItem> getRecyclerList(){
        ArrayList event = new ArrayList();
        event.add(mEventTitle);
        event.add(mEventStartDate);
        event.add(mEventEndDate);
        event.add(mEventLocation);
        event.add(mEventFee);
        event.add(mEventViews);
        return event;
    }
}

EventBackgroundWorker

public class EventBackgroundWorker extends AsyncTask<String, Void, String> {
    Context context;
    AlertDialog alert;
    public static final String REQUEST_URL = "http://10.0.2.2/m/event/";

    public EventBackgroundWorker(Context ctxt) {
        context = ctxt;
    }

    //Invoked on UI thread before doInBackground is called
    @Override
    protected void onPreExecute() {
        alert = new AlertDialog.Builder(context).create();
        alert.setTitle("Result from server");

    }

    @Override
    protected String doInBackground(String... params) {
        String type = params[0];//eventList
        //String login_url = "http://10.0.2.2/m/event/";
        if(type.equals("event")){
            try {
                String user_name = params[1];
                URL url = new URL(REQUEST_URL);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setDoInput(true);
                httpURLConnection.connect();//works without this connect Find out why

                OutputStream outputStream = httpURLConnection.getOutputStream();
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
                String post_data = URLEncoder.encode("getEvents", "UTF-8");
                bufferedWriter.write(post_data);
                bufferedWriter.flush();
                bufferedWriter.close();
                outputStream.close();

                //read response
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
                String result = "";
                String line;
                while((line = bufferedReader.readLine()) != null){
                    result += line;
                }

                //parse JSON event Array

                // Create an empty ArrayList that we can start adding events to
                ArrayList<EventItem> eventArray = new ArrayList<>();

                JSONArray baseJsonResponse = new JSONArray(result);
                for(int i =0; i < baseJsonResponse.length(); i++){
                    JSONObject event = baseJsonResponse.getJSONObject(i);
                    int id = event.getInt("id");
                    String title = event.getString("title");
                    String address = event.getString("address");
                    String startDate = event.getString("startDate");
                    String endDate = event.getString("endDate");
                    int fee = event.getInt("fee");
                    int views = event.getInt("views");

                    //Send data to eventItem Object
                    EventItem eventObject = new EventItem(id,title,address,startDate,endDate,fee,views);
                    eventArray.add(eventObject);
                  /*  Log.d("tag", "JSON id " + id);
                    Log.d("tag", "JSON title " + title);
                    Log.d("tag", "JSON address " + address);
                    Log.d("tag", "JSON startDate " + startDate);
                    Log.d("tag", "JSON endDate " + endDate);
                    Log.d("tag", "JSON fee " + fee);
                    Log.d("tag", "JSON views " + views);*/
                }

                bufferedReader.close();
                inputStream.close();
                httpURLConnection.disconnect();

                return result;

            } catch (MalformedURLException e) {//added for URL object
                e.printStackTrace();
            } catch (IOException e) {
                //HTPURLConnection
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
    }

    //results from doInBackground are passed here
    @Override
    protected void onPostExecute(String result) {
        Log.d("tag", "onPostExecute called" + result);
        alert.setMessage(result);
        alert.show();

    }

}

标签: androidandroid-recyclerviewandroid-asynctask

解决方案


AsyncTask 创建 eventArray 但不做任何事情。doInBackground() 应该返回 eventArray 并且 onPostExecute() 应该将其设置为适配器内容(通过回调或通过在 AsyncTask 对象中设置适配器实例)。您的适配器应该有一个内容设置器,它应该调用 notifyDataSetChanged()。


推荐阅读