{"id":627,"date":"2022-08-30T15:04:30","date_gmt":"2022-08-30T15:04:30","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/09\/error-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-views-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:04:30","modified_gmt":"2022-08-30T15:04:30","slug":"error-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-views-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/error-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-views-collection-of-common-programming-errors\/","title":{"rendered":"error: Only the original thread that created a view hierarchy can touch its views-Collection of common programming errors"},"content":{"rendered":"<p>Hi and thank you for looking at my question. I am an intermediate programmer in C but an Android newbie. I have been trying to get a chat programming working. Assuming everything else in the code below works perfectly. The one question I like to ask is when I try to <strong>setText()<\/strong> from a thread running, I get an exception above. I looked at many many websites and here too. Found many things, but I really do not understand. Please explain to me in the most simple way or offer me some simple fix if possible.<\/p>\n<p>Thank you very much!!<\/p>\n<pre><code>public class chatter extends Activity {\n\nprivate String name = \"Unknown User\";\n\n\/** Called when the activity is first created. *\/\n@Override\npublic void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.main);\n\n\n\n    final EditText msgToServer = (EditText) findViewById(R.id.msgBox);\n    final EditText chatFromServer = (EditText) findViewById(R.id.chatBox); \n\n    final Button MsgToServer = (Button) findViewById(R.id.sendButton);\n\n    Socket socket = null;\n    String ipAddress = \"192.168.1.103\";\n    try {\n        InetAddress serverAddr = InetAddress.getByName(ipAddress);\n        Socket socketMain = new Socket(serverAddr, 4444);\n        socket = socketMain;\n    } catch (IOException e) {\n        \/\/ TODO Auto-generated catch block\n        Log.e(\"TCP\", \"error\", e);\n    }\n\n    final OutMsg outMsg = new OutMsg(socket);\n    Thread msgSenderThread = new Thread(outMsg);\n    msgSenderThread.start();\n\n    \/\/chatFromServer.post(new InMsg(socket, chatFromServer));\n    Thread msgReceiverThread = new Thread(new InMsg(socket, chatFromServer));\n    msgReceiverThread.start();\n\n    MsgToServer.setOnClickListener(new View.OnClickListener() {\n        @Override\n        public void onClick(View v) {\n            String msgToServerString; \n            msgToServerString = msgToServer.getText().toString();\n            outMsg.message = name + \": \" + msgToServerString;\n            outMsg.readyToSend = true;\n            msgToServer.setText(\"\");\n        }\n    });\n}\n\npublic void updateResultsInUi (String msg)\n{\n    final EditText chatFromServer = (EditText) findViewById(R.id.chatBox); \n    chatFromServer.setText(msg); \n}\n\npublic class InMsg implements Runnable {\n\n    Socket socket;\n    EditText chatFromServer;\n    public InMsg(Socket socket, EditText chatFromServer)\n    {\n        this.socket = socket;\n        this.chatFromServer = chatFromServer;\n    }\n\n    public void run(){\n        try {\n        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));\n        String str = \"FIRSTMESSAGEFROMSERVER\";\n            while (true)\n            {\n                if (str.equals(\"FIRSTMESSAGEFROMSERVER\"))\n                    str = in.readLine();\n                else\n                    str = str + \"\\n\" + in.readLine();\n                Log.e(\"TCP\", \"got the message: \" + str);\n     \/\/Here is where went wrong******************\n                chatFromServer.setText(str);\n     \/\/******************************************\n            }\n        } catch (IOException e) {\n            \/\/ TODO Auto-generated catch block\n            Log.e(\"TCP\", \"error in receiving\", e);\n        }\n    }\n\n}\n\n@Override\npublic boolean onCreateOptionsMenu(Menu menu) {\n    MenuInflater inflater = getMenuInflater();\n    inflater.inflate(R.menu.menu, menu);\n    return true;\n}\n\n@Override\npublic boolean onOptionsItemSelected(MenuItem item) {\n    \/\/ Handle item selection\n    switch (item.getItemId()) {\n    case R.id.setNameMenu:\n        setname();\n        return true;\n    default:\n        return super.onOptionsItemSelected(item);\n    }\n}\n\npublic void populateChatBox (String msgFromS)\n{\n    Log.e(\"TCP\", \"going in to popC\");\n    final EditText textNameInput = (EditText) findViewById(R.id.nameBox);\n    Log.e(\"TCP\", \" popC\");\n    textNameInput.setText(msgFromS);\n    Log.e(\"TCP\", \"going out from popC\");\n}\n\npublic void setname()\n{\n    setContentView(R.layout.custom_dialog);\n    final EditText textNameInput = (EditText) findViewById(R.id.nameBox);\n    Button submitNameButton = (Button) findViewById(R.id.submitNameButton);\n    submitNameButton.setOnClickListener(new OnClickListener() {\n    @Override\n        public void onClick(View v) {\n        String nameinput = textNameInput.getText().toString();\n            if (!name.equals(\"\"))\n                name = nameinput;\n            setContentView(R.layout.main);\n        }\n    });\n}\n}\n<\/code><\/pre>\n<ol>\n<li>\n<p>In your run() method:<\/p>\n<pre><code>Message msg = new Message();\nString textTochange = \"text\";\nmsg.obj = textTochange;\nmHandler.sendMessage(msg);\n<\/code><\/pre>\n<p>Create the mHandler in your UI thread;<\/p>\n<pre><code>Handler mHandler = new Handler() {\n        @Override\n        public void handleMessage(Message msg) {\n            String text = (String)msg.obj;\n            \/\/call setText here\n        }\n};\n<\/code><\/pre>\n<\/li>\n<li>\n<p>You are not on the UI thread when setting the text. You need to be on UI if you want to work on UI items. Create a message handler on the UI thread, post your messages to it and call setText from the handler on the UI thread.<\/p>\n<\/li>\n<li>\n<p>you can do this whenever you are in a thread:<\/p>\n<pre><code>msgToServer.post(new Runnable() {\n    public void run() {\n        msgToServer.setText(\"your text here\");\n    }\n}\n<\/code><\/pre>\n<\/li>\n<li>\n<p>Your problem is that there are certain interactions that you can only do on the UI thread. This is one of them.<\/p>\n<p>Looks like you might want to use AsyncTask<\/p>\n<p>http:\/\/developer.android.com\/reference\/android\/os\/AsyncTask.html<\/p>\n<p>Basically you could make your Runnable an AsyncTask instead and do the setText in onProgressUpdate, which gets run on the UIThread.<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-11-09 21:08:44. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>Hi and thank you for looking at my question. I am an intermediate programmer in C but an Android newbie. I have been trying to get a chat programming working. Assuming everything else in the code below works perfectly. The one question I like to ask is when I try to setText() from a thread [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-627","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=627"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/627\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}