RecyclerView 不显示从本地主机发送的 JSON 只是空白屏幕

Posted

技术标签:

【中文标题】RecyclerView 不显示从本地主机发送的 JSON 只是空白屏幕【英文标题】:RecyclerView not showing JSON sent from localhost just blank screen 【发布时间】:2018-11-20 19:07:13 【问题描述】:

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

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

我认为 RecyclerView 是在从 localhost 检索 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();

    


【问题讨论】:

【参考方案1】:

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

【讨论】:

嗨乔纳斯感谢您的回复和解决方案,它运行良好

以上是关于RecyclerView 不显示从本地主机发送的 JSON 只是空白屏幕的主要内容,如果未能解决你的问题,请参考以下文章

从本地主机发送电子邮件

如何配置 XAMPP PHP 通过安全 smtp 我的 ISP 从本地主机发送邮件

使用 gmail 从本地主机发送邮件

使用 gmail 从本地主机发送电子邮件

无法将数据发送到 recyclerview

无法使用汞 XAMPP 从本地主机发送 Drupal 通知邮件