I have a pull based app that has to pull from the Server every 15 seconds. For that I used a normal AsyncTask, my code basically looks like this:
protected Void doInBackground(Context... arg0) {
while (true && this.pull_on ) {
pull_data();
TimeUnit.SECONDS.sleep(15)
};
Now I have the massive Problem that, the app just stops pulling out of the blue. No exeptions, the Status of the AsyncTask is 'running' the 'pull_on' variable is set to 'true' but it just stops pulling.
I can not reproduce this, it just happens sometimes, I can work perfectly for a long time and then it just stops.
Does anybody have an idea how this can happen?
Should I refactor and implement this with a timer?
Also what benefit would using a Service have over what I do know? Battery-power is not an issue.
Thanks for your help.
P.S. I should add that sometimes I start Activitys form the AsyncTask. Like this 'ApplicationManager.getCurrentActivity().startActivity( myIntent )' but I does not seam to be a Problem.
P.P.S.
Timer seams to be to limited for what I want to use, I do want to do something every 15 seconds but in some special case I want to stop the the pinging and then restart it again. The amount of hacking for that seams to be more work then just doing it with a AsyncTask.
That is a terrible design. You do not want to have an infinite loop on the background every 15 seconds. That will drain battery when the app is pushed to the background, as one of the main problems.
One proper way to do it is to have an Alarm and react to that. A timer is not a bad option either.
I suggest you look into moving this to a service, which is what it looks like
A Service is an application component that can perform long-running operations in the background and does not provide a user interface
It talks about long-running operations, but recurrent operations also make sense to be moved to a service.
Official documentation on Services is here: http://developer.android.com/guide/components/services.html
Related
I'd like to know the code or configuration needed to set that.
In my app, there are some places where I'm willingly make the app to sleep for several seconds, as it's needed for some reasons, with a Thread.sleep(long millis) function.
Problem is that on some Android APIS, at least on 25 and 26, usually that system message pops up in few seconds, confusing the user and maybe even causing the application not to fulfill the needed operations that need to happen while that sleep is happening if the user ends the app, which might cause even malfunctioning of the application.
I'd like to find a way of either forcing Android to wait for a good time like, for example, 1 minute, or to make Android aware that it's not that app isn't responding, that is willingly on a Thread.sleep function.
Is there any way to do that?
I'd like to find a way of either forcing Android to wait for a good time like, for example, 1 minute, or to make Android aware that it's not that app isn't responding, that is willingly on a Thread.sleep function.
TL;DR there is none.
Android apps should at all times be able to yield their position in the foreground to other apps. It's up to the users if they want to wait while some lengthy download is taking place or if they prefer to do something else and come back later.
You can't execute Thread.sleep() on the UI thread for long because this would "freeze the UI".
An example: Users should be able to leave your app by pressing the BACK Button at any time they wish to. If your method is blocking the UI thread, Activity#onBackPressed() can't be executed so the users can't quit.
What can you do? Move the heavy work to another thread (using e.g. AsyncTask or IntentService or some plain worker thread) and show some type of progress indicator to the users if necessary. You can/ should also toggle visibility or enabled state of Buttons etc. if required to avoid clicks which can't be processed at that point in time.
I think you have an implementation problem. The system message, known as ANR (Application Not Responding) occurs when the application cannot respond to user inputs, this may be caused by Ui thread blocking and that may be your case.
To avoid blocking the UI Thread just run your long time operations asynchronously. There are many ways to do that. You could use AsyncTask, AsyncTaskLoader, Thread, RxJava... Here you have some links to help you with that:
https://developer.android.com/training/articles/perf-anr
https://google-developer-training.gitbooks.io/android-developer-fundamentals-course-concepts/content/en/Unit%203/71c_asynctask_and_asynctaskloader_md.html
http://www.vogella.com/tutorials/RxJava/article.html
Im trying to make a simple game. The game is going great only I want to use a background timer. Like in citybuild games, a task takes x hours to complete and after that there should be a notification. What is the best way to do this? Do I need a background service, an alarmmanager, both? and is it smart to also keep the start timer of the task in an SQLLite db so if the timer stops he can still see it after it starts in the db?
Basicly what I'm asking is, what is best practive and do you guys have some pointers or better yet, examples/tutorials for me?
I recommend you to use the AlarmManager, it's native, you don't have to implement some background service, it doesn't consume battery, and it's easy to use.
Please refer to this tutorial.
Also, you can save the start time in SharedPreferences (or DB, as you prefer), and when the user re-starts the app, check if the job isn't already completed. This is an extra-step to make sure everything works as expected even if AlarmManager goes wrong
I do have a more general question, without any specific code. I will explain what my application does and how and what issues I can monitor. Maybe one of you had the same issues and can lead me to the problem.
The App:
It reads car diagnostic data (OnBoardDiagnostics) over Bluetooth and shows them in real-time in a ListView. I can start the update function by a "update Button".
How:
Everytime a new value is received via Bluetooth, a background Class (which handles the Stringforming) sends an Intentto notify the UI to update the ListView.
The Adapter Class of my ListView has the listening BroadcastReceiver registered and if it gets triggered, it will notify the ListView by notifyDataSetChanged().
Issues:
1.If I use an WakeLock to keep the screen on, the UI refreshing slows down after approx. 10 minutes.
2.If I press the power button, so the screen is off, it still slows down (I can see that, because I send the values to an webserver) but furthermore: If I turn the screen back on. I see the ListView stops for about 20-30 seconds and than normally continues with normal speed (not slow anymore).
So.. I think this is a very general question. I searched for WakeLock and sleep behaviour, but I couldn't find any similar issues. Maybe one of you can give me a hint, what the problem could be. Maybe one of you had a similar problem.
Any hint is appreciated!
EDIT 1:
Maybe the problem of the 2. issue is based on the lifecycles of my objects / activity.
If I press the update Button, an AsyncTask is started, which sends the Data (JSON, which contains one new value for all list items) to my Webserver. If the device screen is off, I still get the data every 2 seconds. If I turn on the screen, it stops for these 20-30 seconds as well as the UI. So I think my UI works fine. The Update Intents were sent right.
I have to check if I still receive new values in that background class, mentioned above.
Thanks to zapl
Thanks!
Except all possibilities I checked, i came across this article:
AsyncTasks for long running Operations
Short: There are some points you need to keep in mind if you are using AsyncTasks in very long running operations (>20min). My Problem was, that I used the AsyncTask as an inner Class. After a long period, when the Activity that created the Task was destroyed, the AsyncTask still kept a reference of this activity.
After I used a Bus, described in the article above, the UI worked fine!!
So, if anyone else noticed performance problems of your App, I recommend that article.
Thanks for all the other hints!
Have fun coding!
I have developed an application that is used very intensively for hours, makes a lot of web services calls, uses a lot of async tasks and does a lot of operations on an sqlite database. The problem is that absolutely randomly the display dims, as if it goes in power saving mode (this is happened also when the battery was charged) and the UI does not respond at all (the log written for buttons click are not written). If I click the home button the phone works correctly and every app works fine. If I go back to my app the display dims again. I really don't have any idea about the cause of this behavior, I really hope some of you can help me because my boss wants an explanation because the customer wants an answer.
EDIT: I've noticed that when the problem occurs, it's just after unlocking the screen, so it should have something to do with app resuming, but I don't really have any idea of what is causing this behavior.
It seems that some operations may be blocking the main UI thread and the app goes to not responding state. Check if any such intensive operations are done in UI thread.
As jaibatrik says, this might be caused by doing too much work in the UI thread rather than in background threads, AsyncTasks etc. One way this may be achieved which is less obvious is if all the work is correctly done in a background thread (of some type) but a UI thread operation is waiting for the outcome of a background thread operation.
you could prevent display dim like this.
ll.setKeepScreenOn(true);
you should handle onresume(), onpause() & co.
maybe you create memoryleaks within your backgroundtasks or services.
can someone please help me?
I would like to write a program which uses a service to periodically update a text view on an activity.
I do this by having ActivityA with a 2 buttons to start/stop my service. In the service I run a timer which triggers every second. From here I need to have this launch and update a text view on ActivityB which at present is just a counter value.
I'm sure there are likely better ways to do this, such as using only one activity, maybe using a thread but the main design consideration is to have the service running even if my activity is destoyed (the counter value would instead go trigger some alarm or file write instead of a text view update).
Sorry for rambling. I find the android developer resources offer too many solutions!
Thanks
Ben
In the service I run a timer which triggers every second.
Why? Most Android devices run on batteries. Batteries are never big enough. What value are you giving the user to justify your expenditure of CPU and RAM (and, hence, battery life)?
From here I need to have this launch and update a text view on ActivityB which at present is just a counter value.
Where is "here"?
I'm sure there are likely better ways to do this, such as using only one activity
I would think so.
maybe using a thread
Probably not.
but the main design consideration is to have the service running even if my activity is destoyed
This is significantly more complicated than you are perhaps thinking.
(the counter value would instead go trigger some alarm or file write instead of a text view update).
If your goal is to do something at a particular time, use AlarmManager.
I suspect that there is a better approach for whatever it is that you are trying to do than the path you are presently headed down. Unfortunately, since I do not know what it is that you are trying to do, I have limited ability to provide more specific advice.
I think what you want to do is at best done with an simple AsyncTask. If you use the onProgressUpdate method you can increase the value in the textview at every time you reach a certain point during your background work. It is also able to cancel the background work etc. There is no need for the full Service, Thread work.