How to dispose of resources safely in android studio? - android

Just like in visual studio WinForms. I first close any connections before exiting the application. Otherwise, the application will still run in the background. I do this by clicking on the form itself and then click on the closeBeforeexiting property.
I then close all of my connection just before the application exits.
My question is then, how do I do this in an android studio? I want to close of a RFID class first before exiting the app. The reason for this is another app on the device that uses the same RFID class. But since the RFID class did not close safely and is still running in the background, the other application crashes because it cannot access this class.
Is there a closeBeforeexit property in android studio, perhaps in the res->layout->content_main.xml that provides me with the same functionality as in visual studio
I could do this using an exit button on the application but I see people generally use the back button that is already on the screen to exit the application. Is there any way I can access this back button and put my close connection function in there?
Answer:
#Override
public void onBackPressed()
{
try {
RFIDReader reader = RFID.open();
reader.stop();
reader.close();
super.onBackPressed();
return;
}
catch (ReaderException e) {
Toast.makeText(this, "Error: " + e, Toast.LENGTH_LONG).show();
}
}

Yes, you can intercept the back button and do anything you want there (even cancel the back navigation), but then you'll miss the cases where the user leaves by the Home button, or an incoming call, or through a notification...
What you should do instead is to override the onPause, onStop, and/or, onDestroy methods for your activity. They are all callbacks related to the activity life cycle, which you will soon need to learn about.
In short: onPause happens when you lose focus, onStop when you're no longer visible, and onDestroy when the activity is fully deleted (e.g. the user pressed "back", but usually not when they pressed "home").
In your case, onStop is probably the most suitable one.

My question is then, how do I do this in an android studio? I want to
close of a RFID class first before exiting the app. The reason for
this is another app on the device that uses the same RFID class. But
since the RFID class did not close safely and is still running in the
background, the other application crashes because it cannot access
this class.
You better read -> Understand the Activity Lifecycle to see how Android works with Activities and background tasks. If you're running the task in a background task, you should be able to close the RFID using close() method.
I could do this using an exit button on the application but I see
people generally use the back button that is already on the screen to
exit the application. Is there any way I can access this back button
and put my close conection funstion in there?
Using onBackPressed() method should help in your case. Keep in mind that finish() method is not a good approach to close the Activity.
Is there a closeBeforeexit property in android studio, perhaps in the
res->layout->content_main.xml that provides me with the same
functionality as in visual studio
layout->content_main.xml is the UI layout in Android and to be able to handle such things, you'll need to go with java or Kotlin.

Related

Application onCreate() NOT getting called every time

