Android - Performing stop of activity that is not resumed

匿名 (未验证) 提交于 2019-12-03 02:51:02

问题:

When I push my app to background, and do some other stuff like whatsapp or sms, onResume it works great.
But I recently discovered that when I open/launch facebook app while my app is on background, I don't know what happens...
But onResume, the app misbehaves...
Don't do what it is required to do, but when I go back to homepage and come back it works fine Please help me out.. how to fix it ???

Logcat with all messages (without filter)

10-15 12:53:59.899: I/Adreno-EGL(32033): Remote Branch: quic/LNX.LA.3.5.1_RB1.1 10-15 12:53:59.899: I/Adreno-EGL(32033): Local Patches: NONE 10-15 12:53:59.899: I/Adreno-EGL(32033): Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING 10-15 12:53:59.924: D/OpenGLRenderer(32033): Enabling debug mode 0 10-15 12:54:00.000: V/AlarmManager(7677): sending alarm Alarm{42cfa490 type 3 android} 10-15 12:54:00.110: I/ActivityManager(7677): Displayed uk.org.humanfocus.hfi/.EvaluateTrainingActivity: +838ms 10-15 12:54:00.114: D/WifiStateMachine(7677): handleMessage: E msg.what=151572 10-15 12:54:00.114: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:00.114: D/WifiStateMachine(7677): processMsg: L2ConnectedState 10-15 12:54:02.258: V/AlarmManager(7677): sending alarm Alarm{42ebd600 type 1 com.facebook.katana} 10-15 12:54:02.274: V/AlarmManager(7677): sending alarm Alarm{42ec0ff0 type 1 com.android.chrome} 10-15 12:54:02.428: D/hardware_info(7386): hw_info_append_hw_type : device_name = speaker 10-15 12:54:03.011: W/BroadcastQueue(7677): Permission Denial: broadcasting Intent { act=android.net.conn.INET_CONDITION_ACTION flg=0x4000010 (has extras) } from null (pid=-1, uid=-1) requires com.facebook.permission.prod.FB_APP_COMMUNICATION due to registered receiver BroadcastFilter{41fdecd0 u0 ReceiverList{42b2f608 31941 com.facebook.katana/10103/u0 remote:429a17e8}} 10-15 12:54:03.011: W/BroadcastQueue(7677): Permission Denial: broadcasting Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } from null (pid=-1, uid=-1) requires com.facebook.permission.prod.FB_APP_COMMUNICATION due to registered receiver BroadcastFilter{41fdecd0 u0 ReceiverList{42b2f608 31941 com.facebook.katana/10103/u0 remote:429a17e8}} 10-15 12:54:03.118: D/WifiStateMachine(7677): handleMessage: E msg.what=151572 10-15 12:54:03.118: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:03.118: D/WifiStateMachine(7677): processMsg: L2ConnectedState 10-15 12:54:03.140: D/WifiStateMachine(7677): handleMessage: X 10-15 12:54:03.141: D/GCoreFlp(8174): Unknown pending intent to remove. 10-15 12:54:03.145: W/fb4a(:):AbstractMqttPushService(31941): Attempt to start service that is already started 10-15 12:54:03.242: D/WifiStateMachine(7677): handleMessage: E msg.what=131155 10-15 12:54:03.242: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:03.243: D/WifiStateMachine(7677): processMsg: L2ConnectedState 10-15 12:54:03.245: D/WifiStateMachine(7677): handleMessage: X 10-15 12:54:03.319: D/dalvikvm(31941): GC_CONCURRENT freed 1833K, 9% free 20190K/22072K, paused 5ms+7ms, total 86ms 10-15 12:54:03.320: D/dalvikvm(31941): WAIT_FOR_CONCURRENT_GC blocked 68ms 10-15 12:54:03.323: W/MediaPlayer-JNI(31941): MediaPlayer finalized without being released 10-15 12:54:03.452: W/BroadcastQueue(7677): Permission Denial: broadcasting Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } from null (pid=-1, uid=-1) requires com.facebook.permission.prod.FB_APP_COMMUNICATION due to registered receiver BroadcastFilter{42b51d68 u0 ReceiverList{429feb50 31941 com.facebook.katana/10103/u0 remote:41fb8788}} 10-15 12:54:03.573: W/fb4a(:):JACKSON_FALLBACK(31941): Using com.fasterxml.jackson.databind.deser.std.EnumDeserializer@42914bc8 to deserialize [simple type, class com.facebook.common.util.TriState] 10-15 12:54:03.587: W/fb4a(:):JACKSON_FALLBACK(31941): Using com.fasterxml.jackson.databind.deser.std.EnumDeserializer@42bb3100 to deserialize [simple type, class com.facebook.contacts.graphql.contactprofiletype.ContactProfileType] 10-15 12:54:03.957: D/dalvikvm(31941): GC_CONCURRENT freed 3400K, 15% free 20455K/23952K, paused 4ms+7ms, total 88ms 10-15 12:54:03.957: D/dalvikvm(31941): WAIT_FOR_CONCURRENT_GC blocked 75ms 10-15 12:54:04.099: W/fb4a(:):JACKSON_FALLBACK(31941): Using BeanSerializer for com.facebook.katana.newbookmark.qe.NewBookmarkConfig to serialize class com.facebook.katana.newbookmark.qe.NewBookmarkConfig 10-15 12:54:04.119: D/WifiStateMachine(7677): handleMessage: E msg.what=151572 10-15 12:54:04.120: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:04.120: D/WifiStateMachine(7677): processMsg: L2ConnectedState 10-15 12:54:04.124: D/WifiStateMachine(7677): handleMessage: X 10-15 12:54:04.177: W/fb4a(:):JACKSON_FALLBACK(31941): Using com.fasterxml.jackson.databind.deser.std.EnumDeserializer@42a30980 to deserialize [simple type, class com.facebook.platform.webdialogs.PlatformWebViewActionManifest$FetchState] 10-15 12:54:04.197: I/dalvikvm(31941): Could not find method com.android.internal.widget.ILockSettings$Stub.a, referenced from method com.facebook.keyguardtype.LockSettingsServiceKeyguardTypeResolver.b 10-15 12:54:04.197: W/dalvikvm(31941): VFY: unable to resolve static method 5338: Lcom/android/internal/widget/ILockSettings$Stub;.a (Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings; 10-15 12:54:04.197: D/dalvikvm(31941): VFY: replacing opcode 0x71 at 0x0023 10-15 12:54:04.440: I/SBar.NetworkController(7758): onSignalStrengthsChanged SignalStrength: 19 0 -120 -160 -120 -1 -1 99 2147483647 2147483647 2147483647 2147483647 2147483647 gsm|lte 0 -108 -1 false 5 5 0 0 0 99 99 99 5 level=5 10-15 12:54:04.814: V/WebViewChromiumFactoryProvider(31941): Binding Chromium to main looper Looper (main, tid 1) {41f8cbd0} 10-15 12:54:04.815: I/LibraryLoader(31941): Expected native library version number "",actual native library version number "" 10-15 12:54:04.816: I/chromium(31941): [INFO:library_loader_hooks.cc(116)] Chromium logging enabled: level = 0, default verbosity = 0 10-15 12:54:04.817: I/BrowserStartupController(31941): Initializing chromium process, renderers=0 10-15 12:54:04.822: E/AudioManagerAndroid(31941): BLUETOOTH permission is missing! 10-15 12:54:04.864: W/chromium(31941): [WARNING:proxy_service.cc(890)] PAC support disabled because there is no system implementation 10-15 12:54:05.121: D/WifiStateMachine(7677): handleMessage: E msg.what=151572 10-15 12:54:05.121: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:05.122: D/WifiStateMachine(7677): processMsg: L2ConnectedState 

And this is onResume()

super.onResume();          if (backgroundThreadRunning == true) {             backgroundThreadRunning = false;         }          if (Constants.isVideoEditing)             editingProgress.setVisibility(View.VISIBLE);         else             editingProgress.setVisibility(View.GONE);          if (Constants.isAudioProcessing)             addAudioProgress.setVisibility(View.VISIBLE);         else             addAudioProgress.setVisibility(View.GONE);          if (isHomeKeyPressed() && !(isRecentActivity)) {             isRecentActivity = false;             homeKeyPressed(false);             AlertDialog.Builder ab = new AlertDialog.Builder(                     CreateTrainingActivity.this);             ab.setMessage(                     "Due to Other Application Launches, video process will be cancelled!\nAre you sure you want to cancel?")                     .setPositiveButton("Yes", dialogClickListener)                     .setNegativeButton("No", dialogClickListener).show();         }      }; 

