【问题标题】:Android AsyncTask + Handler, no data updated to Main Activity UIAndroid AsyncTask + Handler,没有数据更新到 Main Activity UI
【发布时间】:2017-04-13 06:25:18
【问题描述】:

我们有一个带有文本视图的主要活动,它被请求从 LAN 中的 TCP 服务器自动检索数据。 我们在updateData()中启用了AsyncTask调用Connect调用Handler来更新名为mTvVoc的TextView,并通过beginConnect()刷新连接。

问题是 mTvVoc 没有更新,AsyncTask 似乎没有按预期运行?

public class MainActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    updateData();
}


    public void updateData(final String order) {
        Connect(HOST, PORT, order);
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                System.out.println("get data from order--->" + order);
                beginConnect(HOST, PORT, order);
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);                
            }

        }.execute();
    }

    public String Connect(final String HOST, final int PORT, final String OderType) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket(HOST, PORT);
                    bufferedInputStream = new     BufferedInputStream(socket.getInputStream());
                    System.out.println("bufferedInputStream--->" + bufferedInputStream);
                    printWriter = new PrintWriter(new BufferedWriter(
                            new OutputStreamWriter(socket.getOutputStream())),
                        true);
                    if (socket.isConnected()) {
                        if (!socket.isOutputShutdown()) {
                            printWriter.println(Integer.toHexString(Integer
                                 .parseInt(OderType)));
                        }
                    }

                    while (true) {
                        if (!socket.isClosed() && socket.isConnected() && !socket.isInputShutdown()) {
                            int temp = 0;
                            byte[] buf = new byte[1024];
                            while ((temp = bufferedInputStream.read(buf)) != -1) {
                                isConn(socket);
                                Log.d("Data received", new String(buf, 0, temp));
                                acceptinfo = new String(buf, 0, temp);
                                System.out.println("Data received====》" + acceptinfo);
                                Message message = new Message();
                                message.what = 1;
                                message.obj = acceptinfo;
                                handler.sendMessage(message);
                            }
                        }
                    }
                } catch (UnknownHostException e) {
                    System.out.println("UnknownHostException-->connection failed");
                    stopConnect();
                    e.printStackTrace();
                } catch (IOException e) {
                    System.out.println("IOException-->connection failed");
                    stopConnect();
                    e.printStackTrace();
                }
            }
        }).start();
        return acceptinfo;
    }


    public String beginConnect(final String HOST, final int PORT, final String OderType) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket(HOST, PORT);
                    bufferedInputStream = new BufferedInputStream(socket.getInputStream());
                    System.out.println("bufferedInputStream--->" + bufferedInputStream);
                    printWriter = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())),
                        true);
                    if (socket.isConnected()) {
                        if (!socket.isOutputShutdown()) {
                                 printWriter.println(Integer.toHexString(Integer.parseInt(OderType)));
                        }
                    }
                } catch (UnknownHostException e) {
                    System.out.println("UnknownHostException-->connection failed");
                    stopConnect();
                    e.printStackTrace();
                } catch (IOException e) {
                    System.out.println("IOException-->connection failed");
                    stopConnect();
                    e.printStackTrace();
                }
            }
        }).start();
        return acceptinfo;
    }


    public Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.i("message", msg.obj.toString());
            if (msg.what == 0) {
                mIvContent.setImageResource(R.drawable.wangluo_gray);
                Toast.makeText(MainActivity.this, "Server connection failed", Toast.LENGTH_SHORT).show();
                reGetData();
            }
            if (msg.what == 1) {
                String info = msg.obj.toString();
                if (info.length() != 18) {
                    mIvContent.setImageResource(R.drawable.wangluo_gray);
                    System.out.println("data verification failed");
                    reGetData();
                    return;
                }

                String iszeroupString = info.substring(1, 3);
                String temperature = Integer.toString(Integer.parseInt(info.substring(3, 5), 16));
                String vocValue = Integer.toString(Integer.parseInt(info.substring(7, 9), 16));
                mTvVoc.setText(getVOC((Integer.valueOf(vocValue ) / 100.00)));

            }
        }
}

【问题讨论】:

  • 很奇怪你有一个 Connect() 和一个 beginConnect,() 都连接到服务器。所以两个客户端实例。你为什么要这样做?没有意义。
  • 而你在 doInBackground 中启动新线程是完全错误的。只需将您的代码直接放在 doInBackground 中,而无需将其包装在线程中。并且不要两次连接。好吧,除非您有充分的理由这样做,但您没有告诉我们。使用线程或异步任务。两者都不是。
  • 所以我需要删除 beginConnect()?

标签: android multithreading android-asynctask handler


【解决方案1】:

您不能直接从后台线程到 UI 线程进行通信 更新任何 UI 组件。

在你的后台线程中使用它来更新 textviewAsyncTask.

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        Log.d("UI thread", "I am the UI thread");
        // update your text here 
    }
});

【讨论】:

    【解决方案2】:

    要更新 UI,您需要运行 UIThread 中的代码。请参阅下面的代码并放入您的处理程序:

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Log.i("message", msg.obj.toString());
            if (msg.what == 0) {
                mIvContent.setImageResource(R.drawable.wangluo_gray);
                Toast.makeText(MainActivity.this, "Server connection failed", Toast.LENGTH_SHORT).show();
                reGetData();
            }
            if (msg.what == 1) {
                String info = msg.obj.toString();
                if (info.length() != 18) {
                    mIvContent.setImageResource(R.drawable.wangluo_gray);
                    System.out.println("data verification failed");
                    reGetData();
                    return;
                }
    
                String iszeroupString = info.substring(1, 3);
                String temperature = Integer.toString(Integer.parseInt(info.substring(3, 5), 16));
                String vocValue = Integer.toString(Integer.parseInt(info.substring(7, 9), 16));
                mTvVoc.setText(getVOC((Integer.valueOf(vocValue ) / 100.00)));
    
            }
        }
    });
    

    【讨论】:

      【解决方案3】:

      编写该处理程序以更新 gui 非常糟糕。取消它,因为 AsyncTask 已经提供了这样做的功能。

      你应该对许多例子看得更清楚。

      使用 publishProgress()onProgressUpdate() 更新进度条和/或其他 gui 元素。

      如果您的代码必须在doInBackground() 中执行,请不要将其包装在线程中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-12
        • 2021-08-30
        • 1970-01-01
        • 2019-01-08
        相关资源
        最近更新 更多