Default constructors in Xamarin.Android - xamarin.android

I am new to Android development with Xamarin.Android and I would like to understand how to have the next issue fixed.
Sometimes after restoring my Android application from background I was facing the next error:
Unable to find the default constructor on type MainMenuFragment. The MainMenuFragment is used by the application NavigationDrawerActivity to allow users to switch between different Fragments inside the app.
In order to solve it, I added a default constructor to the MainMenuFragment as described inside the next links:
Xamarin Limitations - 2.1. Missing constructors
Added a default constructor, should fix the issue.
public class MainMenuFragment : DialogFragment
{
readonly NavigationDrawerActivity navigationDrawer;
#region Constructors
public MainMenuFragment () {} // Default constructor...
public MainMenuFragment (NavigationDrawerActivity navigationDrawer, IMenuType launchMenu = null)
{
if (navigationDrawer == null)
throw new ArgumentNullException ("navigationDrawer");
this.navigationDrawer = navigationDrawer;
...
Fragment UpdateTopFragmentForCurrentMenu (Fragment newMenuRootFragment = null)
{
Fragment currentMenuRootFragment = navigationDrawer.CurrentFragment; // issued line.
But now sometime in the future, the MainMenuFragment gets initialized using its default constructor and at the first time it tries to access its navigationDrawer it throws a System.NullReferenceException:
System.NullReferenceException: Object reference not set to an instance of an object
at MainMenuFragment.UpdateTopFragmentForCurrentMenu (Android.App.Fragment) <0x00018>
at MainMenuFragment.OpenMenu (IMenuType,bool) <0x0006b>
at MainMenuFragment.OnCreate (Android.OS.Bundle) <0x00053>
at Android.App.Fragment.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x0005b>
at (wrapper dynamic-method) object.3919a6ec-60c1-49fd-b101-86191363dc45 (intptr,intptr,intptr) <0x00043>
How can I have a default constructor implemented without facing this null reference exception?

You're programming like a C# developer, thats what the problem is :) I faced these same hurdles learning monodroid.
Take a look at the examples out there, in java, you'll see almost all the time they initialize using a static method like object.NewInstance() which returns object. This is how they initialize their views/receivers/fragments. At that point they populate the Arguments property and store that in the fragment. You need to remove all your constructors EXCEPT the empty ones and use arguments to pass your data around. If you try to do this using constructors and regular oo concepts you'll be in for a world of hurt. Arguments.putExtra and all those methods are there. It makes things a little verbose but once you get the hang of it you'll start creating some helper methods etc.
Once you get that sorted, you'll need to figure out if you need to recreate your fragments everytime the activity is resumed and if not, mark them as RetainInstance = true as well as get them onto a fragmentmanager which will help you retain all your state.
If you haven't built on android before it's weird and certainly not what I expected. But it's reeaaallly cool, much more awesome than I expected too. And same with Xamarin.
Great similar question: Best practice for instantiating a new Android Fragment

Related

Nullability mismatch in simple assignment after switching to sound null safety

I switched to sound null safety and started getting runtime error in a simple assignment, that should never happen with sound null safety:
final widgetOnPressed = widget.onPressed;
Error:
type '(LogData) => void' is not a subtype of type '((LogData?) => void)?'
I can repro it for Flutter versions 2.12.0-4.1.pre and 2.13.0-0.0.pre.505.
PR: https://github.com/flutter/devtools/pull/3971
Failing line: https://github.com/flutter/devtools/blob/9fc560ff2e6749459e2ca6a1dc00bf6fb16ed93b/packages/devtools_app/lib/src/shared/table.dart#L1184
To repro, start DevTools at this PR for macos, connect to an app and click the tab 'Logging'. DevTools will show red screen and error in console.
Is it dart bug or the app bug? If it is the app bug, how can I debug it?
It's a bug in your code.
You didn't say which kind of error you got - a compile-time error or a runtime error. I'm guessing runtime error. (Well, you did say to launch it in the debugger, so that is a good hint too.)
The line final widgetOnPressed = widget.onPressed; looks like it can't possibly fail. After all, the type of the local variable is inferred from the expression assigned to it, and the runtime value of that expression will surely be a subtype of the static type because the type system is sound!
Isn't it? ISN'T IT?
It's not, sorry. Dart 2's type system is mostly sound, even more so with null safety, but class generics is covariant, which can still be unsound. It's fairly hard to hit one of the cases where that unsoundness shows its ugly head, but returning a function where the argument type is the class's type variable is one.
Your state class extends State<TableRow<T?>>, so the widget getter returns a TableRow<T?>. The onPressed of that type has type ItemCallback<T?>?, aka, void Function(T?)?.
You create a _TableRowState<LogData>, with its widget which has static type TableRow<LogData?>, but you somehow manage to pass it a TableRow<LogData> instead. That's fine. Class generics are covariant, so all is apparently fine at compile-time.
Then you do final widgetOnPressed = widget.onPressed;.
The static type of widgetOnPressed is void Function(LogData?) here.
The actual runtime type of onPressed is void Function(LogData) because it's from a TableRow<LogData>.
A void Function(LogData) is-not-a void Function(LogData?) because the former cannot be used in all places where the latter can (in particular, it can't be used in a place where it's called with null).
This assignment is potentially unsound, and actually unsound in this case. The compiler knows this and inserts an extra check to ensure that you don't assign a value to the variable which isn't actually valid. That check triggers and throws the error you see.
How do you avoid that?
Don't create a TableRow<LogData> where a TableRow<LogData?> is required.
Or type the variable as:
final ItemCallback<T>? widgetOnPressed = widget.onPressed;
(no ? on the T).
Or rewrite everything to avoid returning a function with a covariant type parameter (from the class) occurring contra-variantly (as an argument type).
Which solution fits you depends on what you want to be able to do.

Jena read hook not invoked upon duplicate import read

My problem will probably be explained better with code.
Consider the snippet below:
// First read
OntModel m1 = ModelFactory.createOntologyModel();
RDFDataMgr.read(m1,uri0);
m1.loadImports();
// Second read (from the same URI)
OntModel m2 = ModelFactory.createOntologyModel();
RDFDataMgr.read(m2,uri0);
m2.loadImports();
where uri0 points to a valid RDF file describing an ontology model with n imports.
and the following custom ReadHook (which has been set in advance):
#Override
public String beforeRead(Model model, String source, OntDocumentManager odm) {
System.out.println("BEFORE READ CALLED: " + source);
}
Global FileManager and OntDocumentManager are used with the following settings:
processImports = true;
caching = true;
If I run the snippet above, the model will be read from uri0 and beforeRead will be invoked exactly n times (once for each import).
However, in the second read, beforeRead won't be invoked even once.
How, and what should I reset in order for Jena to invoke beforeRead in the second read as well?
What I have tried so far:
At first I thought it was due to caching being on, but turning it off or clearing it between the first and second read didn't do anything.
I have also tried removing all ignoredImport records from m1. Nothing changed.
Finally got to solve this. The problem was in ModelFactory.createOntologyModel(). Ultimately, this gets translated to ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_RDFS_INF,null).
All ontology models created with the static OntModelSpec.OWL_MEM_RDFS_INF will have their ImportsModelMaker and some of its other objects shared, which results in a shared state. Apparently, this state has blocked the reading hook to be invoked twice for the same imports.
This can be prevented by creating a custom, independent and non-static OntModelSpec instance and using it when creating an OntModel, for example:
new OntModelSpec( ModelFactory.createMemModelMaker(), new OntDocumentManager(), RDFSRuleReasonerFactory.theInstance(), ProfileRegistry.OWL_LANG );

Debugging JSF ManagedProperty NullPointer

Using JSF 2 on JBoss AS 7
Getting the following error:
07:36:39,579 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-/172.20.91.126:12580-16)
Error Rendering View[/views/afgarendesok.xhtml]:
com.sun.faces.mgbean.ManagedBeanCreationException:
Unable to set property searchManager for managed bean afgArendeBacking
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:615)
The searchManager property is defined in the AfgArendeBacking class as:
#ManagedProperty(value="#{afgArendeSokManager}")
private AfgArendeSokManager searchManager;
#Override
public AfgArendeSokManager getSearchManager() {
return searchManager;
}
public void setSearchManager(AfgArendeSokManager searchManager) {
this.searchManager = searchManager;
}
The AfgArendeSokManager is a #ManagedBean that is #SessionScoped.
Two things I don't get. One is why the error shuts down all usage of JSF not just for the session producing the error. The error seems to appear after non-usage both below the default session timeout and beyond. The other odd this is that a null pointer exception at line 606 in the BakedBeanProperty has to be the one the writeMethod variable. That variable is created via the PropertyDescriptor.getWriteMethod() call. This should have bombed earlier when creating baked bean (i.e. bakeBeanProperty method).
Any ideas how to debug? The property "searchManager" is resolved correctly since we can use the JSF views normally (both the getter/setter exist).
The search manager is our session scratch pad for propagating stuff between view and request scoped backing beans.
The article explains the issue of using reflection to access methods with covariant return types (see here: https://dzone.com/articles/covariant-return-type-abyssal). The article relates to Java 6 but the background information is very useful.
The issue you're facing and that hit us just this week (using Java 1.7.0_40) is not one of EL but of the java.beans.Introspector.

Error "More than one matching bindings are available" when using Ninject.Web.Mvc 2.0 and ASP.NET MVC 1.0

Recently I've switched to Ninject 2.0 release and started getting the following error:
Error occured: Error activating SomeController
More than one matching bindings are available.
Activation path:
1) Request for SomeController
Suggestions:
1) Ensure that you have defined a binding for SomeController only once.
However, I'm unable to find certain reproduction path. Sometimes it occurs, sometimes it does not.
I'm using NinjectHttpApplication for automatic controllers injection. Controllers are defined in separate assembly:
public class App : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
INinjectModule[] modules = new INinjectModule[] {
new MiscModule(),
new ProvidersModule(),
new RepositoryModule(),
new ServiceModule()
};
return new StandardKernel(modules);
}
protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn("Sample.Mvc");
base.OnApplicationStarted();
}
/* ............. */
}
Maybe someone is familiar with this error.
Any advice?
I finally figured this issue out recently. Apparently, the NinjectHttpApplication.RegisterAllControllersIn() function doesn't do all of the proper bindings needed. It binds your concrete controller implementations to IController requests. For example, if you have a controller class called SampleMvcController, which inherits from System.Web.Mvc.Controller. It would do the following named binding during application start:
kernel.Bind<IController>().To(SampleMvcController).InTransientScope().Named("SampleMvc");
But when debugging the NinjectControllerFactory, I find that request are being made for the Ninject Kernel to return an object for the class "SampleMvcController", not for a concrete implementation of IController, using the named binding of "SampleMvc".
Because of this, when the first web request that involves the SampleMvcController is made, it creates a binding of SampleMvcController to itself. This is not thread safe though. So if you have several web requests being made at once, the bindings can potentially happen more than once, and now you are left with this error for having multiple bindings for the SampleMvcController.
You can verify this by quickly refreshing an MVC URL, right after causing your web application to restart.
The fix:
The simplest way to fix this issue is to create a new NinjectModule for your controller bindings, and to load this module during application start. Within this module, you self bind each of your defined controllers, like so:
class ControllerModule : StandardModule {
public override Load() {
Bind<SampleMvcController>().ToSelf();
Bind<AnotherMvcController>().ToSelf();
}
}
But if you don't mind changing the Ninject source code, you can modify the RegisterAllControllersIn() function to self bind each controller it comes across.
I have been dealing with this problem for months. I tried so many options but was unable to come to a solution. I knew that it was a threading problem because it would only occur when there was a heavy load on my site. Just recently a bug was reported and fixed in the ninject source code that solves this problem.
Here is a reference to the issue. It was fixed in build 2.1.0.70 of the Ninject source. The key change was in KernelBase.cs by removing the line
context.Plan = planner.GetPlan(service);
and replacing it with
lock (planner)
{
context.Plan = planner.GetPlan(service);
}
To use this new build with MVC you will need to get the latest build of Ninject then get the latest build of ninject.web.mvc. Build ninject.web.mvc with the new Ninject build.
I have been using this new build for about a week with a heavy load and no problems. That is the longest it has gone without a problem so I would consider this to be a solution.
Are you sure you really are creating a single completely new Kernel from scratch in your OnApplicationStarted every time it's invoked ? If you're not and you're actually creating it once but potentially running the registration bit twice. Remember that you're not guaranteed to only ever have one App class instantiated ever within a given AppDomain.
My answer was a bit more obvious.
I had declared the binding for one of my controllers more than once during refactor of my code.
I added this to my global.ascx.cs file:
public void RegisterAllControllersInFix(Assembly assembly)
{
RegisterAllControllersInFix(assembly, GetControllerName);
}
public void RegisterAllControllersInFix(Assembly assembly, Func<Type, string> namingConvention)
{
foreach (Type type in assembly.GetExportedTypes().Where(IsController))
Kernel.Bind(type).ToSelf();
}
private static bool IsController(Type type)
{
return typeof(IController).IsAssignableFrom(type) && type.IsPublic && !type.IsAbstract && !type.IsInterface;
}
private static string GetControllerName(Type type)
{
string name = type.Name.ToLowerInvariant();
if (name.EndsWith("controller"))
name = name.Substring(0, name.IndexOf("controller"));
return name;
}
Then called it from my OnApplicationStarted() method as follows:
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
RegisterAllControllersInFix(Assembly.GetExecutingAssembly());
Difficult to know whether this fixed it though because it's so intermittent.

