I have been running into a problem with my application, which I have no idea why. The following is:
the application is a large, commercial project, which makes several connections to the database, with a login system and everything else
I noticed that if I leave the app in the background for about 10 minutes, for example, it terminates my connection and restarts everything again, forcing me to log in again.
The only guarantee I can give is that they are not connection problems with my server, as in my tests it never failed.
Anyone who might have any idea why?
(I know that the explanation of the problem was a little vague, but the situation is very vague even for me)
How did I find my problem?
The user of my application was using a bluetooth barcode reader, which was programmed to automatically turn off after a period of inactivity. I noticed that whenever the bluetooth device turned off, my application would lose its previous state if it was in the background. Using the LogCat tool, I realized that my process was being killed by the system itself. The messages always looked like these:
W/ActivityManager: Force finishing activity
my.project/.view.activities.MyActivity
I/ActivityManager: Process my.project (pid 12984) has died
After much research, I found that the Android system interprets some external events as configuration changes, eg screen rotation change, Bluetooth device connection/disconnection, etc.
When such a change happens, Android, by default, kills your app's process and restarts it completely again, so that the app adapts to the new behavior. In my case, there was a NullPointerException in the code, which I hadn't handled correctly, so the application went back to the beginning, losing its state data.
However, in other application screens the mentioned Exception didn't occur (so it doesn't go back to login when starting), but even so I lost some screen data, like something that was typed in an EditText, for example.
How did I solve it?
On researching again, I found that you can let Android handle these configuration changes itself, telling it not to restart its process. To do this, just add in your Manifest, in the desired activity, the line:
android: configChanges = "keyboard | keyboardHidden | navigation"
As in my case the problem was with a bluetooth keyboard, I added these options keyboard | keyboardHidden; some keyboard models, for some reason, also change Android navigation, so I added navigation. After this change, done! No more problems!
P.S. 1: Unfortunately, not everything always works out. Adding android: configChanges won't work if your activity has fragments (I'm still trying to figure out how to solve this).
P.S. 2: This is not a good practice, I need to make that clear to you. For me, it's okay to do it this way, as my application responds well to changes. After all, my app is simple. Only use this feature that I explained if it is your last option or, if like me, your application is not so complex. Remember: this is not a magic solution to problems; in my specific case it worked fine, but for you, it might break your application.
P.S. 3: I recommend taking a look at https://developer.android.com/guide/topics/manifest/activity-element#config, in the android subtopic: configChanges. Listed are all the configuration changes a device can make.
Related
Some users report an issue: they launch the app, the splash screen appears, but nothing else happens. Splash screen just stays on without ANR or errors.
I can't see any logs because no loggers were initialized yet, and I don't even know if the onCreate method was called.
Important notes:
99% of users don't experience this
users that report such issue say that it's persistent - they can't use the app at all
some users say if they launch google play store first and then launch app - it works fine, but without that step it always freezes at the splash screen, so they have to launch google play store each time before launching the app
To send any data anywhere I need to initialize a bunch of dependencies, but looks like it doesn't even get to that point. App works fine on millions of devices, but a few thousand users reported this issue. Cannot post application initialization code as it's huge.
Questions:
What can possibly be the reason of this?
Where would be the best place to start searching for the bug?
Is there a way to determine the first line of code where the app is not launching as it should?
Is there something that the google play store triggers that applications need to launch properly?
It was because of googlePlayStoreAppUpdateManager.appUpdateInfo check for updates that returns a Task, but sometimes it doesn't actually call nor success nor fail listeners, so we hang forever. Solution was to add RxJava wrapper with timeout and limit waiting time for Google to answer to some reasonable time.
It looks like some devices, like Xiaomi or Honor are not allowing google play manager to check for updates unless explicitly started by the user, so this check should be done carefully.
I observed one behavior in fire stick, apps which are present in main screen are always calling onDestroy on app launch, which cause app to restart and not launch where user left off.
I checked with Netflix app, even there onDestroy gets called on launch but they are preserving state before app close, and so able to launch from last exit state.
My doubt is, why fire stick treats main screen apps differently? I searched but did not find proper answer. Mostly people talking about is memory getting full which is not the case here.
I'm making an Android app that act as an IOT host (I use serial communication and send it to Arduino). Is there a way to always set Android to run this activity (never sleep & always inside the activity)? It is important for it to not leave the activity since all the control and db access is done through it. So far what I've found already available is kiosk app in which it act as a launcher with limited app and such but none of the lock the android to an activity.
Thanks for answers & comment!
If you're curious :) The reason I use Android is that it needs a control panel UI and connection to a database, using RPI and other stuff would just get it to be more expensive.
there a way to always set android to run this activity (never sleep & always inside the activity)?
Not really. You are somehow looking for kiosk mode, or you can make your app acting as launcher (but it all depends on use case - if your app is only one on the device then this is all fine, otherwise you would need to put a lot of efforts to jail user)
it is important for it to not leave the activity since all the control and db access is done through it.
It sounds like your app architecture is just designed wrong.
So, I just rebuilt my MediaPlayer service from the ground up, mainly to improve and update the code, but also because it just WASN'T going to work with MediaStyle notifications.
So, now I have a notification, and when I press the Pause button, it logs "onPause" although nothing else I have set to log in the onPause is there in the logs, and they all use the same tag, so that's weird.)
What it does though, that really bugs me. It logs that I pressed the right button, but then it just seems to start another mediaplayer and play that.
This is the offending class. The latest debug and release signed APKs can be found in the mobile package if you want to see the behavior for yourself.
Is there something I'm missing in, say, the AndroidManifest.xml? The service seems to be receiving the intent, but just ignoring it, which is weird.
I'm honestly lost. I barely have a grasp on intents or pendingintents, let alone IBinders.
My compiler wasn't working properly. My code was fine. Somewhere between compiling and installing, it used an older version of the APK, or at least one class.
I basically want to add a feature to an app I am making but it would require me to know when the user closes certain apps. For example if the user closes any of the following; Maps, Firefox, Facebook, and Camera, A yes/no notification, kinda specific to the app, would come up for the user to answer.
It's something that sounds complicated i know but im pretty sure I've seen it done on a few android apps before.
Thanks
edit: so i was thinking since tasker can perform a task upon opening an app and then stopping the task when closing the app i can do what i want right?
The closest option available for monitoring the status of other applications and packages is through the use of a BroadcastReceiver registered to listen for Intents related to packages or applications. I looked through the intents available (the actions are constants with names starting with ACTION_), and none were directly related to another application closing, however you may be able to capture something, such as a changed battery status, that can look at the status of running applications in question.