On Jun 21, 2016, at 3:40 PM, Jeremy A. Kolb - ARA/NED <jk...@ara.com> wrote:
> We put Activation constructors almost everywhere because they tend to fix 
> crashes when coming back to an activity.

There’s a fine line between a “fix” and “hides the symptoms of the actual 
problem.” :-)

> Plus we allow almost all of our classes to be overridden by the user if they 
> need to do so.  Maybe in this case MvxRecyclerViewHolder
> doesn't need to use the constructor.  It's hard to tell when it is needed.

To me, there are only two circumstances in which you should provide the 
activation constructor:

1. You’re subclassing Android.App.Application or Android.App.Instrumentation.
2. You’re subclassing a Java type that contains virtual methods, and the 
constructor of the Java type can invoke those methods.

(2) is harder to narrow down, other than a blanket “Android.Views.View *might* 
require the activation constructor.”

This almost certainly does *not* describe `RecyclerView.ViewHolder`, as the 
only virtual (non-`final` instance) method it has is `Object.toString()`:

        
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html

> As far as I can tell Dispose() is not being called on MvxRecyclerViewHolder.

Normal GC finalizer behavior would also qualify. (I should have thought of that 
 before…) Once the Mono GC has finalized an instance, `Object.Handle` is null, 
and there’s no GREF to keep the Java instance alive. Consequently, 
`Object.finalize()`/`Object.JavaFinalize()` can be invoked on that instance…an 
instance which *can’t* be associated with anything meaningful (short of 
Reflection-fu) — because `Object.Handle` is null! — and now, 5 years on, I 
wonder why I ever bound that method in the first place…

Hm….

---

I think the docs describe what the Activation constructor is *for* reasonably 
well. A related topic would be, what’s the problem with providing the 
activation constructor?

Alternatively, how would providing the activation constructor “hide the 
symptoms of the actual problem”?

Let’s take an IRunnable implementation:

        
https://github.com/xamarin/xamarin-android/blob/5777337/src/Mono.Android/Java.Lang/Thread.cs#L11-L54

Notice that it *doesn’t* have an activation constructor. This isn’t for lack of 
people asking for one (on many types!), because an exception was thrown because 
the activation constructor doesn’t exist:

        https://bugzilla.xamarin.com/show_bug.cgi?id=27408

Yes, not having an activation constructor can cause a 
NotSupportedException/MissingMethodException to be thrown. The fix *isn’t* to 
add the activation constructor.

The fix is to figure out why we were trying to use the activation constructor 
in the first place. In the case of Bug #27408 it was due to a bug in our handle 
management (multithreaded code is hard!).

Adding the activation constructor would have “fixed” that bug. It also means 
we’d have had ~no way to even know that something was wrong, and no way to 
reason about a fix.

I don’t want a platform that cargo-cults around bug fixes with no understanding 
of *why* things are happening. I’m trying to keep the cruft low, the “it works 
if I do *this* but I don’t know why” crap to a minimum.

Not that I’m always successful, but I *really* don’t want to hide bugs. I want 
them found, a bright light shone on them, and the bug exterminated with extreme 
prejudice. Adding activation constructors “everywhere” is anathema to this.

 - Jon

_______________________________________________
Monodroid mailing list
Monodroid@lists.ximian.com

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to