Bug 33995 - NotifyItemInserted() on RecyclerView.Adapter results in "'jobject' must not be IntPtr.Zero"
Summary: NotifyItemInserted() on RecyclerView.Adapter results in "'jobject' must not b...
Status: RESOLVED ANSWERED
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 5.1
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2015-09-16 00:28 UTC by Slug
Modified: 2015-09-22 14:58 UTC (History)
1 user (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description Slug 2015-09-16 00:28:00 UTC
I have a set of classes inheriting from RecycleView & RecyclerView.Adapter (which store items in an underlying ObservableCollection() ).  It is desired that when new items are retrieved from a call to service and then added to the collection they would then be visible in the RecycleView.  It is desired to maintain the user's position within the list as new products are added rather than dropping the entire list an forcing the user to start again from the beginning.

Calling NotifyDataSetChanged() or NotifyItemInserted() on the adapter then triggers redraw.  

However, instead a System.SystemException occurs with the message "'jobject' must not be IntPtr.Zero".  It happens on both methods NotifyDataSetChanged() & NotifyItemInserted().  It also doesn't matter if you execute them on the UI thread.

Here is the relevant code:


  private void OnCreateProductScansCompleted(object sender, CreateProductScansCompletedEventArgs e)
        {
            try
            {
                foreach (SCAN_PRODUCT scanProd in e.Result)
                {
                    if (!moScanProducts.Any(s => s.PRODUCT_ID == scanProd.PRODUCT_ID))
                    {
                        moScanProducts.Add(scanProd);
                    }
                }

                if (Handle == IntPtr.Zero)
                {
                    return;
                }
                moAdapter.NotifyDataSetChanged();
            }
            catch (System.SystemException sysEx) {
                /* Cannot proceed due to inability to Mono runtime exception */
                Console.WriteLine(sysEx.Message);
                this.Finish();
            }
            catch (Exception ex)
            {                
                Console.WriteLine(ex.InnerException.Message);
                return;
            }
Comment 1 Slug 2015-09-16 13:26:09 UTC
In case this helps....

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Xamarin.Android.Support.v4" version="23.0.1.0-rc2" targetFramework="monoandroid51" />
  <package id="Xamarin.Android.Support.v7.RecyclerView" version="23.0.1.0-rc2" targetFramework="monoandroid51" />
</packages>
Comment 2 Jonathan Pryor 2015-09-17 15:24:45 UTC
Could you please provide a complete repro project?

Do you call moAdapter.Dispose() anywhere, either explicitly or implicitly (via `using` block)?
Comment 3 Slug 2015-09-18 14:19:43 UTC
Yes, in the OnDestroy() override.   It is indeed being called, but it is not clear why.  I think it has to do with this: http://stackoverflow.com/questions/11444622/

I think the problem is with the RecyclerView.ViewHolder - in that it is taking too much time to download the image from the remote source.  It is done using webClient.DownloadDataTaskAsync(), but there are a lot of images.  So even though each instance of ViewHolder works efficiently, all of them working simultaneously cause an "Activity Idle Timeout for ActivityRecord" exception - which maybe triggers OnDestroy().

Perhaps there is a better way?  Lemme have just a bit of time to confirm that this is the cause before we mark it RESOLVED/NOBUG.
Comment 4 Slug 2015-09-22 12:20:48 UTC
OnDestroy() is definately being called as a result of "Activity Idle Timeout for ActivityRecord" - so I am recommending RESOLVED/NOBUG.
Comment 5 Jonathan Pryor 2015-09-22 14:58:04 UTC
Closing as ANSWERED, as per Comment #4.