Memory leak and weird crashes in android app - android

I am having an issue with what I believe is a memory leak.
Here are the reasons why:
I know that my app takes a lot of RAM, I see it on the graph in Android Studio
I sometimes get out of memory exceptions on my phone
I did a beta test and some users apps crashes, however some dont. Interestingly enough, a friend with an LG G4 (4 years or so old) is not having any issues and another friend with a Pixel 2 XL couldnt get the app open, it would crash on the main activity.
Sometimes when people would close the app and try to use the app switcher, the app switcher itself would crash. But once they would remove my app everything went to normal
If they tried to delete the app, it would crash the moment it would come up to the screen. Ex: They would go ahead and go to setting....until they reached the uninstall page. They scrolled down to my app and once the screen registered it was my app settings crashed. And the message read Setting is not responding, or something along those lines.
But here is my issue:
I checked all images and none are over 20kb large, as I read the limit is close to 600kb
I checked for leaks using the android studio built in function and nothing came up.
I changed all context calls to getApplicationContext()
I used LeakCanary and it only found an 8 mb leak that was happening. And that leak was on a locations class that I believe is androids.
Could that really be the problem?
Another potential issue, I am not sure how dumb I will sound but I havn't been using any threads. I started using them to open new activities for example:
final Handler handler = new Handler(Looper.getMainLooper());
new Thread(new Runnable() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
Intent open = new Intent(MainActivity.this, className);
startActivity(open);
}
});
}
}).start();
But I havnt seen any difference in performance.
But besides that, everything is working off the main thread.
I am not sure how bad of a habit that is.
Any advice will surely help me!
Thank you!

Related

Android lag after OOM crash

I'm currently serving a kiosk application on a dedicated tablet.
Most of them works well, but in some uncertain cases, an OOM crashed the app.
I use the below library to revive my app with the code inside my Application class.
com.jakewharton:process-phoenix:2.0.0
this.uncaughtException = Thread.UncaughtExceptionHandler { _, e ->
ErrorLogger.saveError(e)
try {
System.gc()
ProcessPhoenix.triggerRebirth(this)
} catch (e: java.lang.Exception) {
ErrorController.showError(e)
} finally {
Runtime.getRuntime().exit(0)
}
}
Thread.setDefaultUncaughtExceptionHandler(uncaughtException)
The app revives but after it, severe lags occur.
When the app starts fresh within a rebooted tablet, it takes the app about three seconds after launch to load everything from the server and internal database. But, after when it launches after OOM, it takes about five minutes to load, as if it's suffering from low memory. AlarmManagers stop working after an ANR of the AlarmManager.
Is there a way to clean the memory or a more fresh way to restart my app?
Yeah- fix your OOM crash. Use less memory. Any kind of library like the one above is a bad idea- especially since you're doing it on any uncaught exception and not just OOM, meaning you could be in any kind of bad state. Just blindly trying to restart your app on any exception is a horrible idea.
In addition, there's no way to fix the slow down. The lag is because it now needs to free and reallocate almost every object in your app. That's going to be slow. Just don't do this.

Android app randomly closes without any error

I'm currently working on a pretty big music app. And for some reason, my app randomly closes, without any error message.
I catch uncaught exceptions in the project using the following code:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {...});
but even if it works every time for obvious exceptions, I don't catch any error when the app closes by itself. Also, it's not device related, since I tried on 10 differents devices of different brands with different versions of Android.
My question is: has anyone experienced something similar and if yes, what was the solution of your problem? Or, in other words: is there any case where an Android app can close by itself without any error (and without using System.exit())
I know it's not a very specific question, but since I have no idea where it comes from, I can't do any better so far.
The default uncaught handler yo are overriding are the responsible to display the error to the user, the solution is to have a reference to the old one and call it on yours as follow:
final Thread.UncaughtExceptionHandler appDefault = Thread.GetDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
// DO STUFF BEFORE APP CRASHES
appDefault.uncaughtException(t, e); // call later, so the app crashes as default
}});

