如何将 AsyncTask 从 Adapter onBindViewHolder() 移动到 Activity onChildEventListener

Posted

技术标签:

【中文标题】如何将 AsyncTask 从 Adapter onBindViewHolder() 移动到 Activity onChildEventListener【英文标题】:How to move AsyncTask FROM Adapter onBindViewHolder() TO Activity onChildEventListener 【发布时间】:2021-02-07 03:39:57 【问题描述】:

我正在使用 RecyclerView 来显示推文,其中一些数据存储在 Firebase 中。当应用程序启动时,我使用 ChildEventListener 来填充提要,这将有助于以后添加新推文并且必须更新提要时提高效率。我的问题是某些数据需要使用 twitter4j API(即 Tweet 的个人资料图片的作者)检索,并且不能存储在 Firebase 中。我目前在我的适配器 onBindViewHolder() 中使用 AsyncTask 获取这些数据。我很好奇如何改为在我的 ChildEventListener 中完成此操作,以便在设置适配器之前数据可用。当我在我的适配器 onBindViewHolder() 中运行 AsyncTask 时,配置文件图像需要一些时间来加载,这显然不符合用户体验。

异步任务:

public class StatusAsyncTask extends AsyncTask<Long, Integer, Status>

  TweetListAdapterFeed tweetListAdapterFeed;
  TweetListAdapterFeed.ViewHolder viewHolder;
  int position;

  public StatusAsyncTask(TweetListAdapterFeed tweetListAdapterFeed, TweetListAdapterFeed.ViewHolder viewHolder, int position)
  
    this.tweetListAdapterFeed = tweetListAdapterFeed;
    this.viewHolder = viewHolder;
    this.position = position;
  

  protected twitter4j.Status doInBackground(Long... tweetStatusId)
  
    ConfigurationBuilder cb = new ConfigurationBuilder();
    TwitterFactory tf = new TwitterFactory(cb.build());
    Twitter twitter = tf.getInstance();
    twitter4j.Status status;

    try
    
      status = twitter.showStatus(tweetStatusId[0]);
      return status;
    
    catch (TwitterException e)
    
      e.printStackTrace();
      return null;
    
  

  protected void onPostExecute(twitter4j.Status status)
  
    if (status != null)
    
      viewHolder.retweetCount.setText(String.valueOf(status.getRetweetCount()));
      viewHolder.likeCount.setText(String.valueOf(status.getFavoriteCount()));

      Picasso.get().load(status.getUser().get400x400ProfileImageURL()).fit().into(viewHolder.profileImage);
    
  

TweetListAdapterFeed onBindViewHolder():

  @Override
  public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int i)
  
    int viewType = holder.getItemViewType();
    final ViewHolder viewHolder = (ViewHolder)holder;

    // Update Like and Retweet Count via AsyncTask
    new StatusAsyncTask(this, viewHolder, i).execute(mData.get(i).getTweetStatusID());

    ...
  

ChildEventListener:

public static final List<TweetData> listFeedList = new ArrayList<>();
public static TweetListAdapterFeed mAdapter;

ChildEventListener tweetChildEventListener = new ChildEventListener()

  @Override
  public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s)
  
    if (dataSnapshot.exists())
    
      TweetData tweetData = dataSnapshot.getValue(TweetData.class);
      if ((tweetData != null) && (!tweetData.tweetText.equals("")))
      
        listFeedList.add(listFeedList.size(), tweetData);
        mAdapter.notifyItemInserted(listFeedList.size());
      
    
  

【问题讨论】:

【参考方案1】:

如果我理解您的意思,您希望在添加新项目的同时准备好照片。这可以做到,但是当你得到一个新数据时,你必须使用与你的StatusAsyncTask相同的类并接收照片并将其完全传递给你的适配器,即下载照片并传递存储到适配器的照片的地址。这是一条艰难的道路

但获得更好视图的更简单方法是在 XML 中为照片使用固定的占位符图像。

另一种方式是use Picasso's own placeholder。

【讨论】:

以上是关于如何将 AsyncTask 从 Adapter onBindViewHolder() 移动到 Activity onChildEventListener的主要内容,如果未能解决你的问题,请参考以下文章

如何将变量从 AsyncTask 返回到 Android 中的 Google Map 活动

如果使用 Asynctask 将 URL 存储在 ArrayList 中,如何从服务器下载图像?

如何使用 asynctask 将图像从 android 上传到 php

如何使用 AsyncTask 将图像从 drawable 加载到 listView

如何将数据从AsyncTask返回到主线程

如何在 AsyncTask 的后执行方法中获取对 recyclerveiw 适配器进度条的引用