Dart, null reference exception on static member - dart

I have the following class:
class Label{
static PopOver contextMenu; // can I put = new PopOver(); here?
Label(){
if(Label.contextMenu == null){ //null reference exception here why????
Label.contextMenu = new PopOver();
}
}
}
but I am getting a null reference exception on the Label.contextMenu should I be getting a null reference exception when I'm checking for null? and also can you initialise static members inline where you declare them?

You should not get a null reference exception with this code. I have tested it and I do not get any error.
You definitely can initialize static members inline. Whether you should do so depends on the situation. If the contextMenu will never change, consider making it final as well:
static final PopOver contextMenu = new PopOver();

Related

How singleton works in Dart?

I am new to Dart and Flutter. While I am going through tutorials, I got that we can make singleton using factory keyword. But after that, I got this code.
class AccountService {
static final _instance = AccountService._internal();
AccountService._internal();
static AccountService getInstance() {
return _instance;
}
}
My questions.
How does the code work?
when getInstance() get called?
is AccountService._internal() a constructor?
static final _instance = AccountService._internal(); - When this get called?
Please help me
Static fields in Dart are all lazy evaluated so they will first get its value the first time you access the field.
So:
When you call getInstance(), it will return the value of the field _instance. If this is the first time the field will be evaluated so AccountService._internal() is called. If it is second time, the value from previous access is reused.
First time you call the method somewhere in your code? If you are never calling the method, the object referenced by _instance will never be created.
Yes, it is a named constructor and because the name starts with "_" it is only available from the library this class is part of. By doing so, it is possible to restrict new objects from this class so only the class itself are allowed to create an instance.
It is called first time _instance is accessed. Since this name also starts with "_" it is only available from the library this class is part of.
The lazy initialization of static fields is described in the Dart specification with the following reasoning:
Static variable declarations with an initializing expression are initializedlazily (8.1).
The lazy semantics are given because we do not want a language where one tends to define expensive initialization computations, causing long application startup times. This is especially crucial for Dart, which must support the coding of client applications.
https://dart.dev/guides/language/specifications/DartLangSpec-v2.2.pdf
Added code example
class AccountService {
static final _instance = AccountService._internal();
AccountService._internal() {
print(':: Calling AccountService._internal constructor');
}
static AccountService getInstance() {
print(':: Calling getInstance()');
return _instance;
}
}
void main() {
print(':: Step 1');
AccountService.getInstance();
print(':: Step 2');
AccountService.getInstance();
print(':: End');
}
Output:
:: Start
:: Step 1
:: Calling getInstance()
:: Calling AccountService._internal constructor
:: Step 2
:: Calling getInstance()
:: End

How to access toolbar items from ViewModel Xamarin forms

I tried to set padge in toolbar item from viewmodel
I have interface called IToolbarItemBadgeService
public interface IToolbarItemBadgeService
{
void SetBadge(Page page, ToolbarItem item, string value, Color backgroundColor, Color textColor);
}
I want to set badge in toolbar item i used this code after i Register the interface but it throw exception
private IToolbarItemBadgeService _toolbarItemBadge;
and in the constructor
public MainTabPageViewModel(IToolbarItemBadgeService toolbarItemBadge)
{
_toolbarItemBadge = toolbarItemBadge;
_toolbarItemBadge.SetBadge(MainTabPage.Main,MainTabPage.Main.ToolbarItems.FirstOrDefault() , $"{BaseService.CartCounter}", Color.Orange, Color.White);
}
Exception is thrown :
Unity.Exceptions.ResolutionFailedException: Resolution of the
dependency failed, type = 'System.Object', name = 'MainTabPage'.
Exception occurred while: Calling constructor
LGMobileApp.Views.MainTabPage(). Exception is:
ResolutionFailedException - Resolution of the dependency failed, type
= 'LGMobileApp.ViewModels.MainTabPageViewModel', name = '(none)'. Exception occurred while: Calling constructor
LGMobileApp.ViewModels.MainTabPageViewModel(Prism.Navigation.INavigationService
navigationService, LGMobileApp.Helpers.IToolbarItemBadgeService
toolbarItemBadge). Exception is: NullReferenceException - Object
reference not set to an instance of an object.
From exception you can see that your service is not registred and it can not be resolved.
You will need to register your IToolbarItemBadgeService interface, with implemenation inside of App.cs in RegisterTypes method.
Something like this:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IToolbarItemBadgeService, ToolbarItemBadgeService>();
// .. Other registration code
}
After this, you will be able to use IToolbarItemBadgeService which is injected in your MainTabPageViewModel.
Wishing you lots of luck with coding!

Class '_LinkedHashMap<String, ObjectPool>' has no instance getter 'iterator'

