http://stackoverflow.com/questions/11293441/android-loadercallbacks-onloadfinished-called-twice/22183247
On Monday, July 2, 2012 4:49:50 PM UTC-4, Malcolm Evershed wrote:
Your issue sounds like it could be different than mine since I'm generally seeing onLoadFinished() called in initLoader(). You might want to do more web or StackOverflow searching or search the Android bug database -- I think somewhere I read about a problem where onLoadFinished() would not be called, but I think it only happens if you don't do the stuff that CursorLoader does. In other words, to solve your issue, you might have to copy a bunch of code from CursorLoader.
As to my issue, I never reported it since there didn't seem to be any interest in it. I just worked around it in my app.
Thanks.On Mon, Jul 2, 2012 at 5:17 AM, szakalinhoPL <szaka...@gmail.com> wrote:
Hi, I noticed same situation, I'm not an expert but it seems like a bug because behaviour of onLoadFinished is not normal according to documentation which says that onLoadFinished should be called in initLoader, but it never does. In very simple application it happens as well. Did you report it or find out an answer?
On Wednesday, April 11, 2012 11:05:41 PM UTC+1, Malcolm Evershed wrote:--[My apologies if this is posted twice, it has been a few days and my original post didn't show up yet, so I'm attempting to post again]
I think I've found an issue where LoaderManager.LoaderCallbacks<
D>.onLoadFinished() will be called unnecessarily twice when rotating the device. Is this expected behavior or should I open a bug?
This can easily be reproduced by running ApiDemos -> App -> Loader -> Cursor (which corresponds to the LoaderCursor.java example) and rotating the device.
1) Here's the first location where onLoadFinished() is called:
LoaderCursor$CursorLoaderListF
ragment.onLoadFinished(Loader, Cursor) line: 159 LoaderCursor$CursorLoaderListF
ragment.onLoadFinished(Loader, Object) line: 1 LoaderManagerImpl$LoaderInfo.c
allOnLoadFinished(Loader, Object) line: 438 LoaderManagerImpl$LoaderInfo.r
eportStart() line: 318 LoaderManagerImpl.doReportStar
t() line: 778 LoaderCursor$CursorLoaderListF
ragment(Fragment). performStart() line: 1534 FragmentManagerImpl.moveToStat
e(Fragment, int, int, int) line: 862 FragmentManagerImpl.moveToStat
e(int, int, int, boolean) line: 1032 FragmentManagerImpl.moveToStat
e(int, boolean) line: 1014 FragmentManagerImpl.dispatchSt
art() line: 1771 LoaderCursor(Activity).perform
Start() line: 4481ActivityThread.performLaunchAc
tivity(ActivityThread$Activity ClientRecord, Intent) line: 1929 ActivityThread.handleLaunchAct
ivity(ActivityThread$ActivityC lientRecord, Intent) line: 1981 ActivityThread.handleRelaunchA
ctivity(ActivityThread$Activit yClientRecord) line: 3351 ActivityThread.access$700(Acti
vityThread, ActivityThread$ActivityClientR ecord) line: 123 ActivityThread$H.handleMessage
(Message) line: 1151 ActivityThread$H(Handler).disp
atchMessage(Message) line: 99 Looper.loop() line: 137
ActivityThread.main(String[]) line: 4424
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 511
ZygoteInit$MethodAndArgsCaller
.run() line: 784 ZygoteInit.main(String[]) line: 551
NativeStart.main(String[]) line: not available [native method]
Basically, as the Activity is starting up, Activity.performStart() calls mFragments.dispatchStart() which eventually calls Fragment.performStart(), which then calls mLoaderManager.doReportStart()
. Ultimately, LoaderManagerImpl$LoaderInfo.r eportStart () checks if the loader has been started and whether mReportNextStart is set (it was set when Fragment.performDestroyView() was called on the old fragment) and then it'll call onLoadFinished().
2) Here's the second location where onLoadFinished() is called during the same rotation:
LoaderCursor$CursorLoaderListF
ragment.onLoadFinished(Loader, Cursor) line: 159 LoaderCursor$CursorLoaderListF
ragment.onLoadFinished(Loader, Object) line: 1 LoaderManagerImpl$LoaderInfo.c
allOnLoadFinished(Loader, Object) line: 438 LoaderManagerImpl$LoaderInfo.f
inishRetain() line: 309 LoaderManagerImpl.finishRetain
() line: 765 LoaderCursor(Activity).perform
Start() line: 4485 ActivityThread.performLaunchAc
tivity(ActivityThread$Activity ClientRecord, Intent) line: 1929 ActivityThread.handleLaunchAct
ivity(ActivityThread$ActivityC lientRecord, Intent) line: 1981 ActivityThread.handleRelaunchA
ctivity(ActivityThread$Activit yClientRecord) line: 3351 ActivityThread.access$700(Acti
vityThread, ActivityThread$ActivityClientR ecord) line: 123 ActivityThread$H.handleMessage
(Message) line: 1151 ActivityThread$H(Handler).disp
atchMessage(Message) line: 99 Looper.loop() line: 137
ActivityThread.main(String[]) line: 4424
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 511
ZygoteInit$MethodAndArgsCaller
.run() line: 784 ZygoteInit.main(String[]) line: 551
NativeStart.main(String[]) line: not available [native method]
Basically, Activity.performStart() calls LoaderManagerImpl.finishRetain
() (shortly after calling mFragments.dispatchStart() in the first callstack above). Ultimately, LoaderManagerImpl$LoaderInfo.f inishRetain () checks if the loader has been started and whether mReportNextStart is cleared (it was just cleared by LoaderManagerImpl$LoaderInfo.reportStart() in the first callstack above) and then it'll call onLoadFinished().
Here is my guess of what is really going on during a rotation:
- Activity.performStart() ultimately causes this sequence of calls:
- LoaderManagerImpl$LoaderInfo.r
eportStart () (from mFragments.dispatchStart())- LoaderManagerImpl$LoaderInfo.f
inishRetain () (from LoaderManagerImpl.finishRetain()) - LoaderManagerImpl$LoaderInfo.r
eportStart () (from LoaderManagerImpl.doReportStart()) - LoaderManagerImpl$LoaderInfo.r
eportStart () and LoaderManagerImpl$LoaderInfo.finishRetain () use the mReportNextStart flag to determine whether to call onLoadFinished(), but this flag usage isn't designed for the sequence of calls above. It seems like maybe 2 flags may be required to cover all the possibilities of call sequences.
But that's just my guess, I'm new to this code. :)
Thanks.
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-d...@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
---
You received this message because you are subscribed to the Google Groups "Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-developers+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
No comments:
Post a Comment