I have a very important initialization to do when the app starts. I found the best way to do is to put that code inside onCreate() of the class which extends Application class.
class ApplicationDemo extends Application{
#Override
public void onCreate(){
super.onCreate();
Log.d("LOG", "Inside onCreate()");
}
}
The Problem
I do not find the log statement to be executed every time the app is run. Like I start the app for the first time, get the log statement, then close the app and start again from the launcher. No, the log statement doesn't come.
What is the problem? How can I ensure a particular code is run every time my app is run and before anything else is performed?
My guess is that you truly have open your application just once.
I'm pretty sure that, after you closed your application, it truly just goes into the background, waiting to be put in the foreground again. (It does not get created again, you only reuse something you already have created.)
Try making sure you actually killed the process of your application before re-opening it; to make sure you actually closed & reopen it, and not just do a simple background-foreground thingy.
This sounds like an Android activity lifecycle problem.
I've included a link about pausing and resuming an activity
http://developer.android.com/training/basics/activity-lifecycle/pausing.html
It looks like when you are exiting the app, your activity is being paused. Likewise when you re enter the app, if the process is still running, the activity is getting resumed rather than recreated.
From here, you can either move the code to the onResume() or you can leave it in onCreate() but make sure that exiting the app kills the process. that could be done by putting
getActivity().finish();
System.exit(0);
in any path that directs the user to the home screen (onBackPressed(), exit buttons, etc.)
for starting, try putting a Log statement in onResume and watch where the two get called.
I hope this helps.
In Android you usually do not 'close' an application, but rather suspend it.
So, when you run it again, it just pops back.
To ensure your app is closed, open the list of running application, find your one and force stop it.
An application or an activity can exist even if it's UI is not displaying. The onCreate() callback is only called when the object is created anew.
This simply means that "every time an user opens the app from the launcher icon".
Then you should be putting the code in the onResume() callback of your launcher activity declared in the manifest. You can make the launcher activity a thin activity that only does this once-per-activation init and then launches the actual main activity.
Sure, there can be prior code run, such as onCreate() of the Application and onCreate() of the Activity so it won't always be the first thing to run, but it will be guaranteed to run every time you launch from the menu.
You can use from bellow code for Kotlin:
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
when (level) {
ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN -> {
/*
Release any UI objects that currently hold memory.
"release your UI resources" is actually about things like caches.
You usually don't have to worry about managing views or UI components because the OS
already does that, and that's why there are all those callbacks for creating, starting,
pausing, stopping and destroying an activity.
The user interface has moved to the background.
*/
System.exit(0);
}
ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE,
ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW,
ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL -> {
/*
Release any memory that your app doesn't need to run.
The device is running low on memory while the app is running.
The event raised indicates the severity of the memory-related event.
If the event is TRIM_MEMORY_RUNNING_CRITICAL, then the system will
begin killing background processes.
*/
}
ComponentCallbacks2.TRIM_MEMORY_BACKGROUND,
ComponentCallbacks2.TRIM_MEMORY_MODERATE,
ComponentCallbacks2.TRIM_MEMORY_COMPLETE -> {
/*
Release as much memory as the process can.
The app is on the LRU list and the system is running low on memory.
The event raised indicates where the app sits within the LRU list.
If the event is TRIM_MEMORY_COMPLETE, the process will be one of
the first to be terminated.
*/
}
}
}
And bellow code for Java:
public void onTrimMemory(int level) {
// Determine which lifecycle or system event was raised.
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
/*
Release any UI objects that currently hold memory.
"release your UI resources" is actually about things like caches.
You usually don't have to worry about managing views or UI components because the OS
already does that, and that's why there are all those callbacks for creating, starting,
pausing, stopping and destroying an activity.
The user interface has moved to the background.
*/
System.exit(0);
break;
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
/*
Release any memory that your app doesn't need to run.
The device is running low on memory while the app is running.
The event raised indicates the severity of the memory-related event.
If the event is TRIM_MEMORY_RUNNING_CRITICAL, then the system will
begin killing background processes.
*/
break;
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
/*
Release as much memory as the process can.
The app is on the LRU list and the system is running low on memory.
The event raised indicates where the app sits within the LRU list.
If the event is TRIM_MEMORY_COMPLETE, the process will be one of
the first to be terminated.
*/
break;
default:
/*
Release any non-critical data structures.
The app received an unrecognized memory level value
from the system. Treat this as a generic low-memory message.
*/
break;
}
}
On my phone even if I close an app it'll keep running in the background until you close from there manually.
You can use
onResume() {}
To run something every time the Activity gets called again.
You should in AndroidManifest.xml in tag "application" set field android:name=".ApplicationDemo"
UPD
author edited question with my assertions.

Android onRestart for whole App?

On Android, I'm trying to catch the event where my app comes back to the foreground from the background. In other words, the app was active, then the user minimized it (by clicking the home button or starting another app or something), and then the user runs the app again.
I can add the onRestart() method to an activity as follows:
#Override
public void onRestart() {
super.onRestart();
Log.d("MAIN", "onRestart called.");
}
But this only works when that specific activity is the active one when the user minimizes the app.
Is there a way to catch this for the whole app somehow? Or do I need to add onRestart to every single activity I have? (I suppose I could create a superclass on which all the other activities are based).
Thanks!
Is there a way to catch this for the whole app somehow?
No, because there is no concept of an app "restarting".
Or do I need to add onRestart to every single activity I have?
Presumably. Or, find a way to avoid needing to "catch the event where [your] app comes back to the foreground from the background".
I think the method you need is void onResume()
here is there android developers page for activities , check the "Implementing the lifecycle callbacks" part of the page .
http://developer.android.com/guide/components/activities.html
hope this helps.

Returning immediately in onCreate -- is that okay?

