I have been playing with the latest templates (patched for Beta tools) and application life cycle. When I was looking for a place to initialize the DispatchHelper, I noticed that the Application_Launching event handler was being executed AFTER the MainViewModel constructor has executed. Is this the expected behavior?
This entirely depends on how and when you are creating your MainViewModel. If you think about it Launching should not be executed until all static objects and the main application object have been fully constructed.
You many want to delay construction of the MainViewModel until after you know whether you have been launched or re-activated. Even better would be to delay construction of the view model until after you know which page you will be displaying.
Related
I am using Prism to navigate between views in my WPF application. One view in particular I've implemented with the IRegionMemberLifetime.KeepAlive => returns false; to create a new instance of the view every time we navigate to the view (we need to do this for display reasons). This view also hosts a custom win32 control that I need to do some cleanup in using IDisposable.Dispose. When I navigate to my view and then away from it, I'd expect Dispose to get called (to run cleanup). I was able to achieve this by implementing a custom region behavior as discussed here, https://github.com/PrismLibrary/Prism/issues/7. All this is working fine except everything gets marked for disposal but the GC doesn't actually get rid of anything. I'm using Autofac as my IOC container and after doing some research I've concluded the reason comes down to Autofac and lifetime scopes of IDisposables, https://nblumhardt.com/2011/01/an-autofac-lifetime-primer/. Basically Autofac holds references to the IDisposable and the GC won't get rid of the old view because of this. For instance I'm registering my view in the Module as _container.RegisterTypeForNavigation(); I'm not able to register this with any sort of lifetime and I'm not sure how I'd resolve this with a lifetime specified? When I call RegionManager.RequestNavigate I don't see any sort of overloads to specify lifetime? Any ideas would be appreciated.
RegisterTypeForNavigation essentially does builder.RegisterType(type).Named<object>(name); which you can do yourself, too, of course and apply any lifetime you desire. There's no magic in registering for navigation, RegisterTypeForNavigation is just a shorthand.
To make Autofac ignore the IDisposables, one can write
builder.RegisterType<SomeView>().Named<object>(typeof(SomeView).Name).ExternallyOwned();
From the docs:
Disabling Disposal
Components are owned by the container by default and will be disposed by it when appropriate. To disable this, register a component as having external ownership:
builder.RegisterType<SomeComponent>().ExternallyOwned();
The container will never call Dispose() on an object registered with external ownership. It is up to you to dispose of components registered in this fashion.
So extending #Haukinger answer. This is what finally worked for me:
//builder.RegisterTypeForNavigation<SomeView>();
builder.RegisterType<SomeView>().Named<object>
(typeof(SomeView).Name).ExternallyOwned();
That ExternallyOwned() signals to autofac that the user is going to handle calling dispose and that autofac shouldn't track the IDisposable.
I would like to handle open events when a user double-clicks on a file that was created by my application, or drags such a file onto the dock icon.
I've therefore implemented NSApplicationDelegate's application:openFile: and application:openFiles: methods, which work as expected when the application is not running.
However, if the application is already running when the open event occurs, the application becomes focused, but the above methods are never called (breakpoints inside them are not hit) and the files do not open.
I also tried implementing application:openURLs:. This method has the same behaviour: it is not called if the application is already running when the event occurs.
Do I need to implement different functions to handle opening files when the application is already running, or is there something else I need to do/set in order for the existing functions to be called in those circumstances?
This is not mentioned in the documentation, but according to this answer the way that application:openFile: works is that it NSApplication forwards odoc Apple Events to its delegate.
Armed with this knowledge, I was able to find the following old Carbon call in the app:
osError = AEInstallEventHandler(kCoreEventClass,
kAEOpenDocuments,
g_OpenDocumentsUPP,
0L,
false);
I'm presuming this existing event handler consumed the Apple Event before NSApplication had a chance to deal with it. However, when the app is not already running, NSApplication handles the event before the line above setting up the event handler is called, hence the different behaviour.
Removing this old code from the build caused the NSApplicationDelegate methods to be called, thus fixing the issue.
Does the following method work?
- (void)application:(NSApplication *)application
openURLs:(NSArray<NSURL *> *)urls;
If your delegate implements this method, AppKit does not call the
application:openFile: or application:openFiles: methods.
I'm making a app with using XF PCL.
I started to doubt that XF's timer is not good enough for UI routine.
for example, in iOS native app, If View is not showing some reason (new page's pushed or something), scheduler is stopped automatically. Because it's for UI.
But Xamarin's doesn't seem like that.
It's still doing his job.
I hope at least within "Device.BeginInvokeOnMainThread(() =>" will be skipped when it's disappeared.
Am I right?
Should I put extra logic for that?
(like stop and restart timer?)
(or declare variable to skip in it?)
Thanks.
In Andriod usually when you are in Page1 and then you navigated to Page2, although Page1 is hidden it is not killed therefore the worker threads would still working (in that case it is the timer)
My suggestion is to override the OnDisappearing method in the code behind of Page1 and place the code that would make the timer stop or being ignored.
If it is for me , I would also place a boolean flag and called _isPageShown so when you override OnDisappearing and OnAppearing you just put the value of _isPageShown to false or true accordingly. Then in the callback of the timer you check the flag if it is true or false and act accordingly.
Ok, this is what I know so far about the Windows Phone 7.1 application life-cyle, but I still have a few questions.
Application Launching
- Called on application start-up, then proceeds to initializes App and then MainPage.
Applicaiton Deactivated
- Called when app becomes dormant (running but user is not using it). This calls the OnNavigatedFrom method of the current page before moving to the ApplicationDeactivated method in the App class. Once the application is Dormant it might become Tombstoned if the operating system needs more memory.
Application Activated
- Called when app comes out of Dormant or Tombstoned state, you can call IsApplicationInstancePreserved to figure out which (true means Dormant, therefore the state was preserved). Once this is called it moves to OnNavigatedTo.
Applicaiton Closing
- Called when user navigates backwards past the first page and the app exits. The OnNavigatedFrom method (on the first page) would be called as well.
So my questions mostly pertain to what is being initialized when the ApplicationActivated method is called.
-If the application was NOT Tombstoned is there anything you need to do to initialize the application or does the operating system restore everything back to the way is was? Is the constructor even called for the page that it is navigating to or was everything just frozen?
-If the application WAS Tombstoned do the page constructors get called? (I'm assuming so since nothing was saved). If the page constructors are called is there a difference between navigating to this page for the first time and coming back from a Tombstoned state?
These are all things that you can test yourself. Under the properties of an the application project you can enable tombstoning when you navigate away from the application. This setting is under the Debug tab.
Correct me if I'm wrong but here are the answers to the questions I posed.
-When the application gets activated and it hasn't been tombstoned then only the OnNavigatingTo method of the last page gets called (no page constructors). I don't believe there is anything you need to do in this case since the application state has been saved.
-When the application gets tombstoned you need to save any page data that you might need to reload since everything on the page is lost and when it becomes activated again the page constructor IS called before the OnNavigatedTo method.
Hope this helps anyone in the future with similar questions....
I want to load some data from mysql into my cocoa application view before the application starts.
I am sure that this should happen in the controller so that it can send the required data to the view.
I am looking for a method or common technique that is used for this sort of thing.
Many Thanks
Sounds like you're looking for the awakeFromNib function.
http://www.cocoadev.com/index.pl?AwakeFromNib
Cocoa gives you many places to perform tasks before and after objects are loaded from a nib, but it's important to read the documentation carefully to make sure things are happening in the order you expect. Usually I use the following strategy when I'm working on a Cocoa application:
Where appropriate I implement the
+(void)initialize method, which is called before any instances of a class are created. I'll probably set the app's default preferences here, for example.
In my application controller (app delegate), I implement the applicationDidFinishLaunching: delegate method to load my data file. If this works okay, I then create the window controller(s) and display any windows I want to show at launch.
In the window/view controllers, I override windowDidLoad: or loadView to perform tasks involving objects loaded from a nib. If I need to create any instance variables that don't involve the nib, I also override the init method and do that there.
If I need to do anything in my view objects after they're loaded from a nib, I'll override awakeFromNib.
You can use the - applicationDidFinishLaunching: or - applicationWillFinishLaunching: delegate messages, by implementing one of them in your application delegate/controller, and do whatever initialization you want there.