Andy Band Andy Band - 4 months ago 33
Android Question

long delay AsyncTask and restart task

I would like to implement this function:
When the user click on button start the task and after 5 minute send one file to dropbox, but if the user click another time on the button, the precedent task abort and new task (5 min) start.

I wrote code to upload files to Dropbox, but never written code using task with such a long time (5 minute).
How can do that?

-- EDIT --

thanks @xdevs23, I have implemented the final code

public void onSendOrder() {

try {
mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
// Just if the above fails (might be first time)
ex.printStackTrace();
}
int minutes = 5;
mHandler.postDelayed(postRunnable, minutes * 20 * 1000 /* 5 minutes in milliseconds */);
...
...
...

private Runnable postRunnable = new Runnable() {
@Override
public void run() {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
};


private Runnable myRunnable = new Runnable() {
@Override
public void run() {
// your code
int cloud = GetPreferenceCloud();
if(cloud > 0){
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
final File bckDatabase = BackupDatabase();

if (networkInfo != null && networkInfo.isConnected() && bckDatabase != null) {

runOnUiThread(new Runnable() {
public void run() {
// call your asynctask here
new UploadOnCloud(MainActivity.this,
PreferenceConstants.DB_DATABASE_STORE_CLOUD,
PreferenceConstants.FILE_DIR_CLOUD,
bckDatabase,
mUListener,
cloud).execute();
}
});

} else {
Toast.makeText(getContext(),getContext().getResources().getString(R.string.send_msg13), Toast.LENGTH_SHORT).show();
}
}
}
};


* EDIT. V2 *

For implement the Countdown on statusbar I've implemented this:

Modify the onSend function:

public void onSendOrder() {

try {
mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
// Just if the above fails (might be first time)
ex.printStackTrace();
}
minute = 3600;
//mHandler.postDelayed(postRunnable, minutes * 20 * 1000 /* 5 minutes in milliseconds */);
mHandler.postDelayed(postRunnable, 1000 /* 1 seconds */);


....
....

in the file menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<item android:id="@+id/break_timer"
android:title="00:00"
app:showAsAction="always"
app:actionViewClass="android.widget.TextView" />
<item
android:id="@+id/action_refresh"
android:title="@string/action_refresh"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_action_autorenew"/>
</menu>


modify the onCreateOptionsMenu

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main, menu);
MenuItem timerItem = menu.findItem(R.id.break_timer);
timerText = (TextView) MenuItemCompat.getActionView(timerItem);
timerText.setPadding(10, 0, 10, 0); //Or something like that...

return super.onCreateOptionsMenu(menu);
}


private int minute;
private Runnable postRunnable = new Runnable() {
@Override
public void run() {
if(minute >= 0){
minute--;
mHandler.postDelayed(postRunnable, 1000 /* 1 seconds */);
timerText.setText(secondsToString(minute));
}else {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
};

Answer

Instead of using an AsyncTask, you could use Threads and Runnables.

Create a Runnable where your code, which you want to run in the background, is located:

Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        // your code
    }
}

Create your Thread:

private Thread myThread;

Make sure that you have a handler created on the main thread. For best results, add it to your onCreate() method:

private Handler mHandler;

@Override
public void onCreate() {
    // ...
    mHandler = new Handler();
    // ...
}

You need to import android.os.Handler.

Declare the runnable where your upload code is:

private Runnable postRunnable = new Runnable() {
    @Override
    public void run() {
        Thread myThread = new Thread(myRunnable);
        myThread.start();
    }
}

Now do following when the user clicks on the button:

try {
    mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
    // Just if the above fails (might be first time)
}
int minutes = 5;
mHandler.postDelayed(postRunnable, minutes * 60 * 1000 /* 5 minutes in milliseconds */);

And that's it.

Explanation:

When the user clicks on the button, it will wait (without blocking the UI) for 5 seconds, and then it will run the code inside postRunnable, which starts a new thread in the background, which will run the code inside your myRunnable.

Comments