【问题标题】:Server's Robot Screenshot Thread Blocked After Client InputStream Is Read读取客户端 InputStream 后服务器的机器人屏幕截图线程被阻塞
【发布时间】:2014-10-24 15:01:48
【问题描述】:

我编写了一个简单的服务器(java)/客户端(android)...我正在使用 Robot 从服务器捕获屏幕截图并使用套接字连接将其中继到客户端...这很好用- ——正好一次——但我需要随意重复这个动作……

我相当肯定,如果指向正确的方向,我可以设置更新屏幕截图的方法——但我不明白为什么我的线程挂起......

在客户端发布一个可运行的通过处理程序仅在初始 BitmapFactory.decodeStream 调用之后返回一个空位图...

我进行了上下搜索,找不到此行为的原因或任何解决方法...

服务器屏幕截图线程:

 private void screen(final Socket socket){
    Thread Shot1 = new Thread(){

        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();
            System.out.println("entered run");
            try {
            while(true){


                Toolkit defaultToolkit = Toolkit.getDefaultToolkit();

                Rectangle shotArea = new Rectangle(defaultToolkit
                    .getScreenSize());

                BufferedImage screenShot = robot
                    .createScreenCapture(shotArea);

                ImageIO.write(screenShot, "JPG", out);


                out.flush();


                Thread.sleep(2000);

            }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    };
    Shot1.start();
}

客户端阅读线程:

 Downloader = new Thread() {

             @Override
             public void run() {
                 android.os.Process
                    .setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

                 Bitmap bit = null;
                 try {
                     in = socket.getInputStream();

                 } catch (IOException e1) {
                     e1.printStackTrace();
                 }
                 try {
                     if (Thread.interrupted()) {
                         Log.i("thread interrupted", "true");
                         throw new InterruptedException();
                     }
                     if (socket != null) {

                         bit = BitmapFactory.decodeStream(in);
                         Log.i("bitmap", "decoded");


                     } else if (socket == null) {
                         Log.i("socket", "null");
                     }

                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block

                     e.printStackTrace();
                 }

                 if (bit != null && bit != temp //temporary bitmap for comparison only{
                          Log.i("bitmap", "not null and not temp");
                          threadMsg(bit);


                 }

             }

             private void threadMsg(Bitmap bit) {
                 if (bit != null) {
                     Message msg = mHandler.obtainMessage();
                     msg.what = NEED_TO_SET_BITMAP_FROM_SCREENSHOT;
                     Bundle b = new Bundle();
                     b.putParcelable("Bitmap", bit);
                     msg.setData(b);
                     mHandler.sendMessage(msg);

                 }
             }

         };

它挂在 ImageIO.write(screenShot, "JPG", out);

输入和输出流定义为客户端和服务器中的字段,它们在套接字连接时初始化。

代码没有抛出任何错误,服务器端截图线程将截取四张截图,客户端只读取一张然后服务器线程将挂在写行...

我迷路了...请帮助...

【问题讨论】:

  • 我之前没有遇到过阻塞的 write() 方法。你能确定线程在 ImageIO.write() 行“挂起”并提供调试代码来显示吗?此外,您的程序通过输出流发送整个屏幕截图的速度有多快?我不知道 ImageIO 能以多快的速度将整个屏幕截图写入输出流。您的线程是否真的“挂起”,或者可能是写所有屏幕截图数据需要一段时间?
  • 虽然我不能说 ImageIO.Write 方法阻塞了线程...我可以明确地说这是线程停止的地方...我使用 System.out.println("一些评论”)在代码的每一行之后检查并查看事情在哪里停止......没有抛出异常......这是我第一次涉足套接字,我不能老实说我没有做某事客户端错误可能完全错误...我可以说客户端将毫无问题地循环,我从另一个线程发布可运行文件并且它们运行但位图始终返回 null...
  • 客户端的第一次解码耗时不到一秒...服务器端似乎循环了四次(始终是四次),然后停止通过 ImageIO.write 行的代码。 ..
  • 在拍摄和写入完成之间检查时间(以毫秒为单位)... 第 1 次:780,第 2 次:1726,第 3 次:1972,第 4 次:1741,第 5 次:无限
  • 对不起,我不知道你的问题的答案。我可以建议你看看这篇文章:stackoverflow.com/questions/11842674/…。如果这不起作用,您可以不使用 ImageIO.write() 手动发送图像数据,只需通过 DataOutputStream 使用您自己的代码发送。

标签: java android multithreading sockets


【解决方案1】:

Android 的 BitmapFactory.decodestream(inputstream) 方法只允许从输入流中解码单个图像;虽然它可能不是最有效的解决方法,但我已通过以下方式解决了该问题:

1) 取消包含输入流和bitmapfactory调用的线程

2) 使用异步任务重新初始化套接字并调用建立新线程来解码新传入的图像...

这很有效,但再次感谢任何有关如何提高流程效率的建议,例如如何使用其他方式解码传入的图像

【讨论】:

    猜你喜欢
    • 2013-05-02
    • 2012-08-24
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    相关资源
    最近更新 更多