So my problem is as follows, I have an AsyncTask Class that is called from a preference file ie. The intent is called from within an xml file. This AsyncTask Class is continuously running as I am doing a real time FFT of the sound within a room and will only be cancelled if I hit the return button. I cant check for keys being pressed as this Class extends AsyncTask and therefore I cant end the thread properly so that it reaches its onCancelled() state. The only other way I can think about ending this is to make a standby class which is called from the xml file which in turn calls this class and calls the .cancel(true) on the class object.. Any other ideas around this?
Can you post some code?
In your calling method (in which you might be able to check for keys), you can call myASyncTask.cancel() and then in the doInBackground() method of your AsyncTask, you can check for isCancelled() and then break your loop and return to your overridden onCancelled() method of your AsyncTask.
http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)
Does that help?
Related
I have an activity which gets called every time a Call is ended. This activity has below AsyncTask.
UploadRecordings uploadRecordings = new UploadRecordings();
uploadRecordings.execute(context);
Now when I get many Calls one after another, everytime new AysncTask is created. But Android limits the number of AsyncTask to 5. So problem is I want to check if a AsyncTask is already running, and if found running, don't create a new AsyncTask. I want to create a new AsyncTask if there is no AsyncTask running.
Any Help be Appreciated.
Use getStatus() to get the status of your AsyncTask. If status is AsyncTask.Status.RUNNING then your task is running.
check this way
if(uploadRecordings.getStatus() == AsyncTask.Status.RUNNING){
// My AsyncTask is currently doing work in doInBackground()
}
For More Detail Read : Android, AsyncTask, check status?
You can use getStatus ()
Returns the current status of this task.
if(YourAsyncTaskOBJ.getStatus() == AsyncTask.Status.RUNNING)
{
// AsyncTask Running
}
Read How to check if Async Task is already running
Override onPostExecute() method of AsyncTask, which is executed whenever a call is completed. Set some flags in onPostExecute() and proceed accordingly.
Dealing with AsyncTask
Put the AsyncTask in a Fragment.
Using fragments probably is the cleanest way to handle configuration changes. By default, Android destroys and recreates the fragments just like activities, however, fragments have the ability to retain their instances, simply by calling: setRetainInstance(true), in one of its callback methods, for example in the onCreate().
please find full implementation and description to deal with AsyncTask.
Handle Android AsyncTask
If you want to create a single AsyncTask when nothing is already running, you can do something like:
if(uploadRecordings == null || uploadRecordings.getStatus() != AsyncTask.Status.RUNNING){
uploadRecordings = new UploadRecordings();
uploadRecordings.execute(context);
}
This assumes that your uploadRecordings is a member variable. e.g.
private UploadRecordings uploadRecordings = null;
I am still confused about callback methods (new to OOP). One definition I found was: "A callback method in java is a method that gets called when an event occurs". What exactly decides when the method will be called? For example, in android, the activity class has an onCreate() callback method that executes whenever an Activity is created, but what code controls this?
Is the doInBackground method of the AsyncTask class also a callback method that executes whenever a foo.execute() is called, where foo is an AsyncTask object?
I see it quite simple like this: lets say you give me your phone number and I'll call you at sunrise. You don't have to worry about how I get up and call your "call-back number", as long as you trust me.
Its the same with a callback method. If the API documents you can supply a method and it will be called when a certain event happens, you don't have to worry about how that's done. Thats the responsibility of the creator of the API.
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.
In my app I have a service that plays audio, that service just has a single static MediaPlayer object. In onStart() from my main activity where I call MediaPlayer.isPlaying(); to determine which UI elements to show, I get an ANR message and a NullPointerException at the line where I call MediaPlayer.isPlaying();
I also call MediaPLayer.isPlaying(); when certain buttons are pressed, and that causes ANR as well, I discovered that after i took away the MediaPlayer.isPlaying(); call in onStart();, since I couldn't get past that without an ANR...
I found this similar question: MediaPlayer isPlaying() always returning false
Where someone says: "Also, while we're on the general MediaPlayer subject, note that isPlaying() can cause an ANR when called on the UI thread. In fact, Google recommends executing all MediaPlayer calls from a background handler thread. Which will also serialize execution of MediaPlayer calls."
I couldn't find anything in documentation about this. So how do I or what is the best way to create a short lived thread in these scenarios so I am able to check the status of my MediaPlayer? Or is there another way?
I download a RSS Feed and then parse it in a class, the rssfeed is saved as a custom object; however the code blocks as the feed is relatively big and the Android typically works only on EDGE.
I want to put the downloading of the file into an AsyncTask with an indefinite progress dialog.
I also want to be able to access the rssfeed object after its downloaded in the ASynctask from within the Main Thread. How do I reference it?
When you build an AsyncTask, the third generic argument is the Result, and when you execute the asyn task, you can call get to retrieve the Result object. Depending on what you need to do with the object on the main thread, you can also override the AsyncTask's onPostExecute method which will be run on the main thread after doInBackground completes. This is probably the best bet, to override onPostExecute on the AsyncTask.