Bug 8741 - ContentProviders cannot access Content property from OnCreate() if .apk has custom App
Summary: ContentProviders cannot access Content property from OnCreate() if .apk has c...
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: Mono runtime / AOT Compiler ()
Version: 4.5.x
Hardware: PC Mac OS
: Normal normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-12-03 23:24 UTC by Jonathan Pryor
Modified: 2017-07-07 20:46 UTC (History)
7 users (show)

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


Attachments
Scratch.ContentProvidersHateApplications.zip (11.28 KB, application/zip)
2012-12-03 23:24 UTC, Jonathan Pryor
Details


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 FIXED

Description Jonathan Pryor 2012-12-03 23:24:19 UTC
Created attachment 3051 [details]
Scratch.ContentProvidersHateApplications.zip

(may be more generic than summary describes, but let's start there...)

If an application provides both an Application subclass, and a ContentProvider in which the OnCreate() method accesses ContentProvider.Context, things "go bad":

	[Application]
	partial class MyApp : Android.App.Application {

		public MyApp (IntPtr handle, JniHandleOwnership transfer)
			: base (handle, transfer)
		{
			Console.WriteLine ("MyApp wrapper created");
		}
	}

	[ContentProvider(new[]{"i.do.not.need.no.stinking.authority"})]
	partial class MyContentProvider : ContentProvider {

		public override bool OnCreate ()
		{
			Console.WriteLine ("MyContentProvider.OnCreate");
			Console.WriteLine ("MyContentProvider.OnCreate: Context.Class.Name={0}", Context.Class.Name);
			Console.WriteLine ("MyContentProvider.OnCreate: Context={0}", Context.GetType ().FullName);
			return true;
		}
	}

What "goes wrong"? Mono for Android attempts to register the MyApp class...constantly. In 4.2.7, this causes a runtime abort:

> # adb shell setprop debug.mono.log gref,timing
> # adb logcat
> ...
> I/mono-stdout(11254): MyContentProvider.OnCreate
> ...
> I/mono-stdout(11254): MyContentProvider.OnCreate: Context.Class.Name=scratch.contentprovidershateapplications.MyApp
> I/mono-stdout(11254): MyContentProvider.OnCreate: Context=Android.App.Application
> I/monodroid-timing(11254): Runtime.register: start time: 1354594250645 ms
> I/monodroid-timing(11254): JNIEnv.RegisterJniNatives ("Scratch.ContentProvidersHateApplications.MyApp, Scratch.ContentProvidersHateApplications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", 0x418928b0) start: 1354594250646.01
> ...
> I/monodroid-timing(11254): JNIEnv.RegisterJniNatives ("Scratch.ContentProvidersHateApplications.MyApp, Scratch.ContentProvidersHateApplications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", 0x418928b0) start: 1354594250649.34
> ...
> E/mono    (11268): Unhandled Exception:
> E/mono    (11268): System.ArgumentException: An element with the same key already exists in the dictionary.
> E/mono    (11268):   at System.Collections.Generic.Dictionary`2[System.String,System.Type].Add (System.String key, System.Type value) [0x00000] in <filename unknown>:0 
> E/mono    (11268):   at Java.Interop.TypeManager.RegisterType (System.String java_class, System.Type t) [0x00000] in <filename unknown>:0 
> E/mono    (11268):   at Android.Runtime.TypeManager.RegisterType (System.String java_class, System.Type t) [0x00000] in <filename unknown>:0 
> E/mono    (11268):   at Android.Runtime.JNIEnv.RegisterJniNatives (IntPtr typeName_ptr, Int32 typeName_len, IntPtr jniClass, IntPtr methods_ptr, Int32 methods_len) [0x00000] in <filename unknown>:0 
> E/mono    (11268):   at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod) [0x00000] in <filename unknown>:0 
> E/mono    (11268):   at Android.App.Application.OnCreate () [0x00000] in <filename unknown>:0 
> E/mono    (11268):   at Android.App.Application.n_OnCreate (IntPtr jnienv, IntPtr native__this) [0x00000] in <filename unknown>:0 
> E/mono    (11268):   at (wrapper dynamic-method) object:f6b

Even once Bug #5397 is fixed, things still fail badly, triggering an apparent stack overflow:

> I/dalvikvm(11474):   at mono.android.Runtime.register(Native Method)
> I/dalvikvm(11474):   at scratch.contentprovidershateapplications.MyApp.onCreate(MyApp.java:24)
> I/dalvikvm(11474):   at scratch.contentprovidershateapplications.MyApp.n_onCreate(Native Method)
> I/dalvikvm(11474):   at scratch.contentprovidershateapplications.MyApp.onCreate(MyApp.java:25)
> I/dalvikvm(11474):   at scratch.contentprovidershateapplications.MyApp.n_onCreate(Native Method)
> I/dalvikvm(11474):   at scratch.contentprovidershateapplications.MyApp.onCreate(MyApp.java:25)
> I/dalvikvm(11474):   at scratch.contentprovidershateapplications.MyApp.n_onCreate(Native Method)
> I/dalvikvm(11474):   at scratch.contentprovidershateapplications.MyApp.onCreate(MyApp.java:25)
> I/dalvikvm(11474):   at scratch.contentprovidershateapplications.MyApp.n_onCreate(Native Method)
> ...
> E/dalvikvm(11474): VM aborting
> W/dalvikvm(11474): JNI WARNING: JNI method called with exception pending
> W/dalvikvm(11474):              in Lmono/android/Runtime;.register:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;)V (NewString)
> W/dalvikvm(11474): Pending exception is:
> I/dalvikvm(11474): java.lang.StackOverflowError:
> I/dalvikvm(11474):   (raw stack trace not found)

Workaround: Don't Do That™: If the overridden ContentProvider.OnCreate() method doesn't access the Context property, the app is able to start normally. Alternatively, if no custom Application subclass is provided, then the app is able to start normally.
Comment 2 Jonathan Pryor 2012-12-03 23:37:20 UTC
Once line of note in the above logcat:

> I/mono-stdout(11254): MyContentProvider.OnCreate: Context=Android.App.Application

The reason is that the created Application subclass has not yet been registered with Mono for Android (via the Android Callable Wrapper's Application.onCreate() method), and without "properly" fixing Bug #7459 the Application subclass provided within the application isn't be checked. It will be used once Android invokes Application.onCreate(), but that's _after_ creating and calling ContentProvider.onCreate(), so within ContentProvider, at present, a "wrapper" instance is used.

It's plausible that this is why things "go horribly bad"; this bears further investigation.
Comment 3 Cody Beyer (MSFT) 2017-07-07 20:46:49 UTC
After reviewing the description of this bug, we believe it no longer affects the current version of Xamarin.Android. If you are still experiencing the issue after updating your packages, please reopen this report with an attached reproduction.