So I have a strange problem, and I'm not entirely sure what all information I should provide, but I'll do my best -- just let me know if I need to add more info. I'm having an issue that when I finish my Activity and return to the previous Activity (or launch it with a new Intent -- the problem seems to be centered on finishing the Activity) the UI performance drops drastically for about six or seven seconds, then returns to normal.
From LogCat, this warning appears consistently:
07-11 22:09:42.594: W/ActivityManager(292): Launch timeout has expired, giving up wake lock!
07-11 22:09:42.601: W/ActivityManager(292): Activity idle timeout for ActivityRecord{42bf6e00 com.kcoppock.sudokubeta/com.kcoppock.sudoku.SudokuBoardActivity}
As soon as the activity times out, UI performance returns to normal. Until that point it is very sluggish. I have no code that I am aware of that could be blocking the main thread, and I've even gone so far as to comment out my entire onPause() method to see if it makes any difference, and it does not.
The Activity does not spawn any background threads, does not perform any network activity, the only disk access it has is some accessing of SharedPreferences. The previous questions I've been able to locate are about idle timeouts for HistoryRecord, not ActivityRecord.
Any ideas what would cause this? Or how I could go about determining what is blocking the UI thread, if that is what is happening?
EDIT : Okay, just tried commenting out everything except super.onCreate() and setContentView() -- the problem still persists. It doesn't occur with any other Activities but this one, but there's NOTHING TO this one. :/
Oh geez. One of those things that's pretty hard to diagnose outside of trial and error, but I've figured it out. For reference, should anyone else have this problem, it came down to a custom view in my layout. I had added a ViewTreeObserver.OnGlobalLayoutListener() to do some layout modifications after the layout pass, but within that listener I modified the layout and thus caused another layout, essentially creating an infinite loop (but somehow not causing an ANR). My solution was like so:
private class BoardLayoutListener implements OnGlobalLayoutListener {
#Override
public void onGlobalLayout() {
//...do stuff here
//REMOVE this listener so that you don't repeat this forever
ViewTreeObserver obs = SudokuBoard.this.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this);
}
}
This solution is quite ironic, considering my second highest rated answer on StackOverflow specifically deals with this. :P
sigh
I've had the same issue today but as it turned out to have a different cause and solution I decided to add the information here just in case it might help someone else.
In my case problem was caused because I had the following line inside my onActivityResult() method:
android.os.Debug.waitForDebugger();
I Just deleted the line and the problem was gone.
This line is usually used to synchronize the debugger with the OS threads but I just figured it shouldn't be used anywhere. Oddly the problem would not appear until I had my phone disconnected from the desktop.
Regards
Related
I ran into a very strange issue with postponing transition.
I postponed the return transition in onActivityReenter. But the problem here is that if I checked „Don’t keep activities“ in the settings of the phone, the app will most of the times just hang and show both activities over each other.
I found out that in that case onActivityReenter still gets called. But onPreDraw doesn’t, which should be called by the onPreDrawListener and resumes the postponed transition. So I postpone the transition forever.
What could have happened there?
The code can be found here.
I've been running into the same issue. It's only in specific cases, and even then not 100% of the time.
Requesting the layout again after adding the listener works for me.
myView.getViewTreeObserver().addOnPreDrawListener(<snip>);
myView.requestLayout(); //Force a layout pass
I'm pretty sure this is indicative of a bug somewhere in Android, but I haven't been able to create a reliable test case. Somehow, it's skipping part of the layout pass, so the listener doesn't ever get called. Calling requestLayout() forces the full layout pass to happen.
I'm facing a serious problem with the Croutons Notification Library,
When i quickly switch my activites, sometimes (very often indeed) croutons for updates, like missing credentials, or "insert date first" are not shown anymore,
and so the users stay without any info, what's the problem.
For instance also the simple usecase:
Login To Application,
Logout,
try to re-login but with false credentials,
doesnt show a crouton anymore.
I tried:
Courton.clearAllNotifcations() in inPause(),
and additionally,
Crouton.clearCroutonsForActivity(this) too in onPause(),
to maybe solve the Problem, but it didn't.
I also debugged in the CroutonLibrary and the problem seems to be,
a Crouton gets added to queue, the the activity gets finished, the something finishes (like aSyncTask showing a crouton in onPostExecute(), this one gets added to the queue again, and then the queue is stuck.
Also.clearAllNotifications (which actually clears the queue) doesn't work, because the courton (asynctask finishes after acitvity.finish()) gets added afterwards, and the problem persists.
also tried:
#Override
protected void onDestroy() {
Crouton.clearCroutonsForActivity(this);
Crouton.cancelAllCroutons();
super.onDestroy();
}
knwon issue: https://github.com/keyboardsurfer/Crouton/issues/24
but didn't work too...
Thankful for any advice!
:)
You have found the correct issue on Crouton and the part of the code that is responsible for producing the issue.
In your case it correlates with the AsyncTask which is still running when your Activity actually should have been destroyed already. It's generally a good thing to move long running behavior out of user facing components, i.e. using a service layer.
Until then canceling the AsyncTask should do the trick.
thx #keyboardsurfer for the explanation...
adding...
and extracting the AsyncTask to a member variable...
#Override
protected void onPause() {
Crouton.clearCroutonsForActivity(this);
if (loadTasksTask != null) {
loadTasksTask.cancel(true);
}
super.onPause();
}
fixed the issue! :)
thx a lot :)
(Note that I've searched online for the warnings I'm describing below, and have come up with next to nothing about them.)
I'm working with API level 10. I have a preference screen (XML-based), and one of the options in there creates a custom ListActivity as follows:
PreferenceActivity contains an option that creates a...
ListActivity which is a dialog that employs...
setOnClickListener() which contains an onClick() method that (right before calling finish()) will startActivity() a new Intent...
sub-Activity which starts up an...
AsyncTask which does variable time work which when done calls...
onPostExecute() which calls finish()
The thing is, it works... but I'm getting a raft of warning starting with:
10-16 21:59:25.010: WARN/WindowManager(170): Rebuild removed 4 windows but added 3
10-16 21:59:25.010: WARN/WindowManager(170): This window was lost:.....
Curiously, this raft of warnings ONLY comes up when the task executes quickly! When I added a Thread.sleep() call to my AsyncTask to artificially inflate its runtime it worked and threw no warnings whatsoever. In fact, as long as it takes more than (roughly) 500 ms to run it works fine. (Note that I tried using startActivityForResult() to no greater effect - the same problem occurs.)
The goal is that the user selects a preference item, they change its setting, some processing takes place, and then the user is left back at the preference menu they started on.
I'm betting it's a race condition... the order in which the windows are destroyed varies depending on that run-time... and I get the impression that when the sub-Activity closes before its parent ListActivity the warnings get thrown. But sprinkling a 1s sleep() in isn't a reasonable solution unless this is some sort of Android bug (unlikely, but then again I've reproduced a couple of those today already).
So, what's the flaw in this my that leads to this stream of warnings? It'd be nice to say "on preference, do this, then do that, then finish" but I think what I'm doing is the equivalent. Maybe not... thoughts?
Edit: I decided to try doing this ListActivity as a custom Dialog... that was one of the more painful things I've tried to do lately (getApplication() doesn't work and lots of other things seem to go wrong... it may be inexperience to some extent, but dialogs really weren't meant for this either...
Try the following two things:
Dismiss your dialog before calling finish() on its parent activity (PreferenceActivity).
Make sure you are starting your AsyncTask later in the sub-activity's lifecycle. I'm specifically thinking you should launch it in onResume().
My best guess is that the AsyncTask is calling finish() on the sub-activity, before the sub-activity has had a chance to fully start up. Why that would matter? I'm not sure. Something to try though. Good luck!
My app may launch a sub-activity for a specific purpose. When that activity finishes, I get the results in onActivityResult. These results are then processed in the subsequent onResume. This consists of a setContentView and also starting an AsyncTask that puts up a ProgressDialog.
This all works well when initiated the normal way, which is via a user request (i.e., menu selection) after the app is up and running. However, under some conditions I need to do this right as the app is starting up, so I initiate this sequence right from my onCreate. What then happens is that I get fatal ResourceNotFound errors within any o/s call that implicitly calls the layout inflater. I got around this with setContentView by pre-inflating the view in my onCreate method, but the AsyncTask's onPreExecute still fails on ProgressDialog.show() as it "fails to find" Android's own progress_dialog.xml!
Anyone know what's happening here?
I suspect it's something to do with the timing, where this is occurring before the main activity has even had a chance to display its screen. These calls are all being made on the main UI thread, but maybe something hasn't completed within the o/s under these conditions.
As a closeout, the problem turned out to be totally unrelated to what I described in my post. Turns out it was due to blindly using some code that had been posted in some online forum showing how to get and use AssetManager. Trouble is, at the end of the block of code he had put "assMan.close()". Well, this closes the asset manager for the entire activity and resources can no longer be accessed!
It took a while to find it since it was not something that I did via my own understanding.
I have three simultaneous instances of an AsyncTask for download three files. When two particular ones finish, at the end of onPostExecute() I check a flag set by each, and if both are true, I call startActivity() for the next Activity.
I am currently seeing the activity called twice, or something that resembles this type of behavior. Since the screen does that 'swipe left' kind of transition to the next activity, it sometimes does it twice (and when I hit back, it goes back to the same activity). It's obvious two versions of the activity that SHOULD only get called once are being put on the Activity stack.
Could this be from both onPostExecute()s executing simultaneously and both checking the flags each other set at the exact same time? This seems extremely unlikely since two processes would have to be running line-by-line in parallel...
*****EDIT*** A lot removed from this question since I was way off in what I thought was wrong. Nonetheless I found the answer here quite useful, so I have edited the question to reflect the useful parts.
The only way I can find that this is
possible is if both AsyncTasks'
onPostExecute() executed SO
simultaneously that they were
virtually running the same lines at
the same time, since I set the
'itemXdownloaded' flag to true right
before I check for both and call
startActivity().
Since they are both called on the main application thread, that's not possible, unless you're doing something really strange.
I would introduce some Log calls to ensure that you are not misreading the symptoms.
Beyond that, it is difficult to see any problems from your pseudocode, unless there's a possibility of other downloadID values beyond the three shown. For example, if there is a DL4, and DL4 completed after DL1 and DL2, DL4 would trigger your activity.