I am trying to disable a button while a download task is running. I tried using setEnabled, setVisibility and setClickable. I seem to have tried all combinations of these options. All of them disable button click events during task execution, but events are still logged somehow, and when I react to a button, the handler is called if I pressed 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).
I also added a counter and a log to check what I said above. The code is shown below. This piece of code if(counter>1) return; designed to stop the crash, but I would like to remove it, since I want to turn this button back on and not turn it off permanently.
OnClick:
public void downloadOnClick(View v) { counter++; Log.d(this.getLocalClassName(), "Button was clicked " + counter + " times."); if(counter>1) return; ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && 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."); } }
AsyncTask:
private class DownloadWebpageTask extends AsyncTask<String, Void, String> { private HttpURLConnection mConnection; @Override protected String doInBackground(String... urls) { try { URL url = new URL(urls[0]); mConnection = (HttpURLConnection) url.openConnection(); mConnection.setReadTimeout(10000 ); mConnection.setConnectTimeout(15000 ); 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);
The full project (this is a very simple, just a training example) is available for testing in this repository that I just created.
In conclusion, from what I read, there is actually a problem with disabling buttons. Basically, this is allowed using 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 also tried mButton.cancelPendingInputEvents(); but it doesn’t work (and I don’t know why. Are events not registered yet? Or are they not expected?
Is there a simple solution to this problem? Any ideas? Am I missing some basic details? If not, I'm thinking of trying to create a new button programmatically to outline the problem. If I don’t refer to the old buttons, are they deleted through the garbage collection?
Thanks in advance!
[Edit] Clarification:
Since the title may be misleading at this point, I want to clarify that I can disable and enable the button again, and all functions are in order , except when the function is disabled . And note that I added the line if(counter>1) return; just for verification, but it doesn’t allow the button to work the way I wanted (why I don’t use the flag. I don’t want this line to be there when I solve the problem!). The log is enough to tell me that the method is called when the button is re-enabled , because I clicked it when it was disabled!