我想实现这个功能: 当用户单击按钮时启动任务,并在 5 分钟后将一个文件发送到 Dropbox,但如果用户再次单击该按钮,则先前的任务将中止并开始新任务(5 分钟)。
我编写了将文件上传到 Dropbox 的代码,但从未编写过使用时间如此长(5 分钟)的任务的代码。 怎么才能做到这一点?
--编辑--
感谢@xdevs23,我已经实现了最终的代码
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();
}
}
}
};
* 编辑。 V2 *
为了在状态栏上实现倒计时,我已经实现了:
修改onSend函数:
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 */);
.... ....
在文件 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>
修改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();
}
}
};
最佳答案
您可以使用Thread
和Runnable
来代替使用AsyncTask
。
创建一个Runnable
,您要在后台运行的代码所在的位置:
Runnable myRunnable = new Runnable() {
@Override
public void run() {
// your code
}
}
创建您的线程
:
private Thread myThread;
确保您在主线程上创建了一个处理程序。
为了获得最佳结果,请将其添加到您的 onCreate()
方法中:
private Handler mHandler;
@Override
public void onCreate() {
// ...
mHandler = new Handler();
// ...
}
您需要导入android.os.Handler
。
声明上传代码所在的可运行程序:
private Runnable postRunnable = new Runnable() {
@Override
public void run() {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
现在,当用户单击按钮时执行以下操作:
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 */);
就是这样。
说明:
当用户点击按钮时,它将等待(不阻塞 UI)5 秒,然后它将运行 postRunnable
内的代码,从而在后台启动一个新线程,它将运行 myRunnable
中的代码。
编辑更新通知
private Handler mHandler;
private int minutes = 5;
private Runnable updateRunnable = new Runnable() {
@Override
public void run() {
if(minutes > 0) {
String notifContent = "" + minutes + " remaining.";
// Create your notification (there are several guides which show you how to do this), use notifContent as title or text or whatsoever
minutes--;
mHandler.postDelayed(updateRunnable, 60 * 1000);
} else {
// Remove your notification
}
}
};
开始倒计时:
mHandler.post(updateRunnable);
关于android - 长延迟AsyncTask并重新启动任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38411095/