so I got a chunk of code below:
...
static final Map<String, ObjectPool> _objectPools = new Map<String, ObjectPool>();
static IPoolable get(Type objectType)
{
for (String name in _objectPools) // <-- This one throws an error
{
if (_objectPools[name].runtimeType == objectType)
{
return _objectPools[name].alloc();
}
}
}
...
and it throws an error "Breaking on exception: Class '_LinkedHashMap' has no instance getter 'iterator'."
Last time I checked it's the for loop that throws me the error (as commented in the code) but I don't have a clue what causes it or any workaround for it. I also have tested that the _objectPools is filled at least one element so it should make a loop, but it doesn't.
any idea? Thanks!
You have to use for (String name in _objectPools.keys).

Binding a static global causes error in MonoTouch

I started with a functioning bindings project, but I needed to add a global int for a status flag and I can't get it to bind without error. I started with the sample code and can't get this to work.
The code I add to my bindings file is:
[Static]
interface CameraEffects {
[Field ("kCameraEffectsZoomFactorKey", "CameraLibrary")]
NSString ZoomFactorKey { get; }
}
I get three errors:
obj/Debug/ios/PDFExpert/CameraEffects.g.cs(34,94): error CS0117: `MonoTouch.Constants' does not contain a definition for `CameraLibraryLibrary'
obj/Debug/ios/PDFExpert/CameraEffects.g.cs(34,76): error CS1502: The best overloaded method match for `MonoTouch.ObjCRuntime.Dlfcn.dlopen(string, int)' has some invalid arguments
obj/Debug/ios/PDFExpert/CameraEffects.g.cs(34,76): error CS1503: Argument `#1' cannot convert `object' expression to type `string'
If I leave the library off it tried to assign it to another unknown constant. This seems really screwed up as it is strait from the documentation.
I guess this should be bound like this
[Static]
interface CameraEffects {
[Field ("kCameraEffectsZoomFactorKey", "__Internal")]
NSString ZoomFactorKey { get; }
}
This is due to on the final app, the executable and the libxxx.a will be linked and merged together so it should work.
Alex
Another option that allows both assignment and retrieval of the value is to use the internal marshalling that MonoTouch uses. I got this from a Xamarin support person, notice that this is for manipulating an int, but should be a pattern you can use if you get the right marshalling code.
public unsafe static partial class RDPDFGlobal
{
static readonly IntPtr __Internal_libraryHandle = Dlfcn.dlopen (null, 0);
public static int RDPDFFeatures {
get {
return Dlfcn.GetInt32 (__Internal_libraryHandle, "RDPDFKitEnabledFeatures");
}
set {
var indirect = Dlfcn.dlsym (__Internal_libraryHandle, "RDPDFKitEnabledFeatures");
if (indirect == IntPtr.Zero)
throw new Exception ("Field 'RDPDFKitEnabledFeatures' not found.");
Marshal.WriteInt32 (indirect, value);
}
}

Type cast from Java.Lang.Object to native CLR type in MonoDroid

How to cast Java.Lang.Object to some native type?
Example:
ListView adapter contains instances of native type Message. When i am trying to get SelectedItem from ListView it returns instance of Message type casted to Java.Lang.Object, but I can't find solution to cast Java.Lang.Object back to Message.
var message = (Message)list.SelectedItem;
// throws Error 5 Cannot convert type 'Java.Lang.Object' to 'Message'
Please Help.
After long time debuging, have found the solution:
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
Usage example:
var message = list.GetItemAtPosition(e.Position).Cast<Message>();
bundle.PutInt("Message", message.ID);
After careful sdk study have found MonoDroid integrated extension for this purpose:
public static TResult JavaCast<TResult>(this Android.Runtime.IJavaObject instance)
where TResult : class, Android.Runtime.IJavaObject
Member of Android.Runtime.Extensions
The least magical way of getting a native type from the Spinner is to call
message = ((ArrayAdapter<Message>)list.Adapter).GetItem(list.SelectedItemPosition);
I used this code from above answer and it works fine to me
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
and this is how I used
var selectedLocation = locationSpinner.SelectedItem.Cast<Location>();
I am able to get my location object fine from spinner
For generic collections, the right answer would be to use JavaList, which is a Java.Lang.Object and also implements IList. But it involves more work that's for sure. This is actually just an adapter for Java's ArrayList implementation.
You could always try the JavaCast<> method (most of the views implement this)(not tested):
var message = list.SelectedItem.JavaCast< Message >();
If for some reason GetChildAtPosition is not possible, serialise the object to json string and then deserialise the string back to native class.
All of the above answers are correct but I found the simplest way for my case was to make the object a subclass of Java.Lang.Object.
For example I'm writing a Android app in Monotouch, mimicking the concept of a UITableView in iOS using the ExpandableListAdapter, which requires the equivalent of UITableViewCells, so I subclassed cell objects from Java.Lang.Object allowing me to implement a subclass of ExpandableListAdapter such as
public override Java.Lang.Object GetChild(int position, int childPosition)
Etc.
it's work for me:
public class HolderHelper<T> : Java.Lang.Object {
public readonly T Value;
public HolderHelper (T value)
{
this.Value = value;
}
}
test:
chkFileName.Tag = new HolderHelper<LinkInfo> (item);
LinkInfo link= (chkFileName.Tag as HolderHelper<LinkInfo>).Value;

Resources