Skip to content

Commit 607ec5e

Browse files
authored
Merge pull request #9 from FastComments/memory-management
Memory Management Improvements
2 parents 549a294 + fbbc052 commit 607ec5e

File tree

5 files changed

+184
-10
lines changed

5 files changed

+184
-10
lines changed

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,70 @@ Available color customization options:
253253
| `fastcomments_action_button_color` | Primary | Color of action buttons |
254254
| `fastcomments_load_more_button_text_color` | Primary | Color of load more button text |
255255

256+
## Memory Management
257+
258+
### Preventing Memory Leaks
259+
260+
To prevent memory leaks when using FastComments views in Activities or Fragments, always call `cleanup()` when the view is no longer needed:
261+
262+
#### In Activities:
263+
```java
264+
@Override
265+
protected void onDestroy() {
266+
super.onDestroy();
267+
// Clean up FastComments views to prevent memory leaks
268+
if (feedView != null) {
269+
feedView.cleanup();
270+
}
271+
if (commentsView != null) {
272+
commentsView.cleanup();
273+
}
274+
}
275+
```
276+
277+
#### In Fragments:
278+
```java
279+
@Override
280+
public void onDestroyView() {
281+
super.onDestroyView();
282+
// Clean up FastComments views when fragment view is destroyed
283+
if (feedView != null) {
284+
feedView.cleanup();
285+
feedView = null;
286+
}
287+
}
288+
289+
@Override
290+
public void onDestroy() {
291+
super.onDestroy();
292+
// Additional cleanup when fragment is destroyed
293+
if (feedSDK != null) {
294+
feedSDK.cleanup();
295+
feedSDK = null;
296+
}
297+
}
298+
```
299+
300+
#### When Switching Fragments:
301+
```java
302+
// Before replacing or removing a fragment containing FastComments views
303+
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container);
304+
if (currentFragment instanceof YourFragmentWithFeedView) {
305+
((YourFragmentWithFeedView) currentFragment).cleanupFeedView();
306+
}
307+
308+
// Then proceed with fragment transaction
309+
getSupportFragmentManager().beginTransaction()
310+
.replace(R.id.container, newFragment)
311+
.commit();
312+
```
313+
314+
**Important**: Always call `cleanup()` methods to prevent memory leaks, especially when:
315+
- Activities are destroyed
316+
- Fragment views are destroyed
317+
- Switching between fragments
318+
- Navigating away from screens with FastComments components
319+
256320
## License
257321

258322
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

app/src/main/java/com/fastcomments/FeedExampleActivity.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,13 @@ public void onImagePickerRequested() {
266266
}
267267
});
268268
}
269+
270+
@Override
271+
protected void onDestroy() {
272+
super.onDestroy();
273+
// Clean up the feed view to prevent memory leaks
274+
if (feedView != null) {
275+
feedView.cleanup();
276+
}
277+
}
269278
}

libraries/sdk/src/main/java/com/fastcomments/sdk/FastCommentsFeedSDK.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,25 @@ public void cleanup() {
625625
liveEventSubscription.close();
626626
liveEventSubscription = null;
627627
}
628+
// Clear listener references to prevent memory leaks
629+
this.onPostDeletedListener = null;
630+
631+
// Clear collections to help GC
632+
if (feedPosts != null) {
633+
feedPosts.clear();
634+
}
635+
if (postsById != null) {
636+
postsById.clear();
637+
}
638+
if (likeCounts != null) {
639+
likeCounts.clear();
640+
}
641+
if (myReacts != null) {
642+
myReacts.clear();
643+
}
644+
if (broadcastIdsSent != null) {
645+
broadcastIdsSent.clear();
646+
}
628647
}
629648

