简单的android tcp应用程序不会更新主线程

时间:2018-11-21 16:22:28

标签: java android

我想为Android构建一个简单的tcp客户端。 客户端需要先发送名称和密码,然后保持与服务器的连接,直到应用程序关闭(如果由于某种原因而失去连接,则需要通过发送用户名和密码来重新建立连接)。

现在,我实现了一些简单的客户端,如下所示:

public class SendRecvAsynch extends AsyncTask<String, String, TcpClient> {

    final String SERVER_IP = "10.0.0.7"; //server IP address
    final int SERVER_PORT = 1234;

    String modifiedSentence;
    EditText tv = (EditText) findViewById(R.id.editText_main);


    @Override
    protected TcpClient doInBackground(String... message) {
        //we create a TCPClient object
        try {
            // create address
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

            try {
                //create a socket to make the connection with the server
                Socket socket = new Socket(serverAddr, SERVER_PORT);


                // create in out stream
                DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream());
                BufferedReader inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                // write to server and get response
                outToServer.writeBytes("hello from client");

                // read from server
                modifiedSentence = inFromServer.readLine();
                if (modifiedSentence == null)
                {
                    modifiedSentence = "didn't get a dame thing from the server";
                }

                // close the socket
                socket.close();

            }catch (IOException e) {
                tv.setText(e.toString());
                e.printStackTrace();
            }


        } catch (UnknownHostException e) {
            tv.setText("got exceptin");
            e.printStackTrace();
        }



        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);

        tv.setText(modifiedSentence);

        //response received from server
        Log.d("test", "response " + values[0]);
        //process server response here....

    }

}

我从OnCreate这样的方法启动客户端:

new SendRecvAsynch().execute("");

我希望该应用程序可以连接服务器,向他发送“来自客户端的问候”,等待服务器响应并关闭套接字连接。

收到响应后,我希望AsyncTask更新我在应用主屏幕上的EditText框。

问题在于此AsyncTask不会更新EditText ...我在服务器端看到该应用已连接并向服务器发送了“来自客户端的问候”,但我没有从客户端看不到服务器的响应...

我猜测由于某种原因,后台进程无法访问属于主线程的主屏幕,我该如何更改呢? 如何创建可以从服务器发送和接收线路的简单tcp客户端?

谢谢。

2 个答案:

答案 0 :(得分:0)

是的,在android系统中,禁止在主线程之外访问更新UI(在您的情况下为EditText)。

但是由于这个原因,AsyncTask具有onPostExecute()方法,您可以在其中直接从主线程运行代码。

因此,您唯一要做的就是覆盖onPostExecute()并在SendRecvAsynch中实现DROP TABLE IF EXISTS #TestTable1 DROP TABLE IF EXISTS #TestTable2 CREATE TABLE #TestTable1 ([No] varchar(50),[Value1] float,[Desc] varchar(50)) insert into #TestTable1 ([No],[Value1],[Desc]) Values (N'123953',300.02,N'Extra Pay') ,(N'123953',427.2,N'Basic Hours') ,(N'123953',106.8,N'Basic Hours') ,(N'123953',213.6,N'Basic Hours') ,(N'123953',213.6,N'Basic Hours') ,(N'123953',213.6,N'Basic Hours') ,(N'123953',213.6,N'Basic Hours') ,(N'123953',105.6,N'Basic Hours') CREATE TABLE #TestTable2 ([No] varchar(50),[Value2] float,[Desc] varchar(50)) insert into #TestTable2 ([No],[Value2],[Desc]) Values (N'123953',200.02,N'Extra Pay') ,(N'123953',553.02,N'Basic Hours') ,(N'123953',446.67,N'Basic Hours') ,(N'123953',427.2,N'Basic Hours') ,(N'123953',106.8,N'Basic Hours') ,(N'123953',213.6,N'Basic Hours') ,(N'123953',213.6,N'Basic Hours') ,(N'123953',213.6,N'Basic Hours') ,(N'123953',105.6,N'Basic Hours') 以适应您的需求。

答案 1 :(得分:0)

您应该看看runOnUiThread method

来自Android's Developers website:

  

public final void runOnUiThread(可运行操作)

     

在UI线程上运行指定的操作。如果当前线程是UI线程,则立即执行该操作。如果当前线程不是UI线程,则将操作发布到UI线程的事件队列。

即使您可以使用runOnUiThread解决问题,但我还是强烈建议您切换不久前引入的新Architecture Components。特别看一下ViewModelLiveData组件。这是Guide to app architecture