1

I have been trying to create time out while AsyncTask execution more than 1 minute. If the time up, then should exit with Notification.

This is my code:

private class GetLongLat extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        longlatDialog = new ProgressDialog(MainActivity.this);
        longlatDialog.setMessage("Fetching Data. Please wait..");
        longlatDialog.setCancelable(false);
        longlatDialog.show();

    }

    @Override
    protected Void doInBackground(Void... arg0) {

         GPSTracker gpsTracker;

         //This is the timer to set time out
         Timer timer = new Timer();
         timer.schedule(new TaskKiller(this), 3000);
         timer.cancel();

         do{
             gpsTracker = new GPSTracker(MainActivity.this);
             gpsTracker.getLocation();

         }while(!String.valueOf(gpsTracker.latitude).equals("0.0"));

        return null;
    }

    protected void onCancelled() {
     // do something, inform user etc.
        Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show();
        System.exit(1);
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        if (longlatDialog.isShowing())
            longlatDialog.dismiss();
    }

}

And this is a class called in doInBackground to set the time up.

class TaskKiller extends TimerTask {
 private AsyncTask<?, ?, ?> mTask;

  public TaskKiller(AsyncTask<?, ?, ?> task) {
    this.mTask = task;
  }

  public void run() {
     mTask.cancel(true);
  }
}

But when i run the code, nothing happen. I mean the progress dialog always run very long time.

EDIT I have edit my code to call GetLongLat something like this:

GetLongLat n = new GetLongLat();
n.execute();
try {

    n.get(3000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (ExecutionException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (TimeoutException e) {
    // TODO Auto-generated catch block
    Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show();
    System.exit(1);
} 

But also, doesn't work.

Samsul Arifin
  • 247
  • 1
  • 6
  • 24

5 Answers5

2

I think you can use AsyncTask.get()

GetLongLat n = new GetLongLat();
n.get(30000, TimeUnit.MILLISECONDS);

you will have to use the n.get in a separate Thread..

Edited: one more different method but not efficient.,

GetLongLat n = new GetLongLat();
n.execute(); 
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
   @Override
   public void run() {
       if ( n.getStatus() == AsyncTask.Status.RUNNING )
           n.cancel(true);
  }
 }, 30000 );
sharan
  • 226
  • 1
  • 4
  • 12
  • i have edit the code based on your answer. I don't know, but doesn't work. @saran – Samsul Arifin Mar 27 '16 at 09:46
  • @SamsulArifin what is the error/problem you are facing ..? – sharan Mar 27 '16 at 09:49
  • @SamsulArifin if you still face a problem, i have edited and updated a different way..see that, but it is not efficient – sharan Mar 27 '16 at 09:57
  • @SamsulArifin If you are planing to use any one of the method i mentioned, then you will first have to remove your already existing time out part of the code... – sharan Mar 27 '16 at 10:00
0

why are you canceling the timer? just after calling schedule()?

Cancels the Timer and all scheduled tasks

timer.cancel(); should be removed. check docs for cancel()

Yazan
  • 6,074
  • 1
  • 19
  • 33
0

You can achieve this behaviour in many ways.

Here's an example using CountDownTimer

// Start your AsyncTask
private YourAsyncTask mTask = new YourAsyncTask().execute();

// Run a timer after you started the AsyncTask
new CountDownTimer(60000, 1000) {

    public void onTick(long millisUntilFinished) {
        // Do nothing
    }

    public void onFinish() {
        mTask.cancel(true);
    }

}.start();

You are cancelling the timer just after initiating it. You can do it like this too. But this type of busy waiting is not recommended at all.

@Override
protected Void doInBackground(Void... arg0) {

     GPSTracker gpsTracker;

     //This is the timer to set time out
     new CountDownTimer(60000, 1000) {

         public void onTick(long millisUntilFinished) {
             // Do nothing
         }

         public void onFinish() {
             // Set latitude to zero to finish the while loop outside.
             // gpsTracker.latitude = "0.0"; // Something like this
         }

     }.start();

     do{
         gpsTracker = new GPSTracker(MainActivity.this);
         gpsTracker.getLocation();

     }while(!String.valueOf(gpsTracker.latitude).equals("0.0"));

    return null;
}
Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
0

Here's another approach. In your doInBackground method, you can use System.currentTimeMillis to check whether 1 minute has elapsed or not.

protected Void doInBackground(Void... arg0) {

         GPSTracker gpsTracker;

         long startTime = System.currentTimeMillis();

         do{
             gpsTracker = new GPSTracker(MainActivity.this);
             gpsTracker.getLocation();

         }while(!String.valueOf(gpsTracker.latitude).equals("0.0")
                && ((System.currentTimeMillis() - startTime) <= 60000);//60000 millisecond = 1 minute

        return null;
}

`

  • then, where i can put the code to exit an apps when time out? – Samsul Arifin Mar 27 '16 at 09:56
  • when timeout is reached, while loop will automatically exit and `null` will be returned from `doInBackground` methd, after that `onPostExecute` will be called and you can put your code there. – Huzaima Khan Mar 27 '16 at 10:04
  • I also trying your code. And i think more efficient and effective. But, i still confuse to check between time out and not in onPostExeute. Do you have idea? – Samsul Arifin Mar 27 '16 at 22:24
  • I didn't understand your question. Can you please elaborate what do you mean by `i still confuse to check between time out and not in onPostExeute.` @Samsul ? – Huzaima Khan Apr 02 '16 at 13:43
0

Just alter your code like this and check whether your async task is getting cancelled or not.

            GetLongLat getLongLatAsync = new GetLongLat();
            getLongLatAsync.execute();
            try {
            Handler handler = new Handler();
            /** 1st method **/
            handler.postDelayed(new Runnable()
             {
              @Override
              public void run() {
                 if (getLongLatAsync.getStatus() == AsyncTask.Status.RUNNING )
                  getLongLatAsync.cancel(true);
                }
              }, 3000 ); //3 Seconds
    /** 1st method ends **/
    /** second method */
            handler.post(new Runnable()
             {
              @Override
              public void run() {
        getLongLatAsync.get(3000, TimeUnit.MILLISECONDS);//You should run it in seperated thread or else it will block ui thread.
    }
    });
/** Second method ends**/
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (TimeoutException e) {
                // TODO Auto-generated catch block
                Toast.makeText(getApplicationContext(), "Failed getting long lat. Please check your internet connection", Toast.LENGTH_LONG).show();
            } 

and in the onCancelld method write your logic

@Override
protected void onCancelled() {
Log.d(TAG,"Asynctask has been cancelled.");
}
Madhukar Hebbar
  • 3,113
  • 5
  • 41
  • 69
  • i have been trying your code. all of it. Then, same result. The point what i have asked above is when user turn on the GPS, then load the long and lat automatically. But sometimes, user has slow internet connection, so if the user cannot load the long lat after 1 minutes. The apps will be exit. – Samsul Arifin Mar 29 '16 at 01:34
  • The mentioned method should work unless you are doing something different because it's working for us!!! – Madhukar Hebbar Mar 29 '16 at 06:36
  • Thanks for your answer. I have been found another way. this http://stackoverflow.com/questions/7882739/android-setting-a-timeout-for-an-asynctask Work perfectly. But your code also work on different method. Thanks again – Samsul Arifin Mar 29 '16 at 06:53
  • Nice. I think the same answer what i have written by adding little more flavour to that. ;) – Madhukar Hebbar Mar 29 '16 at 06:58
  • Yeah, may be 'Handler' not working on my code, should be replaced by 'Thread' – Samsul Arifin Mar 29 '16 at 07:01