【问题标题】:Optimizing Android threads which are used to send network data优化用于发送网络数据的 Android 线程
【发布时间】:2012-05-03 03:06:48
【问题描述】:

我正在使用一个应用程序,它使用两个线程来读取数据并将数据发送到服务器。每个线程运行一个while循环;一个 que 包含一组命令,这些命令被 dequed 发送到服务器。这样我就可以将大量的命令排成队列并一一发送到服务器。

命令发送者是这样的

 class writeThread extends AsyncTask<Object, Object, Object>
 {
    byte[] buffer;
    LittleEndianDataOutputStream outputStream;
    @Override
    protected void onPreExecute() 
    {

    }
    @Override
    protected Object doInBackground(Object... params) 
    {
        try
        {
            buffer = new byte[4096];
            outputStream = new LittleEndianDataOutputStream(dataHolder.connection.getOutputStream());

            try
            {
                dataHolder.flags latestFlag;
                while (true)
                {
                    try 
                    {
                        latestFlag = dataHolder.sendFlags.remove();
                        ByteBuffer sendBytes = ByteBuffer.allocate(128);
                        sendBytes.order(ByteOrder.LITTLE_ENDIAN);
                        switch (latestFlag) 
                        {
                            case sendDataRequest:
                                sendBytes.putInt(20);
                                outputStream.write(sendBytes.array());
                                break;
                            case getSelectedData:
                                sendBytes.putInt(21);
                                sendBytes.put(dataHolder.latestSelected.getBytes());
                                outputStream.write(sendBytes.array());
                                break;
                            case disconnect:
                                sendBytes.putInt(254);
                                sendBytes.put(dataHolder.latestSelected.getBytes());
                                outputStream.write(sendBytes.array());
                                break;                                    

                        }


                    }
                    catch (NoSuchElementException ex){}
                }
            }
            catch (IOException ex) {}

        }
        catch (Exception ex){};
        return null;

    }


}

读取循环如下所示

     while (inputStream.read() > -1)

因此,应用程序最终占用了手机 50% 的处理能力。有没有关于如何优化socket监听和数据发送的建议?

注意:是的,我知道我正在对队列使用 try catch 而不是 if 语句来检查队列是否为空。我确信抛出错误无助于优化,但我认为它不会将处理器推到 50%。如果您需要更多信息,请告诉我。

【问题讨论】:

  • 大声笑我刚刚意识到我有一个未使用的 4kb 缓冲区。一定是以前的代码遗留下来的。

标签: android multithreading networking optimization


【解决方案1】:

您的实现的问题在于您基本上是在忙着等待 - 如果没有要发送的内容,它会立即转到异常处理程序并再次尝试 - 从而占用该内核上的所有 cpu。

您想要的是一种等待事件可用的方法。我建议您创建一个HandlerThread,并使用与该线程关联的 Handler 来处理对数据流的写入。

HandlerThread handlerThread = new HandlerThread("blah");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper()) {
    public boolean HandleMessage(Message msg) {
        switch (msg.what) {
            case sendDataRequest:
               ...
            case getSelectedData:
               ...
            case disconnect:
               ...
        }
    }
}

然后您将创建具有适当 id 和数据的消息,并使用 handler.sendMessage() 将它们发送到处理程序

或者(也许更简单),如果您将 dataHolder.sendFlags 集合设为 ArrayBlockingQueue,而不是当前的任何内容(我猜是 ArrayList 或类似的?),那么当您使用ArrayBlockingQueue.take(),它会一直等到有东西可用(没有执行占用所有可用 cpu 时间的繁忙等待)

【讨论】:

  • 是新 Handler(handlerThread.getLooper()) 的公共布尔 HandleMessage(Message msg) 部分吗?在左括号之前有一个关闭。从高中起我就没有在任何专业上使用过 Java,我对它有点干,所以我可能会错过理解初始化。
  • 这就是所谓的匿名类。这同时创建了一个新的 Handler 子类,以及一个覆盖 Handler.HandleMessage 的该子类的新实例。例如,请参阅docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm
  • 啊,有趣,我想我在 Java 中没有看到过。我习惯于在 ({}) 中看到它;还是我不明白什么?
  • 我有点困惑。我猜这不是writeThread的一部分?我需要确保一旦有任何东西被推送到队列中(可以是多个东西),只要队列中有可用的项目,它就会将该队列中的所有内容出列。我查看了示例,但我不太明白这将如何使其成为一个自动化过程......
  • HandlerThread 旨在替换您现有的 writeThread。当您使用 sendMessage 向处理程序发送消息时,将在 HandlerThread 上调用 HandleMessage 来处理该消息。多条消息可以彼此非常接近地发送 - 它们将排队并按照发送顺序进行处理。
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 2012-12-29
  • 2012-02-03
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多