Прокрутка RecyclerView медленно — setHasStableIds не работает, можно предварительно загрузить более одного закадрового просмотра?

#android #android-recyclerview

#Android #android-recyclerview

Вопрос:

Я пытался исправить медленную прокрутку в приложении, похожем на Twitter, с помощью RecyclerView, используя предложения из this [link] [1], и у меня возникли проблемы с #7 «setHasStableIds (true)». Когда я не переопределяю getItemId(), я получаю только около 6 элементов в моем RecyclerView из 30. Когда я переопределяю его и возвращаю position или tweetStatusID для функции, он по-прежнему отстает, как когда я не использовал setHasStableIds (true) для своего адаптера.

ОБНОВЛЕНО: я добавил несколько асинхронных задач, которые улучшили мою скорость, но все еще медленно, мне было любопытно, можно ли внести какие-либо дополнительные улучшения или можно ли предварительно загрузить больше просмотров, чтобы при быстрой прокрутке было готово больше.

MyFeed onCreate():

 super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed);
final RecyclerView recyclerView = findViewById(R.id.rv_feed);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());

DatabaseReference databaseReference;

// Create new Twitter configuration
ConfigurationBuilder cb = new ConfigurationBuilder();

// Create Twitter instance for retweeting
TwitterFactory tf = new TwitterFactory(cb.build());
twitter = tf.getInstance();

authTokenToken = getIntent().getStringExtra("AUTH_TOKEN_TOKEN");
authTokenSecret = getIntent().getStringExtra("AUTH_TOKEN_SECRET");

// Firebase Auth
mAuth = FirebaseAuth.getInstance();
dbFeedPath = getResources().getString(R.string.isu_feed);
databaseReference = FirebaseDatabase.getInstance().getReference(dbFeedPath);

databaseReference.addValueEventListener(new ValueEventListener()
{
  @Override
  public void onDataChange(@NonNull final DataSnapshot dataSnapshot)
  {
    AsyncTask.execute(new Runnable()
    {
      @Override
      public void run()
      {
        listFeedList.clear();

        for (DataSnapshot postSnapshot : dataSnapshot.getChildren())
        {
          TweetData tweetData = postSnapshot.getValue(TweetData.class);

          if ((tweetData != null) amp;amp; (!tweetData.tweetText.equals("")))
          {
            TweetData listTweetData = new TweetData(tweetData);

            listFeedList.add(listTweetData);
          }
        }
      }
    });

    mAdapter.notifyDataSetChanged();
  }

  @Override
  public void onCancelled(@NonNull DatabaseError databaseError)
  {
  }
});


mAdapter = new TweetListAdapterFeed(listFeedList, this.getApplicationContext(), new ClickListener()
{
});

mAdapter.setHasStableIds(true);
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(mAdapter);
  

Адаптер:

 public class TweetListAdapterFeed extends RecyclerView.Adapter<TweetListAdapterFeed.ViewHolder>
{
  private static List<TweetData> mData;
  private static Context context;
  public static FirebaseAuth mAuth;
  private static String dbFeedPath;
  private static ClickListener clickListener;

  ConfigurationBuilder cb;
  TwitterFactory tf;
  Twitter twitter;

  public TweetListAdapterFeed(@SuppressWarnings("SameParameterValue") List<TweetData> mData,
                              Context context, ClickListener clickListener)
  {
    TweetListAdapterFeed.mData = mData;
    TweetListAdapterFeed.context = context;
    TweetListAdapterFeed.clickListener = clickListener;
  }

  @NonNull
  @Override
  public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
  {
    dbFeedPath = context.getString(R.string.isu_feed);

    ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(viewGroup.getContext())
                                           .inflate(R.layout.feed_list_item, viewGroup,
                                          false), clickListener);

    statusAsyncTask = new StatusAsyncTask(this, viewHolder, i);
    mediaAsyncTaskFeed = new MediaAsyncTaskFeed(this, viewHolder);

    return viewHolder;
  }

  @Override
  public void onBindViewHolder(@NonNull final ViewHolder viewHolder, final int i)
  {
    // Update Like and Retweet Count via AsyncTask
    statusAsyncTask.execute(mData.get(i).getTweetStatusID());

    // Tweet Media
    if (!mData.get(i).getTweetPic1().equals(""))
    {
      viewHolder.photo1.setVisibility(View.VISIBLE);
      viewHolder.photo1.setImageResource(R.drawable.loading_image);
      mediaAsyncTaskFeed.execute(mData.get(i).getTweetPic1());
    }
    else
    {
      viewHolder.photo1.setVisibility(View.GONE);
    }

    // Twitter Profile Image
    Picasso.get().load(mData.get(i).getProfileImage()).fit().into(viewHolder.profileImage);

    // Twitter Name
    viewHolder.twitterName.setText(mData.get(i).getTwitterName());

    // Twitter Handle
    String tString = context.getString(R.string.AtSymbol)   mData.get(i).getTwitterHandle();
    viewHolder.twitterHandle.setText(tString);

    // Tweet Time, converted to Time since Tweet was posted
    String timeAgo = convertDateToTimeAgo(mData.get(i).getTweetTime());
    viewHolder.tweetDate.setText(timeAgo);

    // Tweet Text
    viewHolder.tweetText.setText(mData.get(i).getTweetText());

    // Retweeted By
    if (!mData.get(i).getRetweetedBy().equals(""))
    {
      // Tweet was a Retweet
      viewHolder.retweetedBy.setText(mData.get(i).getRetweetedBy());
      viewHolder.retweetedBy.setVisibility(View.VISIBLE);
      viewHolder.imageRetweetedBy.setVisibility(View.VISIBLE);
    }
    else
    {
      // Tweet was original
      viewHolder.retweetedBy.setText("");
      viewHolder.retweetedBy.setVisibility(View.GONE);
      viewHolder.imageRetweetedBy.setVisibility(View.GONE);
    }
  }

  /*
  @Override
  public long getItemId(int position)
  {
    return position; //TweetListAdapterFeed.mData.get(position).getTweetStatusID();
  }
   */
  

Комментарии:

1. Вы вызываете StrictMode.ThreadPolicy.Builder().permitAll().build() , который специально позволяет вам выполнять сверхмедленные действия в основном потоке. Конечно, это будет отставать, если вы это сделаете.

2. Вы использовали AsyncTasks в 2020 году, а Java не Kotlin?

3. @IgorGanapolsky Я новичок, это мое первое приложение, что вы предлагаете вместо асинхронных задач? Кроме того, я родом из мира C , поэтому Java было легко подобрать, со временем изучу Kotlin.

4. @BiCURE Пожалуйста, посмотрите на сопрограммы Kotlin для асинхронного программирования: developer.android.com/kotlin/coroutines