在 AsyncTask 的 onPostExecute 之后,无法按意图更新 RecyclerView

Posted

技术标签:

【中文标题】在 AsyncTask 的 onPostExecute 之后,无法按意图更新 RecyclerView【英文标题】:Unable to update RecyclerView in intent after onPostExecute from AsyncTask 【发布时间】:2019-06-05 15:10:20 【问题描述】:

我正在尝试在发出 HTTP 请求后更新 RecyclerView。使用以下要点中的代码,我可以打开 android 活动,呈现一个空白的 RecyclerView,并从 HTTP 请求中获取数据。我无法使用来自 HTTP 请求的数据更新 RecyclerView。

以下是相关数据的两个类的链接

ItemSelection.java

ItemSelectionAdapter.java

目前,即使我有数据,在收到 HTTP 响应后,RecyclerView 中也没有显示任何内容。 HTTP 响应后如何填充 RecyclerView?

【问题讨论】:

请不要只在场外链接到您的代码。您需要在问题本身中提供minimal reproducible example。 【参考方案1】:

我认为您缺少适配器视图中的列表项计数,请在您的 ItemSelectionAdapter 中更新以下方法

 @Override
public int getItemCount() 
    return data.size();

它是否可以帮助您解决问题,另一件事是您正在将适配器设置为在后执行方法中回收视图,因此无需在设置适配器后调用方法

 adapter.notifyDataSetChanged();

设置新适配器回收视图后不需要调用上述行

【讨论】:

【参考方案2】:

基本上你做错了,因为你在 onPostExecute 创建 Recyclerview 这是不好的做法,而不是这样做

像这样调用 AsyncTask

 public class HomeFragment extends Fragment 

    // RecyclerView
    RecyclerView recyclerView;
    RecyclerView.Adapter rvAdapter;
    RecyclerView.LayoutManager rvLayoutManger;
    List<NewsData> news_list;

  @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        news_list = new ArrayList<NewsData>();
    


    @Nullable
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 

        View view = inflater.inflate(R.layout.activity_home, null);

        // RecyclerView Setup
        recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view1);
        rvLayoutManger = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(rvLayoutManger);
        rvAdapter = new HomeRecyclerAdapter(getActivity(), news_list);
        recyclerView.setAdapter(rvAdapter);


        load_data_from_server(0);

        return view;
    

    private void load_data_from_server(int id) 
        AsyncTask<Integer, Void, Void> task = new AsyncTask<Integer, Void, Void>() 
            @Override
            protected Void doInBackground(Integer... integers) 
                OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder().url("http://here is my url ").build();
                try 
                    Response response = client.newCall(request).execute();

                    JSONArray array = new JSONArray(response.body().toString());

                    for (int i = 0; i < array.length(); i++) 
                        JSONObject object = array.getJSONObject(i);

                        NewsData data = new NewsData(object.getInt("id"), object.getString("title"), object.getString("describtion"));
                        news_list.add(data);

                    

                 catch (IOException e) 
                    e.printStackTrace();
                 catch (JSONException e) 
                    System.out.print("End of  content");
                
                return null;
            

            @Override
            protected void onPostExecute(Void aVoid) 
                rvAdapter.notifyDataSetChanged();
            
        ;

        task.execute(id);
    

在对象类中传递数据

public class NewsData 

private int id;
private String title, describtion;

public NewsData(int id, String title, String describtion)
    this.id = id;
    this.title = title;
    this.describtion = describtion;



public int getId() 
    return id;


public void setId(int id) 
    this.id = id;


public String getTitle()
    return title;


public void  setTitle(String title)
    this.title = title;


public String getDescribtion()
    return describtion;


public void setDescribtion(String describtion) 
    this.describtion = describtion;

见适配器将从上面定义适配器设置与 arraylist 组成数据

rvAdapter = new HomeRecyclerAdapter(getActivity(), news_list);

【讨论】:

以上是关于在 AsyncTask 的 onPostExecute 之后,无法按意图更新 RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章

如何在修改之前在 AsyncTask 中使用变量?

AsyncTask

Android AsyncTask get()形成另一个AsyncTask()

Android面试Android异步任务AsyncTask

AsyncTask 替代背景图像下载? (AsyncTask ---------已弃用)

在服务中使用 AsyncTask