Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 更新RecyclerView数据会降低活动的UI速度_Java_Android_Android Recyclerview_Android Room - Fatal编程技术网

Java 更新RecyclerView数据会降低活动的UI速度

Java 更新RecyclerView数据会降低活动的UI速度,java,android,android-recyclerview,android-room,Java,Android,Android Recyclerview,Android Room,我正在开发聊天应用程序,在显示聊天信息时遇到一些问题。对于存储,我使用房间数据库,为了显示消息,我使用了RecyclerView。问题是,在滚动消息时,活动变得非常缓慢,响应速度也不太快 这是我的密码: ChatActivity.java public class ChatActivity extends AppCompatActivity { public static final String TAG = ChatActivity.class.getSimpleName();

我正在开发聊天应用程序,在显示聊天信息时遇到一些问题。对于存储,我使用房间数据库,为了显示消息,我使用了RecyclerView。问题是,在滚动消息时,活动变得非常缓慢,响应速度也不太快

这是我的密码:

ChatActivity.java

public class ChatActivity extends AppCompatActivity {
    public static final String TAG = ChatActivity.class.getSimpleName();

    public static Contact contact;
    public static boolean isContactConnected;

    private CircleImageView mContactPicture;
    private ImageView mContactConnected;
    private TextView mContactName;
    private TextView mContactStatus;

    private ChatAdapter mChatAdapter;
    private RecyclerView mRecyclerView;

    private EmojiconEditText mUserMessageInput;

    private View rootView;
    private ImageView emojiImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        initializeToolbar();

        String contactPhone = Objects.requireNonNull(getIntent().getStringExtra("phone"));
        contact = MainActivity.db.getContactDao().findByPhone(contactPhone);

        if (MainActivity.notificationMessages.get(contact.getId()) != null) {
            MainActivity.notificationMessages.put(contact.getId(), new ArrayList<Message>());
        }

        updateUI(contact);
        initializeViews();
        initializeRecyclerView();

        EmojIconActions emojIconActions = new EmojIconActions(this, rootView, mUserMessageInput, emojiImageView);
        emojIconActions.ShowEmojIcon();
        emojIconActions.setIconsIds(R.drawable.ic_baseline_keyboard_24, R.drawable.ic_baseline_emoji_emotions_24);

        mChatAdapter = new ChatAdapter(this, new ArrayList<Message>());
        mRecyclerView.setAdapter(mChatAdapter);

        MainActivity.db.getMessageDao().getLiveMessages(contactPhone).observe(this, new Observer<List<Message>>() {
            @Override
            public void onChanged(List<Message> newMessages) {
                mChatAdapter.setMessages(newMessages);
                mRecyclerView.scrollToPosition(newMessages.size() - 1);
            }
        });
    }

    [...]

    private void updateUI(Contact contact) {
        mContactName.setText(contact.getName());

        if (!contact.isConnected()) {
            Date currentTime = Calendar.getInstance().getTime();
            SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.US);

            isContactConnected = false;
            mContactStatus.setText(
                    String.format(
                            "Last seen %s",
                            DateManager.getLastActiveText(
                                    df.format(currentTime),
                                    contact.getLastActive()
                            )
                    )
            );

            mContactConnected.setVisibility(View.GONE);

            Log.d(TAG, "updateUI: initialized contact UI as disconnected");
        } else {
            mContactStatus.setText(R.string.active_now);
            mContactConnected.setVisibility(View.VISIBLE);
            isContactConnected = true;

            Log.d(TAG, "updateUI: initialized contact UI as connected");
        }

        if (contact.getPhotoUri() != null) {
            Uri imageUri = Uri.parse(contact.getPhotoUri());

            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
                mContactPicture.setImageBitmap(bitmap);

                Log.d(TAG, "updateUI: loaded contact photo from device");
            } catch (IOException e) {
                Toast.makeText(
                        ChatActivity.this,
                        "Failed to load image from device.",
                        Toast.LENGTH_SHORT
                ).show();

                e.printStackTrace();
            }
        }
    }

    [...]

    private void initializeRecyclerView() {
        mRecyclerView = findViewById(R.id.chat_recycler_view);

        RecyclerView.LayoutManager layoutManager =
                new LinearLayoutManager(ChatActivity.this, LinearLayoutManager.VERTICAL, false);
        mRecyclerView.setLayoutManager(layoutManager);

        Log.d(TAG, "initializeRecyclerView: initialized RecyclerView");
    }

    [...]
}
MessageDao.java

@Dao
public interface MessageDao {
    @Query("SELECT * FROM messages WHERE to_from = :contact ORDER BY timestamp")
    List<Message> getMessages(String contact);

    @Query("SELECT * FROM messages WHERE to_from = :contact ORDER BY timestamp")
    LiveData<List<Message>> getLiveMessages(String contact);

    @Query("SELECT * FROM messages WHERE to_from =:contact AND status = 0")
    List<Message> getUndeliveredMessages(String contact);

    @Query("SELECT * FROM messages WHERE payloadId = :payloadId LIMIT 1")
    Message getMessageByPayloadId(long payloadId);

    @Query("SELECT * FROM messages WHERE to_from = :contact ORDER BY timestamp DESC LIMIT 1")
    Message getLastMessage(String contact);

    @Query("SELECT * FROM messages WHERE to_from = :contact ORDER BY timestamp DESC LIMIT 1")
    LiveData<Message> getLastLiveMessage(String contact);