I have an Activity that should only get created once. That is, onCreate can only be called once. If it's called again, I want the Activity to do nothing.
Is it advisable to do the following?
protected void onCreate(Bundle savedInstanceState) {
this.setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
super.onCreate(savedInstanceState);
if(onCreateWasCalledAlreadyBoolean) {
setResult(RESULT_OK);
finish();
return;
}
//Do other stuff here
}
I assume you understand how the activity life cycle works. I mean, you are not trying to avoid something that does not apply here (thinking that onCreate may be called multiple times whenever it just onRestarts etc.).
Technically, it's perfectly fine.
However, you should be worrying more about why you need to call your activity ("A") again if it shouldn't be created at all, if that's what you're thinking.
If you've caught yourself checking if your activity A was already "called" (?), this could mean the previous activity ("B") has a mistake in the logic flow of the app, and that B instead should be checking if it must in fact start that activity A. I mean, if you need to decide if you must call an activity, check before starting it.
I don't think that's applicable if you're restarting the activity (e.g.: go Home, then navigate back), but then again you should be restarting it from where you left (B for what I can tell). You won't be navigating back to A. And you didn't give much detail, so I'd guess this is some kind of splash screen, like evilmage93 said.
If that's indeed some kind of splash screen, I would advise to show it whenever the user navigates back all the way to remove your app from the task stack (contrary to his advice). In other words, whenever the user restarts the app from its "front door".
Although that's ultimately a design decision, I prefer to see the splash screen whenever the app is being loaded ("entered") in the stack for the first time, and it should work fine if you (obviously) finish A before calling B (the splash screen is supposed to finish itself when done, even in its first run). It's a matter of consistency: the same app should behave the same way whenever the user performs the same task (start app from its "front door").
Still, I answered your question covering some general aspects because you asked in such way.
// edited:
Finally, by looking at that onCreateWasCalledAlreadyBoolean I'm afraid you may be trying to reinvent part of the activity life cycle mechanism. In this case, don't: proceed with your regular activity logic because the user expects that behavior. Generally I wouldn't advise people to break the normal loading of an activity just because it was killed and restarted by the system.
I don't see why not. Wouldn't it be simpler to not restart the activity at all though?
What are you worried about NOT being okay? Performance..Uncaught exceptions..Code clarity?

Stop application from running in background?

How to stop application from running in background in android?
I want my application to start fresh everytime it loads. How to do it programatically.
Override onStop method of your activity:
#Override
public void onStop(){
super.onStop();
finish();
}
But I think it's a bad idea to restart your app each time. It's better to override onStart method, and handle "restart" here.
Actually, your app doesn't "run" in background. Android OS keeps it in memory, or saves state of your activity to device (and then you can load it, using savedInstanceState param in onCreate method).
You can use onResume event to reload again, or look here.
EDIT:
Actually you need to use these functions to reload your application when user navigate it.
After adding finish();
This code will completely stop the application.
System.runFinalizersOnExit(true);
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
The whole Android ecosystem is based on the fact that the user shouldn't have to worry about "terminating" or "starting from scratch" an application. If you need to start your application from scratch every time, that's probably because you have tasks in your "scratch" that shouldn;t be there, and should probably be somewhere in onResume.
Please give us more details if you want a more detailed answer.
you should make use of Intent.FLAG_ACTIVITY_CLEAR_TOP to finish all other activities running in activity pool and call the first activity where you can ask to exit from app

Application getting purged by Android

I start my Android app, which in turns initializes some state on the first screen. The app has a many screens, and after randomly navigating through some screens, I minimize the app using the "Home key". Now after running some other apps from the phone, the OS decides that it needs to free up my app and hence kills it.
Now when I again click on the app icon, the OS remembers the history and tries to go back to the screen from where I minimized the app. But, the problem is since the OS purged my app sometime back, all my states are lost and the screen may not have any relevance.
How do I tackle this? How do I ensure that the OS calls the launcher screen, if it has been purged before and not the Activity in the history?
From your above comment about singleton class being initialized I also faced situations similar to you. Since I could not avoid it, what I did was I used the Application class. Whenever the OS decides to purge your app, the next time you launch the app, onCreate on the Application class will be called. Override the onCreate method to initialize the singleton class rather than doing the same in the launcher screen
The code snippet is as follows
public class CellApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Do your singleton class initialization here
}
}
You don't make sure the OS calls the launcher screen. The best way to solve this problem ist to save the state of your screens.
Everytime one of your activities is put in background onSaveInstanceState is called. This allows you to save the state of your app to the bundle that is provided in this method. If your app resumes onCreate will be called with the exact same bundle. You can now rebuild the app the same state the user left it.
Just check if the the bundle in onCreate is null. If it is null your activity is new if not rebuild the state from the bundle.

Categories

Resources