ボタンをクリックすると、UI スレッドから asynctask を呼び出しています。これは、いくつかの HTTP-Get 要求を実行します。
現在のタスクが完了する前にユーザーがもう一度ボタンをクリックするとどうなるでしょうか? これは asynctask によって内部的に処理されますか、それとも自分で処理する必要がありますか?
ボタンをクリックすると、UI スレッドから asynctask を呼び出しています。これは、いくつかの HTTP-Get 要求を実行します。
現在のタスクが完了する前にユーザーがもう一度ボタンをクリックするとどうなるでしょうか? これは asynctask によって内部的に処理されますか、それとも自分で処理する必要がありますか?
これを行うには 2 つの方法があります。
1: 進行状況ダイアログを表示し、ユーザーがそれ以上入力できないようにブロックします。
2: クラス スコープ private に AsyncTask 変数を作成します。次に、これが複数回実行されることはありません。
ブール値フラグを使用してその状態を確認してみませんか? 私はこのロジックを終わりのないリストで使用していますが、失敗したことは一度もありません。
でフラグを切り替えますdoInBackground()
@Override
protected Void doInBackground(Void... params) {
loadingData = true;
}
そして、再びonPostExecute()
@Override
protected void onPostExecute(Void result) {
// CHANGE THE LOADINGMORE STATUS TO PERMIT FETCHING MORE DATA
loadingData = false;
}
ボタンのクリックリスナーの場合
your_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (loadingData == false) {
// RUN THE ASYNCTASK AGAIN
} else if (loadingData == true) {
// SHOW A TOAST THAT YOU ARE ALREADY FETCHING DATA
}
}
});
既に実行されているかどうかを確認し、その場合はボタンのクリックを無視するようにgetStatus()
呼び出すことができます。AsyncTask
そのためには、間違いなくAsyncTask
どこかのインスタンスを保存し、それにアクセスできる必要があります。
別の AsyncTask が生成され、おそらく問題が発生する可能性があります-データを保持している場合に保存されるデータとの競合状態などonClick
。バックグラウンド。
アクションバーに配置された更新ボタンで同様のことを実現しました。非同期タスクは の下で実行されるapp.Service
ため、構成の変更中 (hasStartedSync
再初期化される場所) は「isTheSyncServiceRunning」チェックに依存していることに注意してください。
// on setting the selection buttons up
public void onPrepareOptionsMenu(final Menu menu) {
super.onPrepareOptionsMenu(menu);
final MenuItem refreshItem = menu.findItem(id.sync);
if (isSynchronisationServiceRunning() || hasStartedSync) {
refreshItem.setEnabled(false);
if (Build.VERSION.SDK_INT > 10) {
// Replace the refresh icon with an indeterminate spinner for > 10 API.
final LayoutInflater inflater = (LayoutInflater)getSherlockActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
refreshItem.setActionView(inflater.inflate(layout.actionbar_indeterminate_progress, null));
}
} else {
refreshItem.setEnabled(true);
refreshItem.setActionView(null);
}
}
// on selection.
public boolean onOptionsItemSelected(final MenuItem item) {
boolean isSelected;
switch (item.getItemId()) {
case id.sync:
// Fire request to start GET here.
hasStartedSync = true;
invalidateOptionsMenu();
break;
...
ふたつのやり方:
AsyncTaskonPreExeccute()
で、ProgressDialog をその とともに表示しますsetCancelable(false)
。onPostExecute()
ProgressDialogの AsyncTask 呼び出しのインdismiss()
。これにより、ブロックの進行状況ダイアログが表示されます。ここでメッセージや進行状況を表示することもできます。
onPreExeccute()
AsyncTask の中で、Button を呼び出しますsetEnabled(false)
。onPostExecute()
ボタンの AsyncTask 呼び出しのインsetEnabled(true)
。これにより、タスクが実行されている限り、ボタンが無効になります。これらのポイントでボタンのテキストを変更することもできます。または、一時的にプログレス スピナーに置き換えることもできます (ActionBar のように)。
また、最新の Web ブラウザーの更新ボタンのように、ボタンの動作を「実行」と「キャンセル」の間で切り替えることができます。これにより、ユーザーはより詳細に制御できます。
注意事項: AsyncTask が常に正常に終了し、常に呼び出されるように、すべてonDoInBackground()
を aでラップします。HTTP リクエストが何かを取得したかどうかは、result パラメータから判断できます。try-catch
onPostExecute()
onPostExecute(result)
例:このメソッドを呼び出して、いくつかのテキストをTextView
クリックして from サーバーにロードしますButton
。
public static void runHTTP(final TextView targetView, final Button triggerBtn){
//---new task----
AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>(){
@Override
protected void onPreExecute() {
super.onPreExecute();
//----disable button---
triggerBtn.setEnabled(false);
//---show message----
targetView.setText("Loading...");
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//----update result---
targetView.setText(result);
//----re-enable button---
triggerBtn.setEnabled(true);
}
@Override
protected String doInBackground(Void... voids) {
//---default value--
String result = "No Data";
//--for safety--
try{
//-----do time consuming stuff here ---
}catch (Exception e){
//---error value--
result = "Error fetching data";
}
return result;
}
};
//----run task----
task.execute();
}