It might be because onQueryTextChange is being called on orientation 
changes... so restartLoader is called each time, thus resulting in two 
calls to onLoadFinished. I haven't tested this, but I suspect it is the 
problem here. I forgot my USB cable at work but I'll try to remember to 
test it out. I doubt it is a bug though... it seems like the last 
LoaderManager bug should have been squashed a long time ago, given that it 
has been over a year since HoneyComb's release.

Alex

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 <[email protected]> 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$**CursorLoaderListFragment.**onLoadFinished(Loader, 
>>> Cursor) line: 159        
>>>
>>> LoaderCursor$**CursorLoaderListFragment.**onLoadFinished(Loader, 
>>> Object) line: 1        
>>>
>>> LoaderManagerImpl$LoaderInfo.**callOnLoadFinished(Loader, Object) line: 
>>> 438        
>>>
>>> *LoaderManagerImpl$LoaderInfo.reportStart() line: 318     *   
>>>
>>> LoaderManagerImpl.**doReportStart() line: 778        
>>>
>>> LoaderCursor$**CursorLoaderListFragment(**Fragment).performStart() 
>>> line: 1534        
>>>
>>> FragmentManagerImpl.**moveToState(Fragment, int, int, int) line: 
>>> 862        
>>>
>>> FragmentManagerImpl.**moveToState(int, int, int, boolean) line: 
>>> 1032        
>>>
>>> FragmentManagerImpl.**moveToState(int, boolean) line: 1014        
>>>
>>> FragmentManagerImpl.**dispatchStart() line: 1771        
>>>
>>> *LoaderCursor(Activity).performStart()* line: 4481        
>>>
>>> ActivityThread.**performLaunchActivity(**ActivityThread$**ActivityClientRecord,
>>>  
>>> Intent) line: 1929        
>>>
>>> ActivityThread.**handleLaunchActivity(**ActivityThread$**ActivityClientRecord,
>>>  
>>> Intent) line: 1981        
>>>
>>> ActivityThread.**handleRelaunchActivity(**ActivityThread$**ActivityClientRecord)
>>>  
>>> line: 3351        
>>>
>>> ActivityThread.access$700(**ActivityThread, 
>>> ActivityThread$**ActivityClientRecord) 
>>> line: 123        
>>>
>>> ActivityThread$H.**handleMessage(Message) line: 1151        
>>>
>>> ActivityThread$H(Handler).**dispatchMessage(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.reportStart*() 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$**CursorLoaderListFragment.**onLoadFinished(Loader, 
>>> Cursor) line: 159        
>>>
>>> LoaderCursor$**CursorLoaderListFragment.**onLoadFinished(Loader, 
>>> Object) line: 1        
>>>
>>> LoaderManagerImpl$LoaderInfo.**callOnLoadFinished(Loader, Object) line: 
>>> 438        
>>>
>>> *LoaderManagerImpl$LoaderInfo.finishRetain() line: 309 *       
>>>
>>> LoaderManagerImpl.**finishRetain() line: 765        
>>>
>>> *LoaderCursor(Activity).performStart() line: 4485 *       
>>>
>>> ActivityThread.**performLaunchActivity(**ActivityThread$**ActivityClientRecord,
>>>  
>>> Intent) line: 1929        
>>>
>>> ActivityThread.**handleLaunchActivity(**ActivityThread$**ActivityClientRecord,
>>>  
>>> Intent) line: 1981        
>>>
>>> ActivityThread.**handleRelaunchActivity(**ActivityThread$**ActivityClientRecord)
>>>  
>>> line: 3351        
>>>
>>> ActivityThread.access$700(**ActivityThread, 
>>> ActivityThread$**ActivityClientRecord) 
>>> line: 123        
>>>
>>> ActivityThread$H.**handleMessage(Message) line: 1151        
>>>
>>> ActivityThread$H(Handler).**dispatchMessage(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.finishRetain*() 
>>> 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.*reportStart*() (from 
>>>       mFragments.dispatchStart())
>>>       - LoaderManagerImpl$LoaderInfo.*finishRetain*() (from 
>>>       LoaderManagerImpl.**finishRetain())
>>>       - LoaderManagerImpl$LoaderInfo.*reportStart*() (from 
>>>       LoaderManagerImpl.**doReportStart())
>>>    - LoaderManagerImpl$LoaderInfo.*reportStart*() 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 [email protected]
>> To unsubscribe from this group, send email to
>> [email protected]
>> 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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to