5

ボタンをクリックすると、UI スレッドから asynctask を呼び出しています。これは、いくつかの HTTP-Get 要求を実行します。

現在のタスクが完了する前にユーザーがもう一度ボタンをクリックするとどうなるでしょうか? これは asynctask によって内部的に処理されますか、それとも自分で処理する必要がありますか?

4

5 に答える 5

6

これを行うには 2 つの方法があります。

1: 進行状況ダイアログを表示し、ユーザーがそれ以上入力できないようにブロックします。

2: クラス スコープ private に AsyncTask 変数を作成します。次に、これが複数回実行されることはありません。

于 2012-11-27T08:59:01.640 に答える
4

ブール値フラグを使用してその状態を確認してみませんか? 私はこのロジックを終わりのないリストで使用していますが、失敗したことは一度もありません。

でフラグを切り替えます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
        }
    }
});
于 2012-11-27T09:11:34.150 に答える
2

既に実行されているかどうかを確認し、その場合はボタンのクリックを無視するようにgetStatus()呼び出すことができます。AsyncTask

そのためには、間違いなくAsyncTaskどこかのインスタンスを保存し、それにアクセスできる必要があります。

于 2012-11-27T08:56:53.403 に答える
1

別の 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;
   ...
于 2012-11-27T09:03:48.780 に答える
1

ふたつのやり方:

  1. AsyncTaskonPreExeccute()で、ProgressDialog をその とともに表示しますsetCancelable(false)onPostExecute()ProgressDialogの AsyncTask 呼び出しのインdismiss()。これにより、ブロックの進行状況ダイアログが表示されます。ここでメッセージや進行状況を表示することもできます。

  2. onPreExeccute()AsyncTask の中で、Button を呼び出しますsetEnabled(false)onPostExecute()ボタンの AsyncTask 呼び出しのインsetEnabled(true)。これにより、タスクが実行されている限り、ボタンが無効になります。これらのポイントでボタンのテキストを変更することもできます。または、一時的にプログレス スピナーに置き換えることもできます (ActionBar のように)。

また、最新の Web ブラウザーの更新ボタンのように、ボタンの動作を「実行」と「キャンセル」の間で切り替えることができます。これにより、ユーザーはより詳細に制御できます。

注意事項: AsyncTask が常に正常に終了し、常に呼び出されるように、すべてonDoInBackground()を aでラップします。HTTP リクエストが何かを取得したかどうかは、result パラメータから判断できます。try-catchonPostExecute()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();
}
于 2012-11-27T09:06:34.503 に答える