Get all AsyncTasks that are executed and currently running in Android app - java

I have a number of AsyncTask instances that are downloading some different content from the server. They run on executor:
final GetStationsTask getStationsTask = new GetStationsTask();
getStationsTask
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, URL_STATIONS);
Currently I have 3 subclasses of AsyncTask, but this number will not stay the same. I am also implementing some kind of retrying for tasks that were not completed for different reasons, and I would like to download everything from the beginning, if at least one of the tasks was not finished correctly (the data was not received):
// mHandler = new Handler(); // an instance variable
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
if (!allDataSet()) {
// here I want to cancel the tasks that are still running
// and rerun all of them
}
}
}, 30000); // I give all the tasks 30 seconds to complete
For that I suppose I need to know which tasks are currently running, which tasks have finished correctly and which ones were cancelled, because if all the tasks get restarted, I need to cancel the running ones first to prevent the data from being received multiple times. Any ideas how to solve it?

Override the base AsyncTask, and use that as your base class for all AsyncTasks. Have the overriden task have a static list of running, cancelled and finished tasks. Then add each task to the relevant list in the base class methods.

You can keep a list of AsyncTasks being currently executed in some singleton class, ie. Application extended one.:
List<AsyncTask<String, String, String>> downloadsAsycs = new ArrayList<AsyncTask<String, String, String>>();
inside of your asynctask's onPostExecute remove it from list using downloadsAsycs.remove(this). Remember to either synchronize on using this list, or always modify/read it on UI thread, ie. inside Handler from mainlooper or in onPreExecute/onPostExecute. You can check status of your async task using AsyncTask.getStatus(). After a while it starts getting complicated.
You could also switch from AsyncTask to Executors.newFixedThreadPool and ExecutorService.invokeAll. You could invoke all your tasks and have returned Future for all of them which allow to control them. You could even use Future.get with timeout on some back thread (even asynctask.doInBackground) to 30s, and after this time use Future.cancel if operation timed out.

Since the number of tasks is unknown, but they need to communicate in some way.
I would suggest to create 2 classes:
YourTask class - all needed tasks would be it's instances
TaskMediator - which manage communication as Mediator Design Pattern
So every time one task (YourTask) created it register it's self
to predefined class (TaskMediator) which manage their communication.
That way you get looser coupling between their objects,
but still keeps one communication channel
*By the way your TaskMediator can be Singleton as suggested by Marcin Jedrzejewski

Related

equivalent of an ExecutorService in D language?

