Skip to content

SyncBroadcastReceiver in FileDisplayActivity Triggers Multiple Times Causing Repeated Directory Listing #14855

Description

@alperozturk96

Steps to reproduce

  1. Upload files in a directory.
  2. Observe FileDisplayActivity.SyncBroadcastReceiver being triggered multiple times during the process.
  3. As a result, listDirectory() is called repeatedly.
  4. These repeated calls lead to multiple invocations of OCFileListAdapter.swapDirectory().

Suggestion

The broadcast receiver should be triggered only when necessary, and directory listing should occur a single time per meaningful change.

Activity

  1. changed the title [-]SyncBroadcastReceiver in FileDisplayActivity Triggers Multiple Times Causing Repeated Directory Listing and UI Issues[/-] [+]SyncBroadcastReceiver in FileDisplayActivity Triggers Multiple Times Causing Repeated Directory Listing[/+] on May 2, 2025
  2. alperozturk96 commented on Jun 6, 2025

    @alperozturk96
    CollaboratorAuthor

    Currently, the following code retrieves the path of the remote folder that needs to be synchronized:

    String synchFolderRemotePath = intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH);

    Subsequently, we fetch the list of remote files inside that folder with:

    RemoteOperationResult synchResult = (RemoteOperationResult) DataHolderUtil.getInstance().retrieve(intent.getStringExtra(FileSyncAdapter.EXTRA_RESULT));

    Given that we already have access to the current list of files in the local directory, we can calculate and compare the hash codes of both local and remote file lists. If the hash codes match, we can safely skip the synchronization process. If they differ, we proceed with the update.

    This approach would result in a significant performance improvement. Even a single unnecessary folder update currently triggers a full directory listing, including database queries, thumbnail cache checks, and redundant rendering of thumbnails for each file.

    Implementation Steps

    Convert FileDisplayActivity.SyncBroadcastReceiver to Kotlin (First PR)

    Refactor the logic for better readability, maintainability and performance.

    **Introduce Hash Code Comparison (Second PR)**Implement the hash code comparison logic within FileDisplayActivity.SyncBroadcastReceiver.

    Analyze SyncBroadcastReceiver Usage (Third PR)

    Review the usage of FileDisplayActivity.SyncBroadcastReceiver throughout the codebase. Identify and remove any redundant or unnecessary triggers if it exists.

    Better OCFileListAdapter implementation - this is big one and should be discussed in different issue


    These steps will bring the Android implementation more in line with iOS in terms of performance and state management, and it's a noticeable user experience improvement.

    For each change, we must validate the following functional areas:

    • Folder and file listing behavior
    • "Favorites", "Shared with you", "Personal", and "On-device files" filters.
    • General sync behavior such as folder sync, file download.

    I believe we should prioritize this task.

    @tobiasKaminsky @ZetaTom Please let me know if this approach is acceptable. I can start working on the first pull request.

  3. alperozturk96 commented on Jun 12, 2025

    @alperozturk96
    CollaboratorAuthor

    To prevent unnecessary calls, the following broadcast events should be reviewed.

    FileSyncAdapter.EVENT_FULL_SYNC_START, 
    FileSyncAdapter.EVENT_FULL_SYNC_END, 
    FileSyncAdapter.EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED,
    RefreshFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED,
    RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED
    

    After eliminating any redundant event triggers, we can explore alternative solutions if the issue persists.

  4. alperozturk96 commented on Jun 13, 2025

    @alperozturk96
    CollaboratorAuthor

    In the FileSyncAdapter.onPerformSync method, we currently send two broadcast events:

    sendLocalBroadcast(EVENT_FULL_SYNC_START, null, null);
    // ...
    // ...
    // ...
    sendLocalBroadcast(EVENT_FULL_SYNC_END, null, mLastFailedResult);
    
    

    EVENT_FULL_SYNC_START is used to set mSyncInProgress boolean variables.

  5. ZetaTom commented on Jul 9, 2025

    @ZetaTom
    Collaborator

    As mentioned in #15081, these broadcast events may also cause other side effects. In the FileDisplayActivity, currentDir is sometimes null when rapidly switching between tabs (Files, Favourites and Media). This causes can cause issues, for example #15103.

    Investigating this issue and minimising broadcast events should increase overall reliability and decrease and the number of UI glitches and edge cases we have to handle.

  6. alperozturk96 commented on Jul 10, 2025

    @alperozturk96
    CollaboratorAuthor

    Steps to reproduce the null currentDir scenario:

    1. Open the Shared section from the navigation drawer.
    2. Then, navigate to All Files using the bottom navigation bar.
  7. alperozturk96 commented on Apr 20, 2026

    @alperozturk96
    CollaboratorAuthor

    The listDirectory function inside OCFileListFragment is being called multiple times unnecessarily, even for the same directory. This results in the entire list being recreated over and over again.

    There are many entry points triggering listDirectory, including:

    • onResume in FileDisplayActivity
    • onActivityCreated in OCFileListFragment
    • Broadcast receivers for download and upload completion
    • Sync receiver after a folder refresh operation
    • File deletion events, and others

    I tried several approaches to prevent these redundant calls, but none have worked so far:

    • Comparing eTags: I compared the locally stored eTag with the result from CheckEtagOperation, but it always reports the eTag as changed. This might be caused by some database writes to OCFile that unintentionally affect the stored eTag.

    • Using OCFile.hashCode(): This also didn’t help. Even small changes (e.g., marking a file as favorite) modify a field in OCFile, which should be reflected in the UI. That means the entire list needs to be compared carefully, and missing even one field can lead to incorrect UI state.

    • Debouncing listDirectory calls: This approach feels unsafe. It could ignore legitimate user actions (like taps) and is too fragile to rely on as a solution.

  8. linked a pull request that will close this issuefix(file-list): list directory 🚀 #17438on Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementperformance 🚀Performance improvement opportunities (non-crash related)

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions