Do I need to use multiple AsyncTask subclasses? - java

My app has FTP functionality and now I want to implement a ProgressDialog for the various operations (Connect, download, upload, file list etc.)
I found this snippet here on stack and it seemed like a good starting point.
public class LoadData extends AsyncTask<Void, Void, Void> {
ProgressDialog progressDialog;
//declare other objects as per your need
#Override
protected void onPreExecute()
{
progressDialog= ProgressDialog.show(FTPConnector.this, "Please wait for ","Process Description Text", true);
//do initialization of required objects objects here
};
#Override
protected Void doInBackground(Void... params)
{
//do loading operation here
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
progressDialog.dismiss();
};
}
I've implemented it as a subclass of my FTPConnector class which contains the various methods for connect, download, upload, listfiles,rename, delete. Do I need to create a subclass of ASyncTask for each FTP operation? If not what can I do?

Firs of all, I was under the impression that using AsyncTask as a subclass of activity was disfavored since the task would retain a reference to the activity that started it which could cause problems. I've generally used AsyncTask as its own class and passed in the context of the activity that executed it. You should look into that.
Second you could make different tasks for each server transaction. I guess it depends how many their are or how complicated your application is. Other than that you could use one class with a switch statement in the doInBackground method and pass in a string tag as one of the varargs (assuming your task takes only strings as initial arguments). This just seems cumbersome and ugly.
I'd probably just make one task for each transaction.

Do I need to create a subclass of ASyncTask for each FTP operation?
Not necessarily but that will depend on the logic that you use inside your AsyncTask methods. If you make them to handle the function that operation needs then you will be ok. But depending on the logic for each operation, it may be easier to control if you create a separate class for each.
However, note that you will need to create a new instance each time you need to call execute(), according to the Docs
The task can be executed only once (an exception will be thrown if a second execution is attempted.)

Using AsyncTask for multiple transaction will work, but this is not proper solution. As written before: it could cause problems. I suggest you to take a look at this video(it's about REST client, but described patterns will work for you too). Follow these rules:
Perform transaction in a separate thread
Every thread must be started from a Service
To retain state of transaction use database(don't keep states in a memory)
Use SyncAdapter. Not sure that it works for you(it's depends on your needs)

Related

What does an "asynchronous method" mean in Java?

I am in the process of working through the android billing example for an app. The sample app refers to an asynchronous method. I have had a look on the web and I cant seem to find a good definition, please can someone help with an example.
Sample as follows:
// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Is it a method that does not immediately return a result?
If I am not mistaken, you are referring to this method startSetup that accepts a final OnIabSetupFinishedListener and supposedly sets up the billing.
What you seem to be confused about, is this rather syntactically obscure feature of Java called the anonymous inner class.
Let me attempt to answer your question to make it easier:
Is it a method that does not immediately return a result?
Yes, sort of (it of course does not return anything for it is a void method). It, simply speaking, is a method that accepts an instance of the interface OnIabSetupFinishedListener and does some of its job asynchronously as stated in the Javadoc and returns nothing:
This will start up the setup process asynchronously.
Thus, this method is similar to what any other void Java method looks like. The only additional implementation information is that some kind of communication is set up between the listener you pass to this method and some other objects.
But that communication is going to happen at a later point in time, not at the time you call this method, startSetup. Thus, what is important is the call site, i.e. how you are going to call this method in your own app. This, hopefully, happens at the time of setting up your app and you need to get it quickly running and hence this method provides a callback mechanism and returns as soon as possible in a synchronous manner without unnecessary delay. This means your calling thread can make progress and the listener you passed to this method can be utilized later in some other thread when an appropriate event occurs.
The confusion also comes in part because of the way anonymous inner classes are typically coded. Thus, your call site may look like the following:
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
// Hooray, IAB is fully set up!
}
});
Here, you are providing an anonymous implementation of the interface OnIabSetupFinishedListener directly at the call site (without actually creating a separate class implementing that interface, using the construct like class MyListener implements OnIabSetupFinishedListener).
Yes. In this context, "asynchronous" means that the method will return immediately and execution will continue with the statement following the method call. Sometime later, the onIabSetupFinished(...) method will be called on the listener. This is called a callback. An important consideration with asynchronous callbacks is what thread they are called in. You'll need to refer to the documentation for this API to find that out.
An asynchronous method is not a typically request/response
You can think of this like a promise or something that will reply without pooling.
In your case you are creating an anonymous listener that will resolve the promise here
public void onIabSetupFinished(IabResult result){
//you will eventually get the response here
}