    @Query("DELETE FROM messages")
    void deleteAllMessages();

    @Insert
    void addMessage(Message message);

    @Update
    void updateMessage(Message message);

    @Delete
    void deleteMessage(Message message);
}
ChatOtherViewHolder.java

class ChatItemViewHolder extends RecyclerView.ViewHolder {
    private CircleImageView mUserProfilePic;
    private ImageView mUserStatus;
    private TextView mUserProfileName;
    private EmojiconTextView mLastMessage;
    private TextView mTimestamp;

    public ChatItemViewHolder(@NonNull View itemView) {
        super(itemView);

        mUserProfilePic = itemView.findViewById(R.id.contact_image_item);
        mUserProfileName = itemView.findViewById(R.id.contact_name_item);
        mUserStatus = itemView.findViewById(R.id.status);
        mLastMessage = itemView.findViewById(R.id.contact_status_item);
        mTimestamp = itemView.findViewById(R.id.timestamp);
    }

    public CircleImageView getUserProfilePic() {
        return mUserProfilePic;
    }

    public ImageView getUserStatus() {
        return mUserStatus;
    }

    public TextView getUserProfileName() {
        return mUserProfileName;
    }

    public EmojiconTextView getLastMessage() {
        return mLastMessage;
    }

    public TextView getTimestamp() {
        return mTimestamp;
    }
}
class ChatOtherViewHolder extends RecyclerView.ViewHolder {
    private CircleImageView mSenderProfilePicture;
    private TextView mSenderName;
    private EmojiconTextView mMessageContent;
    private TextView mTimestamp;
    private ImageView mMessageStatus;

    public ChatOtherViewHolder(@NonNull View itemView) {
        super(itemView);

        mSenderProfilePicture = itemView.findViewById(R.id.sender_profile_pic);
        mSenderName = itemView.findViewById(R.id.sender_name);
        mMessageContent = itemView.findViewById(R.id.message_content);
        mTimestamp = itemView.findViewById(R.id.message_timestamp);
        mMessageStatus = itemView.findViewById(R.id.message_status);
    }

    public CircleImageView getSenderProfilePicture() {
        return mSenderProfilePicture;
    }

    public TextView getSenderName() {
        return mSenderName;
    }

    public EmojiconTextView getMessageContent() {
        return mMessageContent;
    }

    public TextView getTimestamp() {
        return mTimestamp;
    }

    public ImageView getMessageStatus() {
        return mMessageStatus;
    }
}
显然,问题来自RV。起初我认为在UI线程上运行的observe方法可能会导致问题,但我替换了onChanged方法中的操作,UI非常平滑,因此只有在尝试更新RV项时才会出现问题


我能做些什么来解决这个问题?

我看到了两个大问题

  • 永远不要在适配器中进行数据库调用,因为在适配器中使用数据库调用代价太高

  • 您还可以将整个位图加载到内存中,使用图像加载库来加载图像,它们处理循环视图,并将图像大小调整为异步加载所需的大小


  • 事实上,就是这样!非常感谢你!我使用Glide加载图像,并在实例化时将联系人数据传递给适配器,现在它可以完美地工作了!谢谢:D
    class ChatItemViewHolder extends RecyclerView.ViewHolder {
        private CircleImageView mUserProfilePic;
        private ImageView mUserStatus;
        private TextView mUserProfileName;
        private EmojiconTextView mLastMessage;
        private TextView mTimestamp;
    
        public ChatItemViewHolder(@NonNull View itemView) {
            super(itemView);
    
            mUserProfilePic = itemView.findViewById(R.id.contact_image_item);
            mUserProfileName = itemView.findViewById(R.id.contact_name_item);
            mUserStatus = itemView.findViewById(R.id.status);
            mLastMessage = itemView.findViewById(R.id.contact_status_item);
            mTimestamp = itemView.findViewById(R.id.timestamp);
        }
    
        public CircleImageView getUserProfilePic() {
            return mUserProfilePic;
        }
    
        public ImageView getUserStatus() {
            return mUserStatus;
        }
    
        public TextView getUserProfileName() {
            return mUserProfileName;
        }
    
        public EmojiconTextView getLastMessage() {
            return mLastMessage;
        }
    
        public TextView getTimestamp() {
            return mTimestamp;
        }
    }
    
    class ChatOtherViewHolder extends RecyclerView.ViewHolder {
        private CircleImageView mSenderProfilePicture;
        private TextView mSenderName;
        private EmojiconTextView mMessageContent;
        private TextView mTimestamp;
        private ImageView mMessageStatus;
    
        public ChatOtherViewHolder(@NonNull View itemView) {
            super(itemView);
    
            mSenderProfilePicture = itemView.findViewById(R.id.sender_profile_pic);
            mSenderName = itemView.findViewById(R.id.sender_name);
            mMessageContent = itemView.findViewById(R.id.message_content);
            mTimestamp = itemView.findViewById(R.id.message_timestamp);
            mMessageStatus = itemView.findViewById(R.id.message_status);
        }
    
        public CircleImageView getSenderProfilePicture() {
            return mSenderProfilePicture;
        }
    
        public TextView getSenderName() {
            return mSenderName;
        }
    
        public EmojiconTextView getMessageContent() {
            return mMessageContent;
        }
    
        public TextView getTimestamp() {
            return mTimestamp;
        }
    
        public ImageView getMessageStatus() {
            return mMessageStatus;
        }
    }