EDIT: HOW I FIXED THE ISSUE

I wrote this code in onResume() method

try {     // check if any view exists on current view     style = ((Button) findViewById(R.id.xyz_button));    } catch (Exception e) {     // Button was not found     // It means, your button doesn't exist on the "current" view     // It was freed from the memory, therefore stop of activity was performed     // In this case I restart my app     Intent i = new Intent();     i.setClass(getApplicationContext(), MainActivity.class);     i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);     startActivity(i);     // Show toast to the user     Toast.makeText(getApplicationContext(), "Data lost due to excess use of other apps", Toast.LENGTH_LONG).show(); } 

回答1:

Just giving my 50 cents on the issue. Catching the exception is indeed one possibility, but the correct way to deal with the issue of an activity being killed by the system for its resources in background is a common problem in android and according to Google the solution for this is:

onPause() is where you deal with the user leaving your activity. Most importantly, any changes made by the user should at this point be committed (usually to the ContentProvider holding the data).

Emphasis is mine. But what this means is that the Android lifecycles are designed so that under normal conditions onPause should be called as an Activity or Fragment is sent to the background. They hint at this in several of the android documentation pages:

As your activity enters the paused state, the system calls the onPause() method on your Activity, which allows you to stop ongoing actions that should not continue while paused (such as a video) or persist any information that should be permanently saved in case the user continues to leave your app. If the user returns to your activity from the paused state, the system resumes it and calls the onResume() method.

Note: When your activity receives a call to onPause(), it may be an indication that the activity will be paused for a moment and the user may return focus to your activity. However, it's usually the first indication that the user is leaving your activity.

But the resource that could most likely help you are these two:

http://developer.android.com/training/basics/activity-lifecycle/stopping.html

http://developer.android.com/training/basics/activity-lifecycle/recreating.html

What's probably happening with your lost resources is this:

When your activity receives a call to the onStop() method, it's no longer visible and should release almost all resources that aren't needed while the user is not using it. Once your activity is stopped, the system might destroy the instance if it needs to recover system memory. ... By default, the system uses the Bundle instance state to save information about each View object in your activity layout (such as the text value entered into an EditText object). So, if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. However, your activity might have more state information that you'd like to restore, such as member variables that track the user's progress in the activity.

Note: In order for the Android system to restore the state of the views in your activity, each view must have a unique ID, supplied by the android:id attribute.

To save additional data about the activity state, you must override the onSaveInstanceState() callback method. The system calls this method when the user is leaving your activity and passes it the Bundle object that will be saved in the event that your activity is destroyed unexpectedly. If the system must recreate the activity instance later, it passes the same Bundle object to both the onRestoreInstanceState() and onCreate() methods.

The correct solution for this is to override and implement the lifecycle methods of the Activity / Fragment as needed.

Two examples given by Google:

    static final String STATE_SCORE = "playerScore"; static final String STATE_LEVEL = "playerLevel"; ...  @Override public void onSaveInstanceState(Bundle savedInstanceState) {     // Save the user's current game state     savedInstanceState.putInt(STATE_SCORE, mCurrentScore);     savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);      // Always call the superclass so it can save the view hierarchy state     super.onSaveInstanceState(savedInstanceState); } Caution: Always call the superclass implementation of onSaveInstanceState() so the default implementation can save the state of the view hierarchy. 

And the reverse restore operation:

public void onRestoreInstanceState(Bundle savedInstanceState) {     // Always call the superclass so it can restore the view hierarchy     super.onRestoreInstanceState(savedInstanceState);      // Restore state members from saved instance     mCurrentScore = savedInstanceState.getInt(STATE_SCORE);     mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } 


回答2:

One Line: It seems some of your activity variables were freed from memory as Android OS needed memory for the Facebook application.

Explanation: When an application in foreground needs more memory than that is available, Android frees some memory from the apps that are running in background. Foreground tasks always have higher priority than background applications.

So, what might have happened to your application while it was in background is that some of its variables have lost their values which you are using in your onResume(). Because of this they are holding wrong values or default values (you can check by using Sysout) as they are re-created when you again bring your app to foreground and due to which some of your code is not working right.



回答3:

Hopefully you've addressed the issue already, but there is an error in your code, perhaps related:

if (backgroundThreadRunning = true) {     backgroundThreadRunning = false; } 

you are assigning instead of comparing in the "if" statement. Should be:

if (backgroundThreadRunning == true) {     backgroundThreadRunning = false; } 

or

if (backgroundThreadRunning) {     backgroundThreadRunning = false; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!