Does onClickListener affect the user interface until all the code inside it runs on Android?

I have an onClickListener that starts a network call, so I would like to have a way to show the user that the connection is in progress. The problem I am facing is that I cannot apparently throw away the ProgressDialog or change the user interface in any way before the call is made inside the onClick listener. All code works very well, but user interface changes do not take effect until all the code in onClickListener has been run.

I was wondering if my problem is simply that an anonymous inner class, such as onclicklistener, can only update the user interface at the end of its launch? Or maybe my code is just bad.

Thanks in advance

Below is the code for the onclick listener:

relayButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { cPanel.throwProgress(NCDTCPRelayActivity.this); System.out.println(tvSocketConnection.getText().toString()); if (relayStatusArray[relayNumber] == 0) { if (cPanel.TurnOnRelay(relayNumber, 1) == false) { changeTitleToRed(); }else{ changeTitleToGreen(); } } else { if (cPanel.TurnOffRelay(relayNumber, 1) == false){ changeTitleToRed(); }else{ changeTitleToGreen(); } } cPanel.hideProgress(NCDTCPRelayActivity.this); } }); 

Here is the code for throwProgress and hideProgress respectively (they are in the activity subclass):

 public boolean throwProgress(Context mContext) { System.out.println("INSIDE THROWPROGRESS"); try { tempDialog = ProgressDialog.show(mContext, "Connecting", "Connecting", true); } catch (RuntimeException e) { return false; } return true; } public boolean hideProgress(Context mContext) { System.out.println("OUTSIDE THROWPROGRESS"); tempDialog.hide(); return true; } 

** Edit Here is the new code for onClickListener, which I entered runnable in:

  public void onClick(View v) { cPanel.throwProgress(NCDTCPRelayActivity.this); System.out.println(tvSocketConnection.getText().toString()); handler.post(new Runnable() { @Override public void run() { // TODO Auto-generated method stub if (relayStatusArray[relayNumber] == 0) { if (cPanel.TurnOnRelay(relayNumber, 1) == false) { changeTitleToRed(); }else{ changeTitleToGreen(); } } else { if (cPanel.TurnOffRelay(relayNumber, 1) == false){ changeTitleToRed(); }else{ changeTitleToGreen(); } } cPanel.hideProgress(NCDTCPRelayActivity.this); relayStatusArray = cPanel.getBankStatus(1); updateButtonText(); } }); } 
+6
source share
2 answers

Changing the user interface of your click handler should work fine. The problem is probably that you are doing hard work on the UI thread and blocking it so that the dialog does not refresh until all this work is done. Try moving the entire heavy lift to AsyncTask (read this document if you are unfamiliar with it), hiding the dialog when the task is completed, and see if this fixes it.

+3
source

All user interface updates are delayed on Android, as well as on virtually every graphics platform. Changes in appearance are not immediately displayed; instead, the GUI subsystem marks the view as "needs to be redrawn" and calls draw() some time later in the message outline.

If you want something to happen after updating the screen, use Handler.post() . The post() 'ed code will run for some time in the message loop, usually later than the code with numbered code.

Beyond node: Windows GUI is a happy exception to this rule; you can draw a windows window outside of WM_PAINT. But on Android you cannot.

+3
source

Source: https://habr.com/ru/post/909223/


All Articles