630649
/**

libraries/sdk/src/main/java/com/fastcomments/sdk/FastCommentsFeedView.java

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -273,22 +273,33 @@ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
273273
* @param sdk The FastCommentsFeedSDK instance
274274
*/
275275
public void setSDK(FastCommentsFeedSDK sdk) {
276+
// Clean up existing SDK if any
277+
if (this.sdk != null) {
278+
this.sdk.setOnPostDeletedListener(null);
279+
}
280+
276281
this.sdk = sdk;
277282
if (adapter == null) {
278283
initAdapter(getContext());
279284
}
280285

281286
// Register for post deletion events from live WebSocket
282-
sdk.setOnPostDeletedListener(postId -> {
283-
handler.post(() -> {
284-
// Update adapter with the current list from SDK
285-
// This ensures the adapter's list is in sync with the SDK after a post is deleted
286-
adapter.updatePosts(sdk.getFeedPosts());
287-
288-
// Log for debugging
289-
Log.d("FastCommentsFeedView", "Received post deletion event for post ID: " + postId);
287+
if (sdk != null) {
288+
sdk.setOnPostDeletedListener(postId -> {
289+
if (handler != null && adapter != null) {
290+
handler.post(() -> {
291+
// Update adapter with the current list from SDK
292+
// This ensures the adapter's list is in sync with the SDK after a post is deleted
293+
if (sdk != null && adapter != null) {
294+
adapter.updatePosts(sdk.getFeedPosts());
295+
}
296+
297+
// Log for debugging
298+
Log.d("FastCommentsFeedView", "Received post deletion event for post ID: " + postId);
299+
});
300+
}
290301
});
291-
});
302+
}
292303
}
293304

294305
/**
@@ -949,10 +960,43 @@ public boolean onSuccess(APIEmptyResponse response) {
949960
@Override
950961
protected void onDetachedFromWindow() {
951962
super.onDetachedFromWindow();
963+
cleanup();
964+
}
965+
966+
/**
967+
* Clean up all resources to prevent memory leaks.
968+
* Call this method when the view will no longer be used.
969+
*/
970+
public void cleanup() {
952971
stopPolling();
972+
973+
// Clear adapter data
974+
if (adapter != null) {
975+
adapter.updatePosts(new ArrayList<>());
976+
}
977+
978+
// Clear SDK listener reference
953979
if (sdk != null) {
980+
sdk.setOnPostDeletedListener(null);
954981
sdk.cleanup();
982+
sdk = null;
955983
}
984+
985+
// Clear local references
986+
listener = null;
987+
988+
// Clear collections
989+
if (feedPosts != null) {
990+
feedPosts.clear();
991+
}
992+
993+
// Clear handler callbacks
994+
if (handler != null && pollStatsRunnable != null) {
995+
handler.removeCallbacks(pollStatsRunnable);
996+
}
997+
998+
// Clear polling runnable
999+
pollStatsRunnable = null;
9561000
}
9571001

9581002
/**

libraries/sdk/src/main/java/com/fastcomments/sdk/FastCommentsView.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1728,12 +1728,50 @@ private void updateReplyButtonText(String commentId, boolean isReplying) {
17281728
@Override
17291729
protected void onDetachedFromWindow() {
17301730
super.onDetachedFromWindow();
1731+
cleanup();
1732+
}
1733+
1734+
/**
1735+
* Clean up all resources to prevent memory leaks.
1736+
* Call this method when the view will no longer be used.
1737+
*/
1738+
public void cleanup() {
17311739
// Stop the timer when the view is detached to prevent memory leaks
17321740
stopDateUpdateTimer();
1733-
// Clean up WebSocket connections when the view is detached
1741+
1742+
// Clear SDK and WebSocket connections
17341743
if (sdk != null) {
17351744
sdk.cleanup();
1745+
sdk = null;
1746+
}
1747+
1748+
// Clear listeners
1749+
commentPostListener = null;
1750+
1751+
// Clear back pressed callback
1752+
if (backPressedCallback != null) {
1753+
backPressedCallback.setEnabled(false);
1754+
backPressedCallback = null;
17361755
}
1756+
1757+
// Clear adapter data through SDK
1758+
if (sdk != null && sdk.commentsTree != null) {
1759+
sdk.commentsTree.clear();
1760+
if (adapter != null) {
1761+
adapter.notifyDataSetChanged();
1762+
}
1763+
}
1764+
1765+
// Clear currently replying state
1766+
currentlyReplyingToCommentId = null;
1767+
1768+
// Clear handler callbacks
1769+
if (dateUpdateHandler != null) {
1770+
dateUpdateHandler.removeCallbacksAndMessages(null);
1771+
}
1772+
1773+
// Clear runnables
1774+
dateUpdateRunnable = null;
17371775
}
17381776

17391777
/**

0 commit comments

Comments
 (0)