StructureMap 202 - Why?

OK, I'm trying to set a property on a type I'm registering with SM.
Here's the code from the registry in one of my components. This
registry is being added during the configuration from a console app.
When I try to access the EndorsementSpecs property of the instance
AutoMandatoryEndorsementAggregator object, I get the 202. What's
interesting is that I can call
GetAllInstances>() from my
console app and it resolves just fine. Is there something about
accessing this code from within OnCreation that is causing the 202? I
can see everything I expect in WhatDoIHave(). I've also tried a TypeInterceptor with the same results.
//register all open generics
cfg.ConnectImplementationsToTypesClosing(typeof
(MandatoryEndorsementSpecBase<>));
ForSingletonOf<IMandatoryEndorsementAggregator<AutoPolicy>>()
.Use<AutoMandatoryEndorsementAggregator>()
.OnCreation((context, x) =>
{
var specs =
context.GetAllInstances<MandatoryEndorsementSpecBase<AutoPolicy>>();
x.EndorsementSpecs = specs;
})
;
Sorry to deflect your real questions, but are you just trying to inject all instances of MandatoryEndorsementSpecBase into AutoMandatoryEndorsementAggregatory?
If so, you can probably get away with just making it a constructor parameter so that they are all automatically injected.
public AutoMandatoryEndorsementAggregatory(MandatoryEndorsementSpecBase<AutoPolicy>[] endorsementSpecs){
EndorsementSpecs = endorsementSpecs;
}

Resources