Android: Use timer to perform a task periodically - android

I am currently working on an android music app which needs to call an api to get the link of album-art and put it in slider, after 'x' seconds I have to call another api and get an url of advertisement and load it on slider. And then after 'y' seconds I have to repeat the whole process.
What is the best way to implement it without having memory leakage issue. I am currently using 'https://github.com/daimajia/AndroidImageSlider' this slider.
To be more specific, let's say I have two functions, I need to call both periodically after '12' and '3' seconds, how can I implement it.

you can achieve this by using postDelayed()
final Handler h = new Handler();
h.postDelayed (() -> {
//your code here
}, DELAY_TIME);

Related

Android Work Manager: Can I force prune the Completed Jobs?

I am uploading photos in my app and want to provide the User with the upload progress. The way I was going to do this is have a global tag, UPLOAD_MEDIA_TAG and use that whenever I am creating a OneTimeWorkRequest. That way I can just observe the WorkManager.getInstance().getStatusesByTag(UPLOAD_MEDIA_TAG) LiveData, and whenever a job completes I would show a percent completed. (I.E. Uploading 3/10 photos would show 30%). Then once all 10/10 photos have been uploaded, I would hide the progress bar. This works great as it easily supports leaving the app, coming back, and you will see the Progress Bar as soon as the app launches right where they left off.
The problem is that once all 10/10 jobs are finished and marked as completed, those jobs will stick around until the WorkManger prunes them. So if the user uploads 5 more photos, the LiveData is returning 15 statuses instead of 5, throwing off the percent calculation.
I noticed there is a method OneTimeWorkRequest.keepResultsForAtLeast(duration) but what I would want is something like, keepResultsForAtMost(duration) or a WorkManager.getInstance().forcePrune() method that would cleanup all the completed jobs from the database.
Any help would be great!
After submitting an issue with Google, they are saying there will be a function called, pruneWork in Alpha03.
As of alpha release, you don't have much control over job pruning since it is managed by WorkManager. You can however observe the lifecycle of WorkManager to get job status and take necessary action as follows:
WorkManager.getInstance().getStatusById(myWork.getId())
.observe(lifecycleOwner, workStatus -> {
// Do something with the status
if (workStatus != null && workStatus.getState().isFinished()){
// Stop observing data or do other action
}
});
Note:
Use [WorkManager 1.0.0-alpha03 which has several bugs fixed and new features introduced. One you might be interested is:
Added WorkManager.pruneWork() to remove completed jobs from the internal database

Best practice to use AsyncTask in autocomplete?

I am using Async task to populate auto-complete suggestions from server.
Problem:
when user types and removes the text in edittext so many times.
lets say he typed: cofee > cof > coffee >coffee late .... etc for so many times.
for each text changed after 3 keyword(threshold) i am initializing an asynctask and ask for result.
so in current scenario i have so many threads running in background. so some of my latest async threads are waiting for there chance.
Whole this make my app very slow.
What can I do to tackle this problem?
If it is possible to load entire data from server at beginning...then you can avoid calling asynctask repeatedly and fetching the data from server. This will improve performance of you app. If data displayed in Listview is String, following link show how to filter it:
http://www.androidhive.info/2012/09/android-adding-search-functionality-to-listview/
And if custom object is used in ListView adapter, try:
Filtering ListView with custom (object) adapter
Hopefully this helps.
You should cancel the current task before issuing a new one. Use AsyncTask#cancel(true) for that and make sure that the execution of the task can be quickly stopped. This means correct handling of interruption and frequent checking whether the task was cancelled in the body of AsyncTask#doInBackground.
And you cannot execute again the AsyncTask you have cancelled. You have to create a new one. (Trying to execute it again leads to IllegalStateExceptions)
It worked for me by cancelling the task each time you change the text (if it is still running).
You need to define your request once outside the listener(private for the class), and then start your listener function by (if your request is not finished, then cancel it).
define your request out side the function
private YourSearchTaskClass YourTaskReq = new YourSearchTaskClass();
then start your addTextChangeListener/afterTextChanged by this
if (YourTaskReq.getStatus()!= AsyncTask.Status.FINISHED)
YourTaskAvReq.cancel(false);
YourTaskReq= new YourSearchTaskClass(keyword);

Do after specific time, Android Runnable

Ive got an app with a class that implements Runnable. Where a thread is started and the run() methid overridden. This runs my graphics.
1.st question : how often is the run() called upon? i havent set a time for this so it must be a default value?
2.nd question : i want stuff to be done after a certain amount of time (2min,5min,10min) etc. What would be the best way to go about doing this, i was thinking about using an int as an counter and once it hits a specific value does what i want.
1.st question : how often is the run() called upon? i havent set a time for this so it must be a default value?
The run() method in your Thread is called when you call it eg. yourThread.start();
2.nd question : i want stuff to be done after a certain amount of time (2min,5min,10min) etc. What would be the best way to go about doing this, i was thinking about using an int as an counter and once it hits a specific value does what i want.
There are to options. Either you could call Thread.sleep() method (NB: Never do this in your UI thread).
Or you can do it the way you described above. So in your run() method you would have a while() loop and check on every iteration if the difference of the lastUpdate and the current time in milli seconds is bigger than the wanted period eg. 2 min, 5 min or 10 min.
I hope this helps.
Regarding question 2 - use ScheduledExecutor
1.st question : how often is the run() called upon?
You can find out for yourself, put this at the start of your Runnable:
Log.v("Running Runnable", System.currentTimeMillis() + "");
2.nd question : i want stuff to be done after a certain amount of time (2min,5min,10min) etc.
Extend a HandlerThread (it initializes the Looper for you!), add a Handler as a class variable, and use the Handler's postDelayed() or postAtTime() methods.
The exact amount of time in between calls to run() depends on the processor. The time between each call is the sort of thing that's really visible by the nanosecond. If you're trying to create a timer, I'd recommend using System.currentTimeMillis(), calling it in the run() method, and once the difference is greater than or equal to 1000 milliseconds, the actual timer decrements by one. This will keep track of seconds, and you can use it as a base for minutes and generating other events at specific times.

android: My software does not work in a linear manner

i have this code
TextView B = (TextView)findViewById(R.id.txtMSG);
B.setText("Loading...");
Call_My_Func();
B.setText("");
my function Call_My_Func() work for 1 minute, but i can see the message "Loading..."
is there in java for android something like Application.DoEvent() like i use in C# ?
You are not seeing the message because you're blocking the UI thread with that long running call (as you seem to know based on your DoEvent comment).
An easy way to move long running operations into another thread is Androids AsyncTask.

Reeating task every specified duration with background worker in .net?

I have a win form, where I have a block of code which keeps checking for entry in database, every say 2mins. Now I want to avoid using timer control, for performance reason; can the same be achieved using background worker?
Create a new thread and than
While True
CallTheDB()
Thread.Sleep(120000)
End While

Categories

Resources