I am currently working on an android application that has to handle a network connection using several AsyncTasks.
This is the first task that is establishing the connection and calling a new task which is handling the microphone input.
private class establishConnectionTask extends
AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
try {
// initialize connection
initConnection();
MicrophoneTask micTask = new MicrophoneTask();
micTask.execute("");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
mReadInputTask = new readInputTask();
mReadInputTask.execute("");
super.onPostExecute(result);
}
Everything works fine, the connection is working and I can transfer data. Also the MicrophoneTask is doing it's job.
Here comes the problem:
In the onPostExecute method I am creating a new AsyncTask which should handle all the network input.
This is how the readInputTask looks like:
private class readInputTask extends AsyncTask<String, Integer, String>
{
#Override
protected void onPreExecute()
{
Log.d("DEBUG", "pre");
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
// blocking readInput method
Log.d("DEBUG", "doInBackground");
}
#Override
protected void onPostExecute(String result) {
Log.d("DEBUG", "post");
super.onPostExecute(result);
}
}
The readInputTask somehow gets stuck in the onPreExecute method of the readInputTask. The only output I get is "pre", eventhough I also expect "doInBackground" and "post".
Does anyone see an error or knows a solution for this?
Any help is appreciated!
mReadInputTask.execute("");
When you use AsyncTask#execute(params), the AsyncTasks are executed serially: one after the other. To execute AsyncTasks in parallel, use AsyncTask#executeOnExecutor(...).
From the docs on executeOnExecutor (Executor exec, Params... params):
This method is typically used with THREAD_POOL_EXECUTOR to allow
multiple tasks to run in parallel on a pool of threads managed by
AsyncTask, however you can also use your own Executor for custom
behavior.
Related
I have an AsyncTask where I invoke a method that download some data from internet and performs certain operations.
In the emulator this works always despite the connection speed but on real devices if connection or device isn't fast this task is automatically terminated. I don't know why, but probably there is some kind of default timeout in Android default task management.
How could I fix this problem?
How to force the completion of the task always?
Here my code
myTask = new AsyncTask<Void, Void, Void>() {
ProgressDialog pd;
boolean correctlyInitialized = true;
#Override
protected void onPreExecute() {
pd= new ProgressDialog(CatcherTree.this);
pd.setCancelable(false);
try {
pd.show();
} catch (Error e) {
e.printStackTrace();
}
}
#Override
protected Void doInBackground(Void... params) {
long t = System.currentTimeMillis();
//this method requires time to complete
updateAllDataSet(CatcherTree.this);
return null;
}
#Override
protected void onPostExecute(Void rate) {
pd.dismiss();
}
}.execute();
AsyncTasks rely on a worker thread to do the background job, and threads do not just disappear. So my guess is that the worker thread is throwing an exception and terminating.
Look through your logcat for the exception, or better yet - handle exceptions correctly in updateAllDataSet().
I have two asyc task both perform separate network operation.I want one async task to wait for other task to finish for a single variable..I thought of doing it like perform other asyc operation onPostexecute of first one but for a single variable i have to make other task to wait first one to finish...is there any to achieve efficently
Referring to this, you can not use .execute() so;
First you have to start your tasks like this:
// Start first task
new Task1().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
// Start second task
new Task2().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
and then you can make a static variable so the both of tasks can access to it:
public static boolean task1Finished = false;
Then simple example of the tasks:
First task
private class Task1 extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
Log.d("myApp", "Task1 started");
for(int x = 0; x < 10; ++x)
{
try
{
Thread.sleep(1000);
//Log.d("myApp", "sleeped 1000 ms");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
return "";
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(String result) {
// Lets the second task to know that first has finished
task1Finished = true;
}
}
Second task
private class Task2 extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
Log.d("myApp", "Task2 started");
while( task1Finished == false )
{
try
{
Log.d("myApp", "Waiting for Task1");
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
Log.d("myApp", "Task1 finished");
// Do what ever you like
// ...
return "";
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(String result) {
Log.d("myApp", "All done here (Task2)");
}
}
Maybe asynctask is not the best tool? There are some interesting classes in the android api that can help doing specifically the synchronizing job :
Quote from android developper : "Four classes aid common special-purpose synchronization idioms.
Semaphore is a classic concurrency tool.
CountDownLatch is a very simple yet very common utility for blocking until a given number of signals, events, or conditions hold.
A CyclicBarrier is a resettable multiway synchronization point useful in some styles of parallel programming.
An Exchanger allows two threads to exchange objects at a rendezvous point, and is useful in several pipeline designs."
So I suggest looking into :
Cyclic Barrier
http://developer.android.com/reference/java/util/concurrent/CyclicBarrier.html
Exchanger
http://developer.android.com/reference/java/util/concurrent/Exchanger.html
You need to create another async in OnpostExecute of first one if you need to call the other synchronously.
The goal:
Using Google App Engine server and Android client, I'm trying to put on the Google map at the Android client Users overlays. Every 30 seconds I'm polling the server and getting Vector that contains users and adding it to the map.
Current status:
I'm dong all that using in one new thread, So after running the app I got:
weird behaviors(delayed overlays, multiple overlays) and after that crushed with ConcurrentModificationException.
After reading a bit i figured out that I need to work with AsyncTask.
Correct me if I'm wrong,But I understand that everything done in the Activity at at onCreate is "running" in UIhread so I need to put the "Logic" (All the Network handling) in doInBackground and all the UI Handling like putting overlays on the map in onPostExecute.
My Question are:
1) In the current status I'm doing:
new Thread()
{
#Override
public void run()
{
super.run();
while(true)
{
SystemClock.sleep(30000);
Vector responseFromServer = getUsersVectorFromServer();
putNewOnlineUserOnTheMap();
}
}
}.start();
What is the right way to convert this To AsyncTask?
Do I poll the server still using new thread in the doInBackground or there is right way to do this?
2) Is there a specific list of what counts as UI to put in onPostExecute or any concepts list?
In my case I guess that in need to put putNewOnlineUserOnTheMap() in onPostExecute.
Thanks.
Something similar to the following:
class UpdateTask extends AsyncTask<Void, Vector, Void>{
#Override
protected Void doInBackground(Void... params) {
// this is running in a background thread.
while (!isCancelled()) {
SystemClock.sleep(30000);
Vector responseFromServer = getUsersVectorFromServer();
// send the result back to the UI thread
// onProgressUpdate will be called then
publishProgress(responseFromServer);
}
return null;
}
#Override
protected void onProgressUpdate(Vector... values) {
// this is executed on the UI thread where we can safely touch UI stuff
putNewOnlineUserOnTheMap(values[0]);
}
}
You can't use the result of the task since the task is finished then. But you can use the progress publishing mechanism to get periodic results. If you use it like that and do the modification on the UI thread you should not get ConcurrentModificationException because you do the modifications on the one thread that can safely modify the UI.
One thing to note here: create new instances of your Vector in the background thread and then use it to update the UI. But don't touch the same object afterwards in the backgroundthread. That way you don't need any synchronization since after the background thread sends it away it is only the UI thread that touches it. (and you could use a simple ArrayList instead of a Vector)
AsyncTask uses generics and varargs.The parameters that are passed to the asyntask are . TypeOfVariableArgumentsParameters is passed into the doInBackground(), ProgressParam is used for progress information and ResultParam must be returned from doInBackground() and is passed to onPostExecute() as parameter.
example:--
protected class ParsingTask extends AsyncTask> {
private ProgressDialog loadingDialog = new ProgressDialog(JsonParserActivity.this);
protected void onPreExecute() {
loadingDialog.setMessage("loading app store..");
loadingDialog.show();
}
#Override
protected ArrayList<Items> doInBackground( Context... params ) {
// do ur process here.
return result;
}
if (!this.isCancelled()) {
}
return result;
}
#Override
protected void onProgressUpdate(String... s) {
super.onProgressUpdate(s);
Toast.makeText(getApplicationContext(), s[0], Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute( ArrayList<Items> response ) {
//if u r dealing with list view and adapters set the adapter here at the onPostExecute()
loadingDialog.dismiss();
}
#Override
protected void onCancelled() {
super.onCancelled();
Toast.makeText(getApplicationContext(), "The operation was cancelled", 1).show();
}
}
You can use AsyncTask like below. Hope this will help you..
Class YourClass{
void YourClass(){
NetworkTask nT = new NetworkTasK();
nT.execute();
}
}
protected class NetworkTask extends AsyncTask<Void, String, Boolean>
{
#Override
protected Boolean doInBackground(Void... params)
{
try
{
String response;
while(keepreceiving)
{
response = in.readLine();//Prog Counter stops here until getting i/p.
if(response != null)
yourFunctionForResponse(response);
}
}
catch (Exception ex)
{
}
return null;
}
private void yourFunctionForResponse(String response){
//things to do....
}
}
You may also try runOnUiThread(Runnable action) along with this to implement your work.
I have an Android application that includes a Socket in an Asynctask and it works, but I do not know if this is the right way to implement it.
Another thing, my onProgressUpdate updates my list adapter and causes lag when I play animation with it.
Someone have a good solution for that?
Are you sure you are not during any computation on the UI thread?
Check out this page, there are some guidelines on how to use the various thread mechanisms in Android.
If this does not solve your problem, try posting the part of your code that handles the population of the list.
I did it like this ... (just for the Socket connection)
private class EstablishConnectionTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
boolean ok = false;
dataSend = false;
//establish the Connection to the server and returns if it succeed or not
ok = client.createClient(server, port);
//try to send the data and return if it succeed or not
if(ok) dataSend = client.sendData(profilename);
if(dataSend) {
//close the connection
client.closeConnection();
}
return null;
}
protected void onPreExecute() {
//bring a process Dialog to the front
showDialog(DIALOG_CONNECTING);
}
protected void onPostExecute(Void result) {
removeDialog(DIALOG_CONNECTING);
if(dataSend) {
Toast.makeText(Activity_sendXML.this, "xml versendet", 2000).show();
}
else{
showDialog(DIALOG_CONNECTION_REFUSED);
}
}
}
I am using AsyncTask to perform some background calculations but I am unable to find a correct way to handle exceptions. Currently I am using the following code:
private class MyTask extends AsyncTask<String, Void, String>
{
private int e = 0;
#Override
protected String doInBackground(String... params)
{
try
{
URL url = new URL("http://www.example.com/");
}
catch (MalformedURLException e)
{
e = 1;
}
// Other code here...
return null;
}
#Override
protected void onPostExecute(String result)
{
if (e == 1)
Log.i("Some Tag", "An error occurred.");
// Perform post processing here...
}
}
I believe that the variable e maye be written/accessed by both the main and worker thread. As I know that onPostExecute() will only be run after doInBackround() has finished, can I omit any synchronization?
Is this bad code? Is there an agreed or correct way to handle exceptions in an AsyncTask?
I've been doing that in my apps, I guess there is not a better way.
You can also read Mark Murphy answer about it.
I think your code would to the job but there is already some kind of error handling built into the AsyncTask class.
You can avoid to use an extra variable by using the cancel() method and its handler method onCancelled(). When you call cancel within the doInBackground() method the onCancelled method in the UI thread. Whether you call cancel(true) or cancel(false) depends on your needs.
private class MyTask extends AsyncTask<String, Void, String>
{
#Override
protected NewsItem doInBackground(String... params)
{
try
{
URL url = new URL("http://www.example.com/");
}
catch (MalformedURLException e)
{
cancel(false/true);
}
// Other code here...
return null;
}
#Override
protected void onPostExecute(String result)
{
// Perform successful post processing here...
}
#Override
protected void onCancelled() {
super.onCancelled();
// Perform error post processing here...
}
}
This is guaranteed to work, even on SMP architecture. All the synchronization is done for you. It would however be better to use the return value to do this.