Skip to content

Commit 9f113cd

Browse files
committed
Added some improvements for states onResume/onPause.
1 parent 2a69f24 commit 9f113cd

2 files changed

Lines changed: 158 additions & 0 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.telegram.messenger;
2+
3+
import android.app.Activity;
4+
import android.os.Handler;
5+
import android.os.Looper;
6+
import android.view.View;
7+
8+
/**
9+
* Helper class to manage app lifecycle and prevent white screen issues
10+
*/
11+
public class LifecycleHelper {
12+
private static final String TAG = "LifecycleHelper";
13+
private static final long UI_RESTORE_DELAY = 100;
14+
15+
private static Handler mainHandler = new Handler(Looper.getMainLooper());
16+
17+
/**
18+
* Ensures UI components are visible and properly restored
19+
*/
20+
public static void ensureUIVisible(Activity activity, View... views) {
21+
if (activity == null || activity.isFinishing()) {
22+
return;
23+
}
24+
25+
mainHandler.post(() -> {
26+
try {
27+
for (View view : views) {
28+
if (view != null && view.getVisibility() != View.VISIBLE) {
29+
view.setVisibility(View.VISIBLE);
30+
}
31+
}
32+
} catch (Exception e) {
33+
FileLog.e(TAG, e);
34+
}
35+
});
36+
}
37+
38+
/**
39+
* Delays UI restoration to ensure proper initialization
40+
*/
41+
public static void delayedUIRestore(Runnable restoreAction) {
42+
if (restoreAction == null) {
43+
return;
44+
}
45+
46+
mainHandler.postDelayed(() -> {
47+
try {
48+
restoreAction.run();
49+
} catch (Exception e) {
50+
FileLog.e(TAG, e);
51+
}
52+
}, UI_RESTORE_DELAY);
53+
}
54+
55+
/**
56+
* Checks if the app needs to restore its state
57+
*/
58+
public static boolean needsStateRestore(Activity activity) {
59+
if (activity == null) {
60+
return false;
61+
}
62+
63+
// Check if main UI components are missing or invisible
64+
View contentView = activity.findViewById(android.R.id.content);
65+
return contentView == null || contentView.getVisibility() != View.VISIBLE;
66+
}
67+
}

TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
import org.telegram.messenger.UserNameResolver;
129129
import org.telegram.messenger.UserObject;
130130
import org.telegram.messenger.Utilities;
131+
import org.telegram.messenger.LifecycleHelper;
131132
import org.telegram.messenger.browser.Browser;
132133
import org.telegram.messenger.pip.PipActivityController;
133134
import org.telegram.messenger.pip.activity.IPipActivity;
@@ -965,6 +966,20 @@ public void onPreviewOpenAnimationEnd() {
965966
}
966967
checkLayout();
967968
checkSystemBarColors();
969+
970+
// Handle app restoration after process kill
971+
if (savedInstanceState != null) {
972+
// Ensure fragments are properly restored
973+
if (actionBarLayout.getFragmentStack().isEmpty()) {
974+
if (UserConfig.getInstance(currentAccount).isClientActivated()) {
975+
DialogsActivity dialogsActivity = new DialogsActivity(null);
976+
dialogsActivity.setSideMenu(sideMenu);
977+
actionBarLayout.addFragmentToStack(dialogsActivity);
978+
drawerLayoutContainer.setAllowOpenDrawer(true, false);
979+
}
980+
}
981+
}
982+
968983
handleIntent(getIntent(), false, savedInstanceState != null, false, null, true, true);
969984
try {
970985
String os1 = Build.DISPLAY;
@@ -6779,6 +6794,11 @@ protected void onPause() {
67796794
pipActivityHandler.onPause();
67806795
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 4096);
67816796
ApplicationLoader.mainInterfacePaused = true;
6797+
6798+
// Ensure UI state is properly saved before going to background
6799+
if (actionBarLayout != null) {
6800+
actionBarLayout.saveLastFragment();
6801+
}
67826802
int account = currentAccount;
67836803
Utilities.stageQueue.postRunnable(() -> {
67846804
ApplicationLoader.mainInterfacePausedStageQueue = true;
@@ -6832,6 +6852,21 @@ protected void onStart() {
68326852
if (GroupCallActivity.groupCallInstance != null) {
68336853
GroupCallActivity.groupCallInstance.onResume();
68346854
}
6855+
6856+
// Ensure fragments are properly restored after app comes back from background
6857+
if (actionBarLayout != null && actionBarLayout.getFragmentStack().isEmpty()) {
6858+
// If fragment stack is empty, restore default fragment
6859+
if (UserConfig.getInstance(currentAccount).isClientActivated()) {
6860+
DialogsActivity dialogsActivity = new DialogsActivity(null);
6861+
if (sideMenu != null) {
6862+
dialogsActivity.setSideMenu(sideMenu);
6863+
}
6864+
actionBarLayout.addFragmentToStack(dialogsActivity);
6865+
if (drawerLayoutContainer != null) {
6866+
drawerLayoutContainer.setAllowOpenDrawer(true, false);
6867+
}
6868+
}
6869+
}
68356870
}
68366871

68376872
@Override
@@ -6972,6 +7007,27 @@ protected void onResume() {
69727007
onResumeStaticCallback.run();
69737008
onResumeStaticCallback = null;
69747009
}
7010+
7011+
// Fix for white screen issue after device sleep
7012+
LifecycleHelper.ensureUIVisible(this, frameLayout, drawerLayoutContainer);
7013+
7014+
// Delayed UI restore if needed
7015+
if (LifecycleHelper.needsStateRestore(this)) {
7016+
LifecycleHelper.delayedUIRestore(() -> {
7017+
if (actionBarLayout != null && actionBarLayout.getFragmentStack().isEmpty()) {
7018+
if (UserConfig.getInstance(currentAccount).isClientActivated()) {
7019+
DialogsActivity dialogsActivity = new DialogsActivity(null);
7020+
if (sideMenu != null) {
7021+
dialogsActivity.setSideMenu(sideMenu);
7022+
}
7023+
actionBarLayout.addFragmentToStack(dialogsActivity);
7024+
if (drawerLayoutContainer != null) {
7025+
drawerLayoutContainer.setAllowOpenDrawer(true, false);
7026+
}
7027+
}
7028+
}
7029+
});
7030+
}
69757031
if (Theme.selectedAutoNightType == Theme.AUTO_NIGHT_TYPE_SYSTEM) {
69767032
Theme.checkAutoNightThemeConditions();
69777033
}
@@ -8193,6 +8249,12 @@ public void hideVisibleActionMode() {
81938249
protected void onSaveInstanceState(Bundle outState) {
81948250
try {
81958251
super.onSaveInstanceState(outState);
8252+
8253+
// Save current account and app state
8254+
outState.putInt("currentAccount", currentAccount);
8255+
outState.putBoolean("isActive", isActive);
8256+
outState.putBoolean("isResumed", isResumed);
8257+
outState.putBoolean("isStarted", isStarted);
81968258
BaseFragment lastFragment = null;
81978259
if (AndroidUtilities.isTablet()) {
81988260
if (layersActionBarLayout != null && !layersActionBarLayout.getFragmentStack().isEmpty()) {
@@ -8236,6 +8298,35 @@ protected void onSaveInstanceState(Bundle outState) {
82368298
FileLog.e(e);
82378299
}
82388300
}
8301+
8302+
@Override
8303+
protected void onRestoreInstanceState(Bundle savedInstanceState) {
8304+
try {
8305+
super.onRestoreInstanceState(savedInstanceState);
8306+
8307+
// Restore app state
8308+
if (savedInstanceState != null) {
8309+
int savedAccount = savedInstanceState.getInt("currentAccount", currentAccount);
8310+
if (savedAccount != currentAccount && UserConfig.isValidAccount(savedAccount)) {
8311+
switchToAccount(savedAccount, false);
8312+
}
8313+
8314+
isActive = savedInstanceState.getBoolean("isActive", true);
8315+
isResumed = savedInstanceState.getBoolean("isResumed", false);
8316+
isStarted = savedInstanceState.getBoolean("isStarted", false);
8317+
8318+
// Ensure UI is visible after restore
8319+
if (frameLayout != null) {
8320+
frameLayout.setVisibility(View.VISIBLE);
8321+
}
8322+
if (drawerLayoutContainer != null) {
8323+
drawerLayoutContainer.setVisibility(View.VISIBLE);
8324+
}
8325+
}
8326+
} catch (Exception e) {
8327+
FileLog.e(e);
8328+
}
8329+
}
82398330

82408331
@Override
82418332
public void onBackPressed() {

0 commit comments

Comments
 (0)