Why does my phoneGap Android application crash on resume?

I recently began writing a phonegap android application and noticed that when the app is resumed from the background (so I deploy the app to an android tablet, press the home button and then reopen the app from the menu) it gives a timeout error (something to the effect of Error code =-6 The connection to the server was unsuccessful) and then crashes. From what I've tested this only seems to happen when the "Don't keep activities" option is checked in the developer options, when that option is not checked the app works as intended.
It's also worth noting that I recreated the default phonegap application, ran it and encountered the same issue.
Can anyone explain why this happens, or suggest a solution? Obviously I can get around this problem by simply leaving the Don't keep activities option unchecked, but I'm guessing the problem will persist on any android device that has this option checked, which just won't do.
I'm using phonegap 2.5.0 and testing on a device running Android 4.0.3,
Thanks,
Josh
"Don't keep activities" is a developer tool to simulate user activity that would be extremely hard to test for. I personally believe all apps should be tested a second time (at least run automated tests) with this setting turned on, and devs should turn it on / off during development.
Your issue (which I've just ran into on v2.7) comes from a silly implementation of a timeout feature. CordovaWebView.loadUrlIntoView creates and locks (wait()) a thread for 20 seconds (default value), after which time it checks a value to see if the url finished loading - if it hasn't finished, it shows an error message.
This thread exists outside of the lifetime of your activity, so if the activity stops running, the Webview can never finish loading the url, and when the thread wakes up, it does Bad Things trying to show the error.
The same crash could happen without using "Don't keep activities" by simply having the user leave the application and then the system reclaiming the activity's resources (because it is low on memory or something) within 20 seconds.
Using a Handler seems like a more appropriate way to handle this timeout, but without changing the source there are a couple of hacky work arounds.
Call System.exit(0) at the end of your Activity.onDestroy() - this is horrible, but if you only have the one activity and no services, it might be an option
Use reflection to change CordovaWebView.loadUrlTimeout - this is horrible, but it should work, this is the value that the thread checks to see if the url loaded (inc by 1).

Returning to a surfaceview after onResume kills performance

My entire game slows down when returning from another app in the emulator (ie pressing the phone button, then back). frame rate drops by half - which turns it into sludge.
Everything is still there, apart from the thread which I kill when the (only) view is surfaceDestroyed (after calling join repeatedly, as with the lander sample.). I make a new thread and attach it - and the game runs, after a fashion.
if (_thread.getState() == Thread.State.TERMINATED)
{
_thread = null;
_thread = new TutorialThread(getHolder(), this);
_thread.setRunning(true);
_thread.start();
}
else
{
_thread.setRunning(true);
_thread.start();
}
This was after some headbanging and searching on this forum and the game crashing when returning. All the big objects in the game (bitmaps, sound etc) are in the main activity so they don't need to be destroyed or recreated I hope. Music is paused onPause and restarted onResume. It all works much more smoothly on a real phone (htc desire) but I'm worried this behaviour is something to do with 1.6 (which the emulator runs for broad compatibility) or something has been left dangling.
LOGCAT - Lots of SurfaceFlinger messages do turn up (write blocked for n ms) SurfaceFlinger ("executeScheduledBroadcasts skipped, contention on the client") and SurfaceComposerClient whinges about "lock_layer" timing out.
Also, running and jumping back to the home page then running the app (several times) on both the htc and the emulator will eventually cause the app to crash, but with no red issues turning up in Logcat. I'm baffled - any help much appreciated.
Cheers,
Robin.
I came to the same solution and it works well for me, though I don't think you need the if stament nor _thread=null;
There is anoter solution which I could not make it work which you can see here together with my/your way: Android crash when app is closed and reopened

Close Android Application [duplicate]

This question already has answers here:
Is quitting an application frowned upon?
(40 answers)
Closed 9 years ago.
Please suggest how I may close my whole Android Application with one line code.
Yes - Why, then how(sort of):
Short answer:
System.exit(0);
This nicely and cleanly terminates the whole java machine which is dedicated to running the app. However, you should do it from the main activity, otherwise android may restart your app automatically. (Tested this on Android 7.0)
Details and explanation of why this is a good question and a programmer may have a very legitimate reason to terminate their app this way:
I really don't see the gain in speaking harshly to someone who's looking for a way to terminate their app.
Good is a friendly reminder to beginners that on Android you don't have to worry about closing your app -- but some people actually do want to terminate their app even though they know that they don't have to -- and their question of how to do so is a legitimate question with a valid answer.
Perhaps many folks live in an ideal world and don't realize that there's a real world where real people are trying to solve real problems.
The fact is that even with android, it is still a computer and that computer is still running code, and that it is perfectly understandable why someone may wish to truly exit their "app" (i.e. all of the activities and resources belonging to their app.)
It is true that the developers at Google designed a system where they believed nobody would ever need to exit their app. And maybe 99% of the time they are right!
But one of the amazing things about allowing millions of programmers to write code for a platform is that some of them will try to push the platform to its limits in order to do amazing things! -- Including things that the Android Developers never even dreamed of!
There is another need for being able to close a program, and that is for troubleshooting purposes. That is what brought me to this thread: I'm just learning how to utilize the audio input feature to do realtime DSP.
Now don't forget that I said the following: I well know that when I have everything done right, I won't need to kill my app to reset the audio interface.
BUT: Remember, perfect apps don't start out as perfect apps! They start out as just barely working apps and grow to become proper ideal apps.
So what I found was that my little audio oscilloscope test app worked great until I pressed the android Home button. When I then re-launched my oscilloscope app, there was no audio coming in anymore.
At first I would go into
Settings->Applications->Manage Applications->AppName->Force Stop.
(Note that if the actual linux process is not running, the Force Stop button will be disabled. If the button is enabled, then the Linux process is still running!)
Then I could re-launch my app and it worked again.
At first, I was just using divide by zero to crash it - and that worked great.
But I decided to look for a better way - which landed me here!
So here's the ways I tried and what I found out:
Background:
Android runs on Linux.
Linux has processes and process IDs (PIDs) just like Windows does, only better.
To see what processes are running on your android (with it connected into the USB and everything) run adb shell top and you will get an updating list of all the processes running in the linux under the android.
If you have linux on your PC as well, you can type
adb shell top | egrep -i '(User|PID|MyFirstApp)' --line-buffered
to get just the results for your app named MyFirstApp. You can see how many Linux Processes are running under that name and how much of the cpu power they are consuming.
(Like the task manager / process list in Windows)
Or if you want to see just the running apps:
adb shell top | egrep -i '(User|PID|app_)' --line-buffered
You can also kill any app on your device by running
adb shell kill 12345
where 12345 is it's PID number.
From what I can tell, each single-threaded app just uses a single Linux process.
So what I found out was that (of course) if I just activate the android Home option, my app continues to run.
And if I use the Activity.finish(), it still leaves the process running.
Divide by zero definitely terminates the linux process that is running.
Killing the PID from within the app seems the nicest so far that I've found, at least for debugging purposes.
I initially solved my need to kill my app by adding a button that would cause a divide by zero, like this in my MainActivity.java:
public void exit(View view)
{
int x;
x=1/0;
}
Then in my layout XML file section for that button I just set the android:onClick="exit".
Of course divide by zero is messy because it always displays the "This application stopped..." or whatever.
So then I tried the finish, like this:
public void exit(View view)
{
finish();
}
And that made the app disappear from the screen but it was still running in the background.
Then I tried:
public void exit(View view)
{
android.os.Process.killProcess(android.os.Process.myPid());
}
So far, this is the best solution I've tried.
UPDATE: This is the same as above in that it instantly terminates the Linux process and all threads for the app:
public void exit(View view)
{
System.exit(0);
}
It instantly does a nice full exit of the thread in question without telling the user that the app crashed.
All memory used by the app will be freed. (Note: Actually, you can set parameters in your manifest file to cause different threads to run in different Linux processes, so it gets more complicated then.)
At least for quick and dirty testing, if you absolutely need to know that the thread is actually fully exited, the kill process does it nicely. However, if you are running multiple threads you may have to kill each of those, probably from within each thread.
EDIT: Here is a great link to read on the topic:
http://developer.android.com/guide/components/fundamentals.html
It explains how each app runs in its own virtual machine, and each virtual machine runs under its own user ID.
Here's another great link that explains how (unless specified otherwise in manifest) an app and all of its threads runs in a single Linux process: http://developer.android.com/guide/components/processes-and-threads.html
So as a general rule, an app really is a program running on the computer and the app really can be fully killed, removing all resources from memory instantly.
(By instantly I mean ASAP -- not later whenever the ram is needed.)
PS: Ever wonder why you go to answer your android phone or launch your favorite app and it freezes for a second? Ever reboot because you get tired of it? That's probably because of all the apps you ran in the last week and thought you quit but are still hanging around using memory. Phone kills them when it needs more memory, causing a delay before whatever action you wanted to do!
Update for Android 4/Gingerbread: Same thing as above applies, except even when an app exits or crashes and its whole java virtual machine process dies, it still shows up as running in the app manager, and you still have the "force close" option or whatever it is. 4.0 must have an independent list of apps it thinks is running rather than actually checking to see if an app is really even running.
You could finish your Activity by calling Activity.finish(). However take care of the Android Activity life-cycle.
You could close your Android Application by calling System.exit(0).
just call the finish() in the method you would like to end the activity in, for example when you use the onCreate() method, in the end of the method, just add finish() and you will see the activity ends as soon as it is created!
As per my knowledge, finish function close the current displayed screen only.
Refer this example (where see the answer given by 'plusminus'), it will sure help you to close your application.
Before doing so please read this other question too:
android.os.Process.killProcess(android.os.Process.myPid());
android.os.Process.killProcess(android.os.Process.myPid());
This code kill the process from OS
Using this code disturb the OS. So I would recommend you to use the below code
this.finish();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
The answer depends on what you mean by "close app". In android's terms its either about an "activity", or a group of activities in a temporal/ancestral order called "task".
End activity: just call finish()
End task:
clear activity task-stack
navigate to root activity
then call finish on it.
This will end the entire "task"
not a one-line-code solution, but pretty easy:
sub-class Activity, then override and add finish() to onPause() method
this way, activity will be gone once it enters background, therefore the app won't keep a stack of activities, you can finish() the current activity and the app is gone!
If you close the main Activity using Activity.finish(), I think it will close all the activities.
MAybe you can override the default function, and implement it in a static way, I'm not sure
I don't think you can do it in one line of code. Try opening your activities with startActivityForResult. As the result you can pass something like a CLOSE_FLAG, which will inform your parent activity that its child activity has finished.
That said, you should probably read this answer.
That's one of most useless desires of beginner Android developers, and unfortunately it seems to be very popular. How do you define "close" an Android application? Hide it's user interface? Interrupt background work? Stop handling broadcasts?
Android applications are a set of modules, bundled in an .apk and exposed to the system trough AndroidManifest.xml. Activities can be arranged and re-arranged trough different task stacks, and finish()-ing or any other navigating away from a single Activity may mean totally different things in different situations. Single application can run inside multiple processes, so killing one process doesn't necessary mean there will be no application code left running. And finally, BroadcastReceivers can be called by the system any time, recreating the needed processes if they are not running.
The main thing is that you don't need to stop/kill/close/whatever your app trough a single line of code. Doing so is an indication you missed some important point in Android development. If for some bizarre reason you have to do it, you need to finish() all Activities, stop all Services and disable all BroadcastReceivers declared in AndroidManifest.xml. That's not a single line of code, and maybe launching the Activity that uninstalls your own application will do the job better.

Categories

Resources