The stream in onCreate() sets the value to true , but after using the stream, the global variable is displayed as false .

How to correctly change it in the stream so that after that it has visibility outside the stream (with the data assigned to it in the stream)?

 public class MainActivity extends Activity { boolean access; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txt=(TextView) findViewById(R.id.textView); new Thread(new Runnable() { @Override public void run(){ if (checkInternet()) { access = true; } else { access = false; } } }).start(); Log.d("my_tag", "AFTER Thread access is "+access); // show access as "false" } } 
  • 2
    and if the variable is marked as volatile - ermak0ff
  • one
    most likely, you simply have no time to complete the thread, so the old value is shown. To wait for the thread to complete - execute the join () method for an object of type Thread - Andrew Bystrov
  • if volatile boolean access; it is also false - mtb
  • @AndrewBystrov to bring the work into the asynchronous stream and hang the main thread to wait for the completion of the asynchronous? very good advice .. - pavlofff
  • then how else? - mtb

2 answers 2

So you do not correctly conclude.

See:

 new Thread(new Runnable() { ... }).start(); 

Here you created a thread and it went to run. And you immediately output the variable in the OTHER stream (which is the parent for the Internet Checker stream).

  Log.d("my_tag", "AFTER Thread access is "+access); // show access as "false" 

So it turns out that the stream started, but checkInternet() did not have time to complete and you display the old value. Option two is to remove the start of the stream, if checkInternet() is performed quickly, then you just lose time on starting the stream. Or, if checkInternet() and everything in run() takes a long time, then move the output to the stream itself:

 new Thread(new Runnable() { @Override public void run(){ Log.d("my_tag", "Checking internet..."); if (checkInternet()) { access = true; Log.d("my_tag", "Okay, internet works fine."); } else { access = false; Log.d("my_tag", "Fail! Can't connect to internet."); } } }).start(); 
  • This option does not suit me because checkInternet () should be executed in a separate stream, besides access must change so that it can be immediately seen by the main thread, and then it will not work so I’ll have to wait for this thread to check the connection - mtb
  • @mtb, I hope you understand that the problem is that you check the value of a variable before it changes. Those. the variable changes from a separate thread, but you, without waiting for its change, take the old value. - Nikotin N
  • I'm interested in how to synchronize this action without stopping the main thread - mtb
  • If you call join (), as advised above, immediately after the start () call, this will be equivalent to running in one thread. Only you still lose time at the start of the stream. In general, an epic crap. It makes sense only if you do not want to block the interface. In principle, you are doing everything right, only the conclusion was not made there. All actions should be carried out in a new stream. Immediately I will say, you want to manipulate the interface from another thread - read about runOnUIThread and postInvalideate, often beginners stumble on this. - Uraty
  • How are these methods better than AsynTask? - mtb

In the logs you get false due to the fact that in your case, the variable changes its value after you output its value to the log.

Those. You start the stream, then output the value of the variable, and only after that change the value of this variable.

If you need to check for an Internet connection, and, depending on the result, perform any actions, you can declare an activation callback class in the class:

 private void onInternetConnectionChecked(boolean isEnabled) { // some actions } 

And call this callback from the stream after you get the state of the Internet connection, for example:

 onInternetConnectionChecked(true); 

If in this callback you manipulate the UI, then you need to call this callback in the UI stream:

 runOnUiThread(new Runnable() { @Override public void run() { onInternetConnectionChecked(true); } });