Skip to content

Commit bfad195

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

2 files changed

Lines changed: 155 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: 88 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,8 @@ protected void onPause() {
67796794
pipActivityHandler.onPause();
67806795
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 4096);
67816796
ApplicationLoader.mainInterfacePaused = true;
6797+
6798+
// UI state is handled by existing fragment lifecycle methods
67826799
int account = currentAccount;
67836800
Utilities.stageQueue.postRunnable(() -> {
67846801
ApplicationLoader.mainInterfacePausedStageQueue = true;
@@ -6832,6 +6849,21 @@ protected void onStart() {
68326849
if (GroupCallActivity.groupCallInstance != null) {
68336850
GroupCallActivity.groupCallInstance.onResume();
68346851
}
6852+
6853+
// Ensure fragments are properly restored after app comes back from background
6854+
if (actionBarLayout != null && actionBarLayout.getFragmentStack().isEmpty()) {
6855+
// If fragment stack is empty, restore default fragment
6856+
if (UserConfig.getInstance(currentAccount).isClientActivated()) {
6857+
DialogsActivity dialogsActivity = new DialogsActivity(null);
6858+
if (sideMenu != null) {
6859+
dialogsActivity.setSideMenu(sideMenu);
6860+
}
6861+
actionBarLayout.addFragmentToStack(dialogsActivity);
6862+
if (drawerLayoutContainer != null) {
6863+
drawerLayoutContainer.setAllowOpenDrawer(true, false);
6864+
}
6865+
}
6866+
}
68356867
}
68366868

68376869
@Override
@@ -6972,6 +7004,27 @@ protected void onResume() {
69727004
onResumeStaticCallback.run();
69737005
onResumeStaticCallback = null;
69747006
}
7007+
7008+
// Fix for white screen issue after device sleep
7009+
LifecycleHelper.ensureUIVisible(this, frameLayout, drawerLayoutContainer);
7010+
7011+
// Delayed UI restore if needed
7012+
if (LifecycleHelper.needsStateRestore(this)) {
7013+
LifecycleHelper.delayedUIRestore(() -> {
7014+
if (actionBarLayout != null && actionBarLayout.getFragmentStack().isEmpty()) {
7015+
if (UserConfig.getInstance(currentAccount).isClientActivated()) {
7016+
DialogsActivity dialogsActivity = new DialogsActivity(null);
7017+
if (sideMenu != null) {
7018+
dialogsActivity.setSideMenu(sideMenu);
7019+
}
7020+
actionBarLayout.addFragmentToStack(dialogsActivity);
7021+
if (drawerLayoutContainer != null) {
7022+
drawerLayoutContainer.setAllowOpenDrawer(true, false);
7023+
}
7024+
}
7025+
}
7026+
});
7027+
}
69757028
if (Theme.selectedAutoNightType == Theme.AUTO_NIGHT_TYPE_SYSTEM) {
69767029
Theme.checkAutoNightThemeConditions();
69777030
}
@@ -8193,6 +8246,12 @@ public void hideVisibleActionMode() {
81938246
protected void onSaveInstanceState(Bundle outState) {
81948247
try {
81958248
super.onSaveInstanceState(outState);
8249+
8250+
// Save current account and app state
8251+
outState.putInt("currentAccount", currentAccount);
8252+
outState.putBoolean("isActive", isActive);
8253+
outState.putBoolean("isResumed", isResumed);
8254+
outState.putBoolean("isStarted", isStarted);
81968255
BaseFragment lastFragment = null;
81978256
if (AndroidUtilities.isTablet()) {
81988257
if (layersActionBarLayout != null && !layersActionBarLayout.getFragmentStack().isEmpty()) {
@@ -8236,6 +8295,35 @@ protected void onSaveInstanceState(Bundle outState) {
82368295
FileLog.e(e);
82378296
}
82388297
}
8298+
8299+
@Override
8300+
protected void onRestoreInstanceState(Bundle savedInstanceState) {
8301+
try {
8302+
super.onRestoreInstanceState(savedInstanceState);
8303+
8304+
// Restore app state
8305+
if (savedInstanceState != null) {
8306+
int savedAccount = savedInstanceState.getInt("currentAccount", currentAccount);
8307+
if (savedAccount != currentAccount && UserConfig.isValidAccount(savedAccount)) {
8308+
switchToAccount(savedAccount, false);
8309+
}
8310+
8311+
isActive = savedInstanceState.getBoolean("isActive", true);
8312+
isResumed = savedInstanceState.getBoolean("isResumed", false);
8313+
isStarted = savedInstanceState.getBoolean("isStarted", false);
8314+
8315+
// Ensure UI is visible after restore
8316+
if (frameLayout != null) {
8317+
frameLayout.setVisibility(View.VISIBLE);
8318+
}
8319+
if (drawerLayoutContainer != null) {
8320+
drawerLayoutContainer.setVisibility(View.VISIBLE);
8321+
}
8322+
}
8323+
} catch (Exception e) {
8324+
FileLog.e(e);
8325+
}
8326+
}
82398327

82408328
@Override
82418329
public void onBackPressed() {

0 commit comments

Comments
 (0)