Search code examples
javaandroidcallbacktextview

TextView setText() called in callbacks from wrong context


I tried implementing a network service discovery and setting the name into a textView after successful registration. But I am getting an android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. exception. My basic structure looks like this:

NsdManager.RegistrationListener mRegistrationListener;

onCreate() {
    mRegistrationListener = new NsdManager.RegistrationListener() {
        onServiceRegistered(serviceInfo) {
            TextView textView = (TextView) findViewById(R.id.nsdServiceNameText);
            textView.setText(serviceInfo.getServiceName());
        }
    }
    
    mNsdManager = (NsdManager) this.getBaseContext().getSystemService(Context.NSD_SERVICE);

    mNsdManager.registerService(
        serviceInfo,
        NsdManager.PROTOCOL_DNS_SD,
        mRegistrationListener);
}

It makes sense to me that I may be in the wrong context to edit the view but how did I get there and more importantly how do I solve this?


Solution

  • If you read the documentation of NsdManager here: https://developer.android.com/reference/android/net/nsd/NsdManager

    It says that:

    The API is asynchronous, and responses to requests from an application are on listener callbacks on a separate internal thread.

    So it moves away from the UI thread which is where you should be updating your UI as pointed out in the comments as following:

    runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText(serviceInfo.getServiceName());
                    }
                });