How to wait for an asynchronous task to return

So I have a problem and I am wondering how to solve it if it can be solved at all.
I have an external library class called Messenger that defines the method sendMessage(String msg). I also have the following MessengerManager class
public class MessengerManager{
private Messenger messenger;
public MessengerManager(Context context){
messenger = new Messenger(context);
}
public void message(){
String msg = "12435";
messenger.sendMessage(msg);
// Do more stuff
.....
.....
.....
}
}
So the issue is that sendMessage runs asynchronously and starts a new activity. Probably using startActivity() (lets call this Activity A). Hence, the code after sendMessage ("Do more stuff") gets run immediately. However, I need to wait for the newly created activity (Activity A) to return to carry on with the "Do more stuff".
As sendMessage is a method defined in an external library, I cannot change it in any way nor do I have access to its source code.
So, in short, my problem is that sendMessage creates a new thread (using startActivity() probably) and I need to know when this newly created activity ends. However, I have no way of monitoring it since it is defined in an external library. Anyone know how to solve this?
AsyncTask should be what you are looking for.
Let your message() starts an AsyncTask that calls messenger.sendMessage(msg) in doInBackground(). If you care about the result of the AsyncTask, get it in onPostExecute().
http://developer.android.com/reference/android/os/AsyncTask.html
One admittedly ugly way to get around this is to call
Thread.sleep(int milliseconds)
after sendMessage(), and before you continue with the rest of your code. Of course, this will only be helpful if you can fairly accurately estimate how long it will take to get the callback.
The better alternative is as Kaifei is saying. But you won't want the "do more stuff" where it is now. Instead, put it in a new method, and call that method in onPostExecute(). That way, the code will not continue until the AsyncTask has returned.
Edit: Saw your addition about needing the created activity to finish. If that's the case, you're going to somehow need to communicate with that activity (which I can't speak to without seeing all the code). But if you have that, then before "do more stuff", insert
while(!activity.isFinished()) {}
and in that activity, have it set a finished variable to true when it is done (however you define done). So the main thread will run this loop until the activity on the second thread is done, and then the first thread will continue.
Double Edit: Another idea. Let's say that the other activity the user has to complete is some form. In your main activity, after you call sendMessage(), have some popup where the user selects "finished" when they have completed the new activity. Have the program only continue when "finished" has been selected. A bit annoying for the user, but if it's only a single additional tap, that should work.
As you mentioned, sendMessage() runs asynchronously. If it's written properly, it must also have provided a callback interface, whose method will be called when messaging is finished. Move the code in that callback method.

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.

Combining Handler and AsyncTask in Android - Obvious Flaws?

I have a simple Android app which uses AsyncTasks for I/O. A frequent pattern:
User clicks a button
In response, an onClick handler instantiates and .execute()s an AsyncTask
Once the AsyncTask completes, the UI should be updated in some way
According to the documentation for AsyncTask, the correct way to accomplish the UI updates is to override onPostExecute in the AsyncTask class - this will be invoked back on the UI thread after execution and thus can touch the widgets, etc.
However, it seems wrong to me that onPostExecute should have any sort of hard reference to a UI element. I would prefer to keep my I/O tasks and UI code separate. Instead, this seems the obvious situation where I should pass an opaque callback to the AsyncTask - the callback retains a reference to the UI elements and thus we maintain isolation and reusability in the code. A classic delegate pattern (or perhaps listener, event, etc, many options here).
As an example, the code below seems wrong to me:
class QueryJobsDBTask extends AsyncTask<Void, Void, ArrayList<ContentValues>> {
#Override
protected void onPostExecute(ArrayList<ContentValues> freshJobsData) {
someList.clear();
someList.addAll(freshJobsData);
// BUG why does my DB query class hold UI references?
someAdapter.notifyDataSetChanged();
}
After some research, it looks like the Handler class is the most straightforward and lightweight way to accomplish a delegate pattern here. I can write reusable AsyncTasks for I/O and specify contextual UI update callbacks on a per-instance basis via Handler instances. So I have implemented this new Handler-enabled base class
public abstract class HandlerAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
private Handler preExecuteHandler, postExecuteHandler;
public void setPreExecuteHandler(Handler preExecuteHandler) {
this.preExecuteHandler = preExecuteHandler;
}
public void setPostExecuteHandler(Handler postExecuteHandler) {
this.postExecuteHandler = postExecuteHandler;
}
#Override
protected void onPreExecute() {
if (preExecuteHandler != null) {
preExecuteHandler.sendMessage(Message.obtain());
}
}
#Override
protected void onPostExecute(Result result) {
if (postExecuteHandler != null) {
Message msg = Message.obtain();
msg.obj = result;
postExecuteHandler.sendMessage(msg);
}
}
}
And voila, all of my I/O tasks are now properly partitioned from the UI - and I can still specify simple UI update callbacks when needed via Handler instances. This seems straightforward, flexible, and superior to me ... so of course I wonder what I'm missing.
How is the current framework solution superior? Is there some major pitfall to this approach? To my knowledge the topology of code execution and threads is the exact same at runtime, just code coupling is looser (and a few extra frames on the stack).
This is an elegant solution for segregating UI/Background tasks in small projects, although passing Runnables is even more elegant. Keep in mind that the AsyncTask is a wrapper around Thread/Handler, so you're doubling up on the thread-messaging that's already going on behind the scenes. The flaw here is that if you design the AsyncTasks to be reusable, you'll need to make sure that the IO you're running are all thread-safe, as there's no communication between the various AsyncTasks as to who is active or accessing which resources. An IntentService might be more appropriate if you need to queue background tasks rather than just fire them.
It's not so much a matter of superiority as purpose & use-case. AsyncTasks are usually written as private classes (or declared anonymously inline) within Activities, and as such inherit the Activity's references to various UI elements that need updating anyway.
If an AsyncTask is of sufficient size and/or complexity that it should be pulled out into its own class, and can be re-used by other classes, than using Handlers for better decoupling is a great idea. It's just that it's often not necessary, as the AsyncTask is accomplishing something specific to the Activity in which it was defined, and for simple ones, the corresponding handler code could even be larger than the entire AsyncTask itself.

Swing Worker Thread : Inner class vs passing parameter

I know SO is for specific questions but I need an advise on what is the correct practice in Java for working with swing worker thread.
My application generates large HTML text in response to a calculation process which is is displayed in a jTextPane. To avoid blocking the GUI I used to do the calculation in a Swing Worker Thread.
My problem is the following to start the calculation I need plenty information available in different menus checkboxes and listbox of the GUI, and at the end of the calculation I need to start functions within the EDT.
Here are 2 possibilities for me :
First one is to send plenty of information to my Swing Worker and also need to pass the MainFrame to access specific functions in the "done()"
public class MyWorker extends SwingWorker<Void, Void> {
private MyMainFrame frame;
public MyWorker(plenty of params) {
}
#Override
public Void doInBackground() {
//my background process
}
#Override
public void done() {
frame.myfunc1;
frame.myfunc2;
frame.myfunc3;
}
}
Second one would be to use a Inner Class
Which one is correct to do in Java. If both are "correct" what are the pros and cons of one against the other.
Both approaches are OK. The advantage of an inner class is that it has access to the internals of the enclosing object. The disadvantage is that it's not reusable in another context (another frame which would have a similar interface, for example).
Just make sure your code is well structured and readable. For example, you might want to extract the three method calls in your done() method in a single method of the frame.
If it is the large amount of parameters you have to pass in the constructor that is bothering you, you can group those parameters in a container object and just pass the container (e.g. a MyWorkerContext class).
I personally would try to avoid passing the UI (elements) itself, but rather pass a model/stream/... which will be updated by the SwingWorker, allowing me to refactor the UI later on without having to fiddle with my SwingWorker class.

Categories

Resources