Dart on exit event - events

Is there a way to do something just before a Dart application running on the VM exits?
I'm writing a server application, so there is no specific point in time where my application will exit. I'm trying to talk to another process, but if a user closes my application (with ctr+c), or it crashes for some unknown reason, I would like to be able to tell that process to close as well.
It would be nice if something similar to this existed:
void main() {
onExit().then(() {
process.kill();
});
}
Thanks.
Edit:
I figured out how to detect Ctr+C:
void main() {
ProcessSignal.SIGINT.watch().listen((ProcessSignal signal) {
print("exiting");
exit(0);
});
}
Now if the application is ran from the Dart editor, is there a way to detect that closing?

Seems work in progress [POSIX signal handling (SIGINT, SIGTERM, SIGHUP, etc] (http://code.google.com/p/dart/issues/detail?id=15188)

Related

Core Data fetch: EXC_BREAKPOINT (code=1, subcode=0x18451a014)

Whenever I'm running the app in Xcode, I'm running into this issue and I can't really figure out what to do. I'm just trying to fetch all the items in an entity in Core Data, returning a Job array. The only thing I can do if this happens is stop the the app, close it, and open it in the emulator without clicking on the run button.
Here's the image of the code and the error I'm talking about:
Is there anything I can do to fix this? Is this a debug issue or is it a real app problem?
You would use something like this
func generateData(context: NSManagedObjectContext) async throws {
try await context.perform {
//Your fetch code here
}
}
Here is a WWDC video on the subject https://developer.apple.com/wwdc21/10017
The biggest thing I think is not chaining these calls try an condense them, I recently had a client that that was calling perform inside other performs.
async await is all about straight lines you should know exactly what is happening, when it is happening and in what order. There is no hanging on to anything.

Application Fails to Log Off

I have an application and I am facing some serious problems. This application is preventing the user to log off. Each time when log off it crashed.
How to log off properly?
Any suggestions will be well received.
Thanks.
write a bat file that calls two programs, the first is a .net C# console app that runs this code in it's main method:
foreach (var process in Process.GetProcessesByName("apppreventinglogoff.exe"))
{
process.Kill();
}
then the bat file can call "logoff.exe"
Assuming your application is an SAP Business One Add-On, it sounds like you're not handling the SAP application close/shut-down events:
obj.SBO_Application.AppEvent += new _IApplicationEvents_AppEventEventHandler(SBO_AppEvent);
Then in your SBO_AppEvent method you'd do something like this:
switch(EventType)
{
case SAPbouiCOM.BoAppEventTypes.aet_ServerTermination:
System.Windows.Forms.Application.Exit();
break;
case SAPbouiCOM.BoAppEventTypes.aet_ShutDown:
System.Windows.Forms.Application.Exit();
break;
}

How to terminate a Xamarin application?

How to terminate a Xamarin application from any of the activities?
I have tried both System.Environment.Exit(0) and System.Environment.Exit(1) as well as Finish() and killing all the activities.
It still opens one blank page with default activity name and a black screen.
Is there any specific solution for this?
If you are using Xamarin.Forms create a Dependency Service.
Interface
public interface ICloseApplication
{
void closeApplication();
}
Android : Using FinishAffinity() won't restart your activity. It will simply close the application.
public class CloseApplication : ICloseApplication
{
public void closeApplication()
{
var activity = (Activity)Forms.Context;
activity.FinishAffinity();
}
}
IOS : As already suggested above.
public class CloseApplication : ICloseApplication
{
public void closeApplication()
{
Thread.CurrentThread.Abort();
}
}
UWP
public class CloseApplication : ICloseApplication
{
public void closeApplication()
{
Application.Current.Exit();
}
}
Usage in Xamarin Forms
var closer = DependencyService.Get<ICloseApplication>();
closer?.closeApplication();
A simple way to make it work cross platform is by this command:
System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow();
Got it from this link.
EDIT: After using it for a while, I discovered that .CloseMainWindow() don't kill the application, only Closes it (well, thats obvious). If you want to terminate the app (kill), you shoud use the following:
System.Diagnostics.Process.GetCurrentProcess().Kill();
For Android, you can do
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
iOS explicitly does not provide any API for existing an App. Only the OS can close an App.
For iOS, you can use this code:
Thread.CurrentThread.Abort();
For Android, as #Jason mentioned here:
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
System.Environment.Exit(0);
Works for me.
In your activity, use this code
this.FinishAffinity();
I tried this code
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(async () =>
{
var result = await DisplayAlert("", "Would you like to exit from application?", "Yes", "No");
if (result)
{
if (Device.OS == TargetPlatform.Android)
{
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
}
else if (Device.OS == TargetPlatform.iOS)
{
Thread.CurrentThread.Abort();
}
}
});
return true;
}
In this, iOS and Android application close when a user chooses to terminate the application. Maybe it helps you.
A simple all-in-one combination of the previous answers, instead of the interface/dependency:
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(async () =>
{
var result = await this.DisplayAlert("Alert!", "want to exit?", "Yes", "No");
if (result)
{
#if __ANDROID__
var activity = (Android.App.Activity)Forms.Context;
activity.FinishAffinity();
#endif
#if __IOS__
Thread.CurrentThread.Abort();
#endif
}
});
return true;
}
System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow();
System.Diagnostics.Process.GetCurrentProcess().Kill();
None of the methods above helped my Xamarin Android app to completely shut down. I tried to close it from Activity B, having Activity A also open under it.
A clever guy left a trick here.
First call FinishAffinity() in Activity B (closes both activities,
however, the app is still alive in the background)
Then call JavaSystem.Exit(0) to kill the background app (I think it can be replaced with Android.OS.Process.KillProcess(Android.OS.Process.MyPid()); or System.Diagnostics.Process.GetCurrentProcess().Kill();)
My method to close the app:
private void CloseBtn_Click(object sender, EventArgs e){
FinishAffinity();
JavaSystem.Exit(0);
}
As your original question mentions activities, your question is specifically for Android, you should probably update the question title with that in mind to avoid people looking for a cross-platform solution coming here.
For iOS and Android (say in Xamarin Forms) you can just throw an exception, which while being the "heavy handed" approach, will do the job:
throw new Exception();
As this isn't the best user experience and you may only want to use this for iOS because on Android, you are likely to get a system popup telling you the app crashed. However, unlike other iOS methods like calling exit(0) or calling private iOS methods like "terminateWithSuccess" via a selector, it shouldn't fail app store validation purely based on how you do it. They may still fail you because your app tries to terminate itself.
You may want to implement something different specifically for Android, in which case Jason's answer is sufficient, again if not a little on the nose i.e. using this approach may not allow your app to clean itself up:
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
Either way, you should really question why you need to provide this option. Unlike desktop applications where closing an application is needed because apps reside inside windows which by design allow multi-tasking and are not task orientated, mobile platforms are primarily designed for users to focus on one task at a time. Once the user is finished the task, they should decide to exit this task by clicking the home button, back button or change app (task) button. This really applies to all platforms.
None of these work with Android 8. They all left the app in the background.
I can prove this by pressing the close all button and the app is still there.
For my testing I used a brand new simple Android app and tried all of your answers.
Application.Quit();
I'm assuming you are using C#
Call
public void Quit ();
This will quit the application the correct way without it "crashing".

