title: How to disable Button while AsyncTask is running? (Android)
body: <p>I am trying to disable a button while a download task is being executed. I have tried using setEnabled, setVisibility and setClickable. I think I tried all combinations of these options. All of them disable the button click events while the task is performing, but the events are still being registered somehow, and when I reactive the button, the handler is called if I clicked the button while it was disabled... even if it was invisible or "gone"! (not sure if it is called a handler, I want to refer to the onClick method).</p>
  
  <p>I have also inserted a counter and a Log to verify what I've stated above. The code is shown below. This piece of code <code>if(counter&gt;1) return;</code> is meant to stop the crash, but I would like to remove it, since I want to re-enable the button, and not disable it forever.</p>
  
  <p><b>onClick:</b></p>
  
  <pre><code>public void downloadOnClick(View v) {
      counter++;
      Log.d(this.getLocalClassName(), "Button was clicked " + counter + " times.");
      if(counter&gt;1) return;
  
      ConnectivityManager connMgr = (ConnectivityManager)
              getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
      if (networkInfo != null &amp;&amp; networkInfo.isConnected()) {
          //mButton.setVisibility(View.GONE);
          mButton.setEnabled(false);
          //mButton.setClickable(false);
          mTextView.setText("Getting html file...");
          // if we use simple http, we will need to handle redirect status code
          new DownloadWebpageTask().execute("https://www.google.com/");
      } else {
          mTextView.setText("No network connection available.");
      }
  }
  </code></pre>
  
  <p><b>AsyncTask:</b></p>
  
  <pre><code>private class DownloadWebpageTask extends AsyncTask&lt;String, Void, String&gt; {
  
      private HttpURLConnection mConnection;
  
      @Override
      protected String doInBackground(String... urls) {
          try {
              URL url = new URL(urls[0]);
              mConnection = (HttpURLConnection) url.openConnection();
              mConnection.setReadTimeout(10000 /* milliseconds */);
              mConnection.setConnectTimeout(15000 /* milliseconds */);
              mConnection.setRequestMethod("GET");
              mConnection.setDoInput(true);
  
              mConnection.connect();
              int statusCode = mConnection.getResponseCode();
              if (statusCode != HttpURLConnection.HTTP_OK) {
                  return "Error: Failed getting update notes";
              }
  
              return readTextFromServer(mConnection);
  
          } catch (IOException e) {
              return "Error: " + e.getMessage();
          }
      }
  
      private String readTextFromServer(HttpURLConnection connection) throws IOException {
          InputStreamReader stream = null;
          try {
              stream = new InputStreamReader(connection.getInputStream());
              BufferedReader br = new BufferedReader(stream);
              StringBuilder sb = new StringBuilder();
              String line = br.readLine();
              while (line != null) {
                  sb.append(line + "\n");
                  line = br.readLine();
              }
              return sb.toString();
          } finally {
              if (stream != null) {
                  stream.close();
              }
          }
      }
  
      @Override
      protected void onPostExecute(String result) {
          mTextView.setText(result);
          // Can not reactivate button / cancel (pending?) events....
          //mButton.setVisibility(View.VISIBLE);
          mButton.setEnabled(true);
          //mButton.setClickable(true);
      }
  }
  </code></pre>
  
  <p>The full project (it is very simple, just a training example) is available to test in this <a href="https://github.com/JSMiranda/android-training/tree/master/Lab4_Ex1" rel="nofollow">repository</a> that I have just created.</p>
  
  <p>To conclude, from what I have read, there is in fact a problem regarding button disabling. Mostly this is resolved through the use of a flag to call the onClick method only when the flag is true. Although, this does not solve the problem of re-enabling the button. I have also tried <code>mButton.cancelPendingInputEvents();</code> but it does not work (and I do not know why. Click events are not yet registered? Or they are not pending?</p>
  
  <p>Is there a simple solution to this problem? Any ideas? Am I missing some basic detail? If not, I am considering trying to create a new button programatically to contour the problem. If I do not keep references to old buttons, are they deleted through garbage collection?</p>
  
  <p>Thanks in advance!</p>
  
  <p><strong>[Edit] Clarification:</strong>
  <p>Since the title could be misleading in this point, I want to clarify that I am able to disable and re-enable the button and all the functionality is ok <strong>except when the buttion is disabled</strong>. And note that I have added the line <code>if(counter&gt;1) return;</code> just to test but it stops the button from working the way I wanted (that's why I am not using a flag. I don't want this line to be there when I solve the problem!). The log is enough to inform me that the method is being called when the button is <strong>re-enabled</strong>, because I clicked it when it was <strong>disabled!</strong></p>