7

I am aware of the constructor difficulty in Xamarin Android as is explained here : No constructor found for ... (System.IntPtr, Android.Runtime.JniHandleOwnership)

and all the fragments & activities & other custom views that I create in the app import this constructor.

Sometimes however a null reference exception is thrown in the OnCreateView method. Example:

public class TestView: Android.Support.V4.App.Fragment{

    public TestClass _testClass;

    public TestView (TestClass testClass)
    {
        this._testClass = testClass;
    }

    public TestView(IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) : base(javaReference, transfer)
    {
    }

    public override Android.Views.View OnCreateView (Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Android.OS.Bundle savedInstanceState)
    {
        View view = inflater.Inflate (Resource.Layout.Fragment_TestView, container, false);

        _testClass.ExecuteTestMethod();

        return view;
    }

}

This piece of code throws a null reference exception in the OnCreateView, occassionaly. This happens very rarely and never when I create the view from code directly and test it then.

Now clearly the only point in this code where the exception can be thrown is on the _testClass variable. So now obviously my question is, is the OncreateView method also executed when the javaReference constructor is called?

Community
  • 1
  • 1

1 Answers1

3

Even in Java onCreateView can be called in situations where the constructor would not be, that's the fragment lifecycle works:

Fragment Lifecycle Diagram


Your constructor is called before Fragment is added, but your instance variable _testClass doesn't always get set because Android will call the default constructor when restoring it. I'd guess that your crashes are happening when you rotate the device (three times in a row?) and/or when you go to another app and come back

You need to manage that by persisting the arguments (basic data types supported by Bundle) needed to create an instance of TestClass with onSaveInstanceState, then using them to create an instance of TestClass in onResume

Selali Adobor
  • 2,060
  • 18
  • 30
  • Hey, thanks for your reply! The rotation is locked in our app so the restore does not occur then but as you point out it will most likely occur when the app comes out of sleep or from another app. I will investigate this lead in our current app and will get back to you! Thanks! – Philippe Creytens Jan 20 '17 at 14:55
  • @PhilippeCreytens there are multiple events other than rotation that cause configuration changes (like connecting a keyboard, changing the system language, etc.), you can disable them, but then you break support for the things that cause those changes. (Accidentally hit enter) You can try and skip supporting proper state restoration by locking rotation, but it's a poor work around that will break when people use your app outside of a vacuum and is generally unsustainable. The earlier to build with it in mind, the less grief you'll experience down the road. – Selali Adobor Jan 20 '17 at 15:23
  • I completely relate to you about that but the app I am currently talking about is Portrait only, so that is why the rotation is not available in the app. Not because of these issues. – Philippe Creytens Jan 20 '17 at 15:36
  • @PhilippeCreytens sorry, I misread "The rotation is locked in our app so the restore does not occur" to imply configuration changes don't happen because of locked rotation, not the other way around – Selali Adobor Jan 20 '17 at 15:47
  • 1
    I was actually about to remove the comment but I think maybe it's relevant to a lot of other people who might read the answer on an issue like this – Selali Adobor Jan 20 '17 at 15:48
  • The Lifecycle of the app indeed caused these errors to occur. Adding all the required variables to the bundle and checking them in the OnCreate fixed it. – Philippe Creytens Jan 24 '17 at 08:20
  • Philippe Creytens, im having this issue now also and really confused as to why it's happening. When you added all the variables to the bundle and checking them, how did you manage this? – SmiffyKmc May 12 '18 at 17:53