Communicating over XPC with an app and launch daemon running as root

Is it possible to communicate with a launch daemon running as root and an application over XPC? When my daemon is running as my user I can communicate with it fine, when run as root it stops receiving my messages. Is this intended security inside Mac OS X?
I need to use low level xpc (for running on Lion as well). I know I can create a priviliged and signed helper tool that is running as root for my app. Will I be able to communicate with it with another process as well over XPC or sockets?
Thanks!
Small extract from my daemon code:
int main()
{
Logger::Start(Poco::Path::expand("/Users/Shared/Me/Service.log"));
Logger::LogInfo("Starting xpc_main...");
void* observer = nullptr;
CFStringRef observedObject = CFSTR("com.me.service.close");
CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
CFNotificationCenterAddObserver(center, observer, notificationCallback, CFSTR("ClientClosing"), observedObject, CFNotificationSuspensionBehaviorDeliverImmediately);
xpc_connection_t listener = xpc_connection_create_mach_service("com.me.service", NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
xpc_connection_set_event_handler(listener, ^(xpc_object_t event)
{
// New connections arrive here. You may safely cast to
// xpc_connection_t. You will never receive messages here.
// The semantics of this handler are similar to those of
// of the one given to xpc_main().
Logger::LogInfo("Event Handler on listener is called");
eventHandler((xpc_connection_t)event);
});
Logger::LogInfo("call xpc_connection_resume...");
xpc_connection_resume(listener);
CFRunLoopRun();
Logger::LogInfo("Main Program is Exiting...");
return 0;
}
The problem is that CFNotificationCenterGetDistributedCenter works only on the same user, root user will not send message to other logged in users..
You'll need to switch to CFNotificationCenterGetDarwinNotifyCenter.
Please note however, that you can't pass any data using this center.

How to launch a BREW application in background?

I know the Brew application have 3 types: active, suspend & background. Launch one BREW application as active or suspend is very simple. I know in BREW2.0 and later version, there is a new application type can allow we create one application in the background. It will not stay in the application stack and change status by active or resume command. It will always stay in the background no matter what user command system received. In one of my small project, I need to create and launch one background application like this.
Unfortunately, I cannot find a simple example on Qualcomm or Google. Is there any programmer who has encountered the same problem?
Yes, you are right. BREW2.0+ do support background application.
When we initial a background application, just like other normal new application, it can be launched by the brew application interface directly. You also can launch it by ISHELL_StartApplet function.
When you want to put one brew application in the background, you need do it when handle EVT_APP_STOP event and must set dwParam to false. After handling EVT_APP_STOP by this, the application will be put in the background. And if you want to change it to normal application, you need call ishell_StartApplet function to active to itself again.
Example code:
typedef struct _bgApp
{
AEEApplet a;
boolean m_bGoBg;
} bgApp;
switch (eCode)
{
case EVT_APP_START:
if(pMe->m_bGoBg)
ISHELL_CloseApplet(pMe->a.m_pIShell, FALSE);
case EVT_APP_STOP:
if(pMe->m_bGoBg)
*((boolean*) dwParam) = FALSE;
return TRUE;
case EVT_USER:
if(pMe->m_bGoBg)
{
pMe->m_bGoBg = FALSE;
// make applet active
ISHELL_StartApplet(pMe->a.m_pIShell, AEECLSID_BGAPP); }
else
{
pMe->m_bGoBg = TRUE;
// trigger EVT_APP_STOP to send app to background
ISHELL_CloseApplet(pMe->a.m_pIShell, FALSE);
}
return TRUE;
}
There is a limitation of background application. You cannot change the screen or communicate with user directly. Developer should be careful on the memory used by the background application. This is very important.

Resources