The D documentation is a bit difficult to understand, how do I achieve the following Java code in D?
ExecutorService service = Executors.newFixedThreadPool(num_threads);
for (File f : files) {
service.execute(() -> process(f));
}
service.shutdown();
try {
service.awaitTermination(24, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
Would I use std.parallelism or std.concurrency or is this functionality not available in the standard library.
The example you posted is best represented by std.parallelism. You can use the parallel helper function in there, which when used in a foreach it will automatically execute the body of the foreach loop in a thread pool with a thread number (worker size) of totalCPUs - 1. You can change this default value by setting defaultPoolThreads = x; before doing any parallel code (best done at the start of your main) or by using a custom taskPool.
basically then your code would translate to this:
foreach (f; files.parallel) {
process(f); // or just paste what should be done with f in here if it matters
}
std.parallelism is the high-level implementation of multithreading. If you want to just have a task pool you can create a new TaskPool() (with number of workers as optional argument) and then do the same as above using service.parallel(files).
Alternatively you could queue lots of tasks using
foreach (f; files) {
service.put!process(f);
}
service.finish(true); // true = blocking
// you could also do false here in a while true loop with sleeps to implement a timeout
which would then allow to implement a timeout.
Though I would recommend using parallel because it handles the code above for you + gives each thread a storage to access the local stack so you can use it just the same as a normal non-parallel foreach loop.
A side-note/explanation on the documentation:
The std.concurrency is also very useful, though not what you would use with your example. In it there is a spawn function which is spawning a new thread with the powerful messaging API. With the messaging API (send and receive) you can implement thread-safe value passing between threads without using sockets, files or other workarounds.
When you have a task (thread with messaging API) and call receive in it it will wait until the passed timeout is done or another thread calls the send function on the task. For example you could have a file loading queue task which always waits using receive and when e.g. the UI puts a file into the loading queue (just by calling send once or more) it can work on these files and send them back to the UI task which receives using a timeout in the main loop.
std.concurrency also has a FiberScheduler which can be used to do thread style programming in a single thread. For example if you have a UI which does drawing and input handling and all sorts of things it can then in the main loop on every tick call the FiberScheduler and all the currently running tasks will continue where they last stopped (by calling yield). This is useful when you have like an image generator which takes long to generate, but you don't want to block the UI for too long so you call yield() every iteration or so to halt the execution of the generator and do one step of the main loop.
When fibers aren't running they can even be passed around threads so you can have a thread pool from std.parallelism and a custom FiberScheduler implementation and do load balancing which could be useful in a web server for example.
If you want to create Fibers without a FiberScheduler and call them raw (and check their finish states and remove them from any custom scheduler implementation) you can inherit the Fiber class from core.thread, which works exactly the same as a Thread, you just need to call Fiber.yield() every time you wait or think you are in a CPU intensive section.
Though because most APIs aren't made for Fibers they will block and make Fibers seem kind of useless, so you definitely want to use some API which uses Fibers there. For example vibe.d has lots of fiber based functions, but a custom std.concurrency implementation so you need to look out for that.
But just to come back to your question, a TaskPool or in your particular case the parallel function is what you need.
https://dlang.org/phobos/std_parallelism.html#.parallel
https://dlang.org/phobos/std_parallelism.html#.TaskPool.parallel

IntentService's own Thread

I know an IntentService itself runs on a different thread.
Also that it execute the onHandleIntent() and stops when that method is done.
my question is: are there any consequences for creating my own custom Thread inside the intent service?
I know it can be done in a Service but I want to know if thats a wrong way of using IntentService
for a bit more information what I need to do is to send lots of HTTP requests.
What im about to do is save on a DB the request strings, and run intent service that execute them.
That's why I use IntentService, the requests might take time and I want the service to shut down once the table containing the requests is empty.
I thought i might increase the speed of this service by adding my own threads to it as I will be running lets say, 5 threads each time.
EDIT:
This is the code I thought to do, I guess it will clear things about what im trying to do and if its possible.
protected void onHandleIntent(Intent intent) {
helper = new DBHelper(getApplicationContext());
File file;
//checks if the DB requests exists
while(helper.requestsExists()){
ArrayList<String> requestArr = helper.getRequestsToExcute(5);
if(!requestArr.isEmpty()){
//execute them and delete the DB entry
for(int i=0;i<requestArr.size();i++){
file = new File(requestArr.get(i));
new MyThread(file).start();// the DB entry is delete withing the thread
}
}
}
}
so this service will run as long as it got any DB entries on my SQLite db, after it will finish executing all of them it will stop.
is it ok or should i use Service for it?
As you have explained, the onHandleIntent is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic.
Why do you want to create a separate thread unless you want to handle multiple requests coming in and handle them in parallel ?
So, if you handle the action that you are suggesting in the onHandleIntent it will hold up other requests to the same IntentService, but it will not hold up anything else.
This answer might help you - start async task from onhandleintent

How to listen new db records through java

Currently I use while(true) and Thread.sleep() for checking for new records in the db and execute java code.
Here is an example:
public class StartCommands implements Runnable{
private Active_Job activeJob;
Runnable execute_command;
public StartCommands(){
activeJobs = new Active_Job();
}
#Override
public void run(){
int jobId = 0;
while(true){
//access the db and get one row from the table by the status
jobId = activeJobs.get(Status.NEW);
if (jobId > 0){
activeJob.updateStatus(Status.INIT);
execute_command = activeJob.getCommand();
new Thread(execute_command).start();
activeJob = new Active_Job();
jobId = 0;
}
Thread.sleep(10*1000);
}
}
}
I've few places in the code that I use this method. But I dont like the endless loop and check every 10 seconds for new row.
So what I'm looking for is some kind of listener: once new record has been entered - execute java code. Some of the inserts executed from the application and some are not.
The technique you are using is called polling. You are checking for new records, waiting a set amount of time, then checking again for new records. One good way to respond to new records might be to create a controller that handles inserting new records into the database and force all clients (who update database records) to use the controller to do so. Then the controller can alert you when there is a new record. To facilitate the controller's alerts, you can set up a web service where the controller can contact you.
I say that this "might" be a good way to do it because creating a controller and a web service is obviously extra work. However, it would make polling unnecessary. If you want to continue using your polling technique, you could make a service (producer) that does the polling and fills a queue with the new results. Your other program (consumer) can then retrieve items from the queue and do something with them.
There is no builtin "update listener" in MySQL (or any SQL database I'm aware of), so you have to build your own.
Notice that in your implementation, if two new rows are added you will handle one, wait 10 seconds, then handle the next one. Your code cannot handle more than one event every 10 seconds.
What you want to do is separate the polling of the database from the dispatching of the worker threads. Have the polling loop wake up every n seconds, read ALL new records from the database, and add them to a work queue. Have a consumer thread that is waiting on the queue and launches processors as messages appear on the queue. using a thread pool implementation.
#nir, Since there is no mysql database update listener in java so far, so what you can do is, create a database update trigger against the table, the change of which you want to listen. Within the trigger statement or code construct a function.Now from within that function call java function. Java function should be such that it modify some text, say "a". Now register the listener against the change in "a". And within the class implementing the text change listener of "a",put the code you want to execute.
The Condition Interface would work nicely for your needs. It will give you the granular control you are looking for, and it will avoid the problem of spinning the thread constantly.
http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html
Use a trigger, call a User Defined Function that uses sys_exec() to run an external app that signals an inter-process semaphore. Your listener thread can wait on that and, when signaled, process the new records.
In oracle exists something called database change notification http://docs.oracle.com/cd/E11882_01/java.112/e16548/dbchgnf.htm and I just implement a component like yours is there something like that in mysql or what approach you arrived?

Firing Android Activity methods on separate process at set interval

I am writing my first Android app(allot of fun so far!) and have run into a roadblock. I am using SDK tools 21.1 targeting Android 4.2.
I am trying to set up a system that allows activities to register to invoke a method at set time intervals. I wanted to do this in such a way that the processing of the request would be handled on it's own process to avoid making the UI unresponsive.
I have been doing some reading and have explored a few avenues. First I thought that a service would be a good way to go about this but found a fair bit of information suggesting that was not a good course of action due to the OS being able to kill services indiscriminately.
I'm now looking at using a ScheduledThreadPoolExecutor. I've created this simple class with an overridable method to pass methods around:
public abstract class BaseEvent implements EventListener {
public abstract void onFire(Object... params);
}
I've created this runnable task invoke the method:
public class HeartBeatTask implements Runnable {
private BaseEvent mCallback;
private Object mParams;
public HeartBeatTask(BaseAioEvent callback,Object... params){
mParams = params;
mCallback = callback;
}
#Override
public void run() {
Log.d(LOG_TAG,"Run called");
if(mCallback != null)
{
mCallback.onEvent(mParams);
}
}
}
I'm going to use it like this (inside an Activity)
ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(1);
BaseEvent callback = new BaseEvent() {
public void onFire(Object... params){
if(params[0] !=null)
{
Context context = (Context)params[0];
Toast toast = Toast.makeText(context, "Task ran", Toast.LENGTH_SHORT);
toast.show();
}
}
};
threadPool.scheduleAtFixedRate(new HeartBeatTask(callback,(this)),0, 5, TimeUnit.SECONDS);
This will execute the task every 5 seconds, although the callback method is only being run once.
I'm thinking that this may not be a good way to do things. My feeling is that I'm overcomplicating things. What I really need is the ability to have something that will execute a method, on a process other than the main thread, and at a set interval, that activities can bind multiple actions to. So, for instance, I may want to have a UI component update after a call is made to a database, and would want that to happen every minute.
Could any tell me if I am on the right track here? Is what I am trying to do a viable way to accomplish my goal? Is there a better approach I could be taking? Any advice or suggestions would be very much appreciated. Thanks!
a few suggestions for an Android beginner.
Don't call it a separate process. Process is a different thing (Google 'Linux process'), you want to call them on a separate thread inside the same process.
ScheduledThreadPoolExecutor IS better than anything else people will suggest you here such as Timers or PostDelayed.
But I think you do have a philosophical error here as to UI updates shouldn't be running on a timed manner but on an event base instead. Once your Db, Disk or Network operation finishes from a background thread you callback to the UI thread to update it immediately.
There`re several tools for that and I'll list a few, point the one I like the best, but let you do some research on each one
Handler: That's basic java way
AsyncTask: Nice framework but doesn't handle screen rotation
Loader: That's my preferred way
I think your approach is a bit complicated. Consider you example
So, for instance, I may want to have a UI component update after a call is made
to a database, and would want that to happen every minute.
I think I will do it this way.
Create a AsyncTask which will update the UI component.
Create a thread which will execute a new AsyncTask and sleep one minute in a while loop.
Start the thread in step 3. at some point.
Interrupt the thread if you don't want the component to be updated.
Example of step 2
while (true) {
try {
new updateTask.execute();
Thread.sleep(60000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
Android is a mobile platform and in all honesty each time you want something run, you better consider it separately. You may be killing the battery or using resources for no reason. I begrudge Zedge app everyday for running for no reason in the background at all times. Especially since on CyanogenMod kernel puts WiFi to sleep, while apparently it is currently on.
I am guessing this is more of an exercise and for running tasks at a specified intervals. One-offs, most universal can be done via AlarmManager class. But this may not be the best solution.
For some system wide events there is the BroadcastReceiver class.
While addressing
So, for instance, I may want to have a UI component update after a call is made to a database, and would want that to happen every minute.
Easier done via an Interface really.

On MultiThreading on the Android platform

Multithreading on Android is to some extent an easy task due to the various possibilities available for us.
However it would be nice to understand the difference between the approaches.
What is the best way to multitask and based on what preferences is it the "best"?
AsyncTask?
class MultiTasker extends AsyncTask<, , >
Runnable?
Runnable myRun = new Runnable(){
public void run(){
}
};
Thread T = new Thread(myRun);
T.start();
Handler?
class MultiTasker extends Handler
Asking which one is "best" is the wrong approach here - it depends on what you are trying to accomplish.
Runnable/Thread - This is the basic, lowest-level ways to control threading in Java. Provided in the Java APIs, so they're not specific to Android. You can use these in Android programs, but you'll probably want to use one of the other two options for most tasks (or use them in addition to Threads).
Handler - Provided in the Android APIs. You can post() a Runnable directly, or sendMessage() a Message (along with other options, such as providing a delay before processing a Runnable or Message). However, Handler isn't something you would use by itself to provide multithreading - it's use is usually to get back into the main activity (UI) thread. You'd start some other Thread to do a process in the background, and inside of it would post a Runnable using the Handler when you needed to update the UI. Or if you had a task that didn't necessarily need to run in the background, but did need to pop up and do something every so often, you could post a Runnable with a delay to activate later, and then at the end post itself again with a delay.
AsyncTask - Provided in the Android APIs. This class is for doing something on a background thread, optionally providing incremental updates on the UI thread, and ultimately providing an end result on the UI thread. The Params, Progress, and Result generic types are used to provide start parameters, progress update data, and end result data, respectively. Internally, AsyncTask uses Threads, Runnables, and Handlers to accomplish this task.
Its Always better if you go with AsyncTask().. because Thats something which has been built to solve MultiThreading issues in Android..

Categories

Resources