Mousa Jafari
Mousa Jafari

Reputation: 677

Access to main thread views from another thread

I thought that it is not possible to access main thread views in a new thread!

But why below codes runs without any problem?!

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView = (TextView) findViewById(R.id.textView);

    new Thread(new Runnable() {
        @Override
        public void run() {

            try {
                textView.append(InetAddress.getByName("192.168.1.252").getHostName() + "\n\n");
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

Upvotes: 0

Views: 527

Answers (3)

GilbertS
GilbertS

Reputation: 659

The solution is to run the UI thread inside your new thread. Here is an example using anko.

btn_login.text = "LOGING IN"
doAsync {
   authenticate(email, password)
   uiThread { btn_login.text = "LOGIN" }
}



Upvotes: 0

Rashin
Rashin

Reputation: 806

As it stands here:

For example, below is some code for a click listener that downloads an image from a separate thread and displays it in an ImageView:

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            Bitmap b = loadImageFromNetwork("http://example.com/image.png");
            mImageView.setImageBitmap(b);
        }
    }).start();
}

At first, this seems to work fine, because it creates a new thread to handle the network operation. However, it violates the second rule of the single-threaded model: do not access the Android UI toolkit from outside the UI thread—this sample modifies the ImageView from the worker thread instead of the UI thread. This can result in undefined and unexpected behavior, which can be difficult and time-consuming to track down.

So it works, but not recommended. There are some recommended way to do this instead:

To fix this problem, Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help:

Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)

Upvotes: 1

Konstantin
Konstantin

Reputation: 184

try this:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);

        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.append(InetAddress.getByName("192.168.1.252").getHostName() + "\n\n");
                        }
                    });                 
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

runOnUiThread - is method from activity. if you work inside fragment you can call getActivity().runOnUiThread

Upvotes: 1

Related Questions