如何在不导致 UI 冻结的情况下延迟执行某项任务
How to delay performing a certain task without causing UI to freeze
所以我有一个 Asynctask class 在单击按钮 5 秒后执行下一个操作。
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
delay = new delayMessageAsyncTask();
delay.setProgressBar(delaySendProgressWheel);
delaySendProgressWheel.setProgress(0);
delaySendProgressWheel.setSpinSpeed(0.21f);
mButton.setVisibility(ImageView.GONE);
delaySendProgressWheel.setVisibility(ProgressWheel.VISIBLE);
delay.execute();
//performAction();
}
});
class delayMessageAsyncTask extends AsyncTask<Void, Integer, Void> {
int myProgress;
@Override
protected void onPreExecute() {
myProgress = 0;
super.onPreExecute();
}
@Override
protected void onPostExecute(Void result) {
edit_text.setText("");
mButton.setVisibility(ImageView.VISIBLE);
delaySendProgressWheel.setVisibility(ProgressWheel.GONE);
msgAdapter.setArrayList(message);
msgAdapter.notifyDataSetChanged();
listView.smoothScrollToPosition(msgAdapter.getCount()-1);
super.onPostExecute(result);
}
@Override
protected Void doInBackground(Void... params) {
while(myProgress<100){
myProgress+=20;
publishProgress(myProgress);
try {
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
performAction();
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
delaySendProgressWheel.setProgress((float)values[0]);
}
问题是,performAction()
非常复杂,因为它包含后台线程和 UI 线程,所以我必须在 doInBackground
中放一部分并更新 UI onPostExecute
。但正如我所说,只有在恰好 5 秒后才能执行操作,因此它会在到达 onPostExecute
之前停止一段时间。我曾尝试将 performAction()
移动到 onPostExecute
,但它会导致 UI 冻结。理想情况下,我想知道是否有任何方法可以在 onClick()
中的 execute()
方法之后停止执行代码,以便我可以将 performAction()
放在那里。
您可以在按下点击后使用处理程序添加延迟:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// exec code here
}
}, 5000);
你可以使用这个:
Handler mHandler;
public void postHandler() {
mHandler = new Handler();
mHandler.postDelayed(mRunnable, 5000);
}
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
/** Do something **/
new AsyncTask<Void,Void,Void>(){
@Override
protected Void doInBackground(Void... params) {
performAction();
return null;
}
}.execute();
}
};
所以我有一个 Asynctask class 在单击按钮 5 秒后执行下一个操作。
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
delay = new delayMessageAsyncTask();
delay.setProgressBar(delaySendProgressWheel);
delaySendProgressWheel.setProgress(0);
delaySendProgressWheel.setSpinSpeed(0.21f);
mButton.setVisibility(ImageView.GONE);
delaySendProgressWheel.setVisibility(ProgressWheel.VISIBLE);
delay.execute();
//performAction();
}
});
class delayMessageAsyncTask extends AsyncTask<Void, Integer, Void> {
int myProgress;
@Override
protected void onPreExecute() {
myProgress = 0;
super.onPreExecute();
}
@Override
protected void onPostExecute(Void result) {
edit_text.setText("");
mButton.setVisibility(ImageView.VISIBLE);
delaySendProgressWheel.setVisibility(ProgressWheel.GONE);
msgAdapter.setArrayList(message);
msgAdapter.notifyDataSetChanged();
listView.smoothScrollToPosition(msgAdapter.getCount()-1);
super.onPostExecute(result);
}
@Override
protected Void doInBackground(Void... params) {
while(myProgress<100){
myProgress+=20;
publishProgress(myProgress);
try {
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
performAction();
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
delaySendProgressWheel.setProgress((float)values[0]);
}
问题是,performAction()
非常复杂,因为它包含后台线程和 UI 线程,所以我必须在 doInBackground
中放一部分并更新 UI onPostExecute
。但正如我所说,只有在恰好 5 秒后才能执行操作,因此它会在到达 onPostExecute
之前停止一段时间。我曾尝试将 performAction()
移动到 onPostExecute
,但它会导致 UI 冻结。理想情况下,我想知道是否有任何方法可以在 onClick()
中的 execute()
方法之后停止执行代码,以便我可以将 performAction()
放在那里。
您可以在按下点击后使用处理程序添加延迟:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// exec code here
}
}, 5000);
你可以使用这个:
Handler mHandler;
public void postHandler() {
mHandler = new Handler();
mHandler.postDelayed(mRunnable, 5000);
}
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
/** Do something **/
new AsyncTask<Void,Void,Void>(){
@Override
protected Void doInBackground(Void... params) {
performAction();
return null;
}
}.execute();
}
};