【问题标题】:Not able to close input stream无法关闭输入流
【发布时间】:2011-09-04 18:55:18
【问题描述】:

在这个应用程序中,我正在运行一个远程服务,我正在启动一个单独的线程来运行 TCP 连接...在应用程序退出时,我必须关闭我要为其提供线程中断并更改布尔值的输入流(stopBroadcastRequested)..当在线程块中满足这一点时,我正在关闭输入流,但它实际上并没有关闭......如果我在正常线程执行期间手动给线程内的 instream.close ,输入流关闭为预期..但是在 if(stopBroadcastRequested){ 代码块} 中,它不起作用..有人可以告诉我我犯了什么错误...

public class BroadcastService extends Service {

    class Task implements Runnable{
    OutputStream outStream = null;
    InputStream inStream = null;

    @Override
    public void run() {
        while(!stopBroadcastRequested){
            Log.i(TAG, "Thread Task started");          
            try {
                isSocketOpen = broadCastComm.isAliveOrOpenSocket("192.168.43.2", 6000, 17, 0);

                if(isSocketOpen){
                    Log.d("SERVICE CLASS", "STARTED THREAD - Writing in output stream");

                    notificationMngr.cancelAll();
                    isShowingNotification = false;
                    outStream = broadCastComm.getCurrentOutputStream();
                    outStream.write(messageToBeSent);
                    if(Integer.valueOf(messageToBeSent[2]) != (byte)0xA0){
                        Log.e("REVERTING", "REVERTING");
                        messageToBeSent = mFormatter.formBroadCastMessage("GET_PERIPH_DATA");
                    }

                    Log.d("OUTPUT STREAM", "Message sent ->" + ByteArrayToString(messageToBeSent));
                }else{
                    connectivityStatusHandler.sendEmptyMessage(0);
                }

                Thread.sleep(3000L);

                if(isSocketOpen){

                }

            } catch (Throwable t) { 
                Log.e(TAG, "Failed to retrieve data in thread", t);
            }
            Log.d("SERVICE CLASS", "End of THREAD");

        }

        if(stopBroadcastRequested){
            Log.e("SERVICE", "STOPPED THREAD");
            try {
                Log.e("*****THREAD", "CLOSED INPUT STARTED");
                if(inStream != null)
                    inStream.close();

                Log.e("*****THREAD", "CLOSED INPUT CLOSED");
                outStream.flush();
                outStream.close();
                Log.e("*****THREAD", "CLOSED OUTPUT");
            } catch (Exception e) {
                Log.e("THREAD", "FAILED TO CLOSE STREAMS");
            }
        }
    }

    public synchronized void stopThread(){
        stopBroadcastRequested = true;
    }

}


@Override
public void onDestroy() {
    super.onDestroy();
    Log.e(TAG, "Service destroying");
    stopBroadcastRequested = true;
    serviceThread.interrupt();


    cleanNotifications();
    broadCastComm.clearConnections();
    //dbHandler.removeCallbacks(dbUpdater);
    try {
        dbHelper.cleanup();
    } catch (Exception e) {
        Log.e("SERVICE", "Failed to clear DB connections");
    }
}

}

  ------LOG
05-30 19:28:03.878: ERROR/BroadcastService(20288): Failed to retrieve data in thread
05-30 19:28:03.878: ERROR/BroadcastService(20288): java.lang.InterruptedException
05-30 19:28:03.878: ERROR/BroadcastService(20288):     at java.lang.VMThread.sleep(Native Method)
05-30 19:28:03.878: ERROR/BroadcastService(20288):     at java.lang.Thread.sleep(Thread.java:1213)
05-30 19:28:03.878: ERROR/BroadcastService(20288):     at java.lang.Thread.sleep(Thread.java:1195)
05-30 19:28:03.878: ERROR/BroadcastService(20288):     at      com.RBEI.TTApp.BroadcastService$Task.run(BroadcastService.java:126)
05-30 19:28:03.878: ERROR/BroadcastService(20288):     at java.lang.Thread.run(Thread.java:1019)
05-30 19:28:03.878: DEBUG/SERVICE CLASS(20288): End of THREAD
05-30 19:28:03.878: ERROR/SERVICE(20288): STOPPED THREAD
05-30 19:28:03.878: ERROR/*****THREAD(20288): CLOSED INPUT STARTED
05-30 19:28:03.882: ERROR/*****THREAD(20288): CLOSED INPUT CLOSED
05-30 19:28:03.882: ERROR/*****THREAD(20288): CLOSED OUTPUT

【问题讨论】:

  • Log.e("SERVICE", "STOPPED THREAD");这条线真的执行了吗?
  • 是的..它被执行了....
  • 当我在此 while(buf.available() > 0){} 内或在正常执行期间仅在此之外给出时,它按预期关闭,...但在中断中不起作用块......这是一些线程问题......像共享资源或什么......
  • 您多次致电inStream.close();。也许第一个镜头关闭了它,而您在随后的关闭中看到未能关闭。
  • hmmm...如果它关闭一次应该没问题..因为在服务器中它会关闭...

标签: android sockets tcp inputstream


【解决方案1】:

您只能使用 close() 一次。只需添加支票if (inStream != null { inStream.close(); ) 每次。

【讨论】:

  • hmmm....当我放一个断点并检查它是否有效...我不确定为什么它需要延迟才能工作...
  • 好吧,如果您找不到解决方案,我想将此代码放入 AsyncTask 会正常工作。我认为由于线程睡眠,它目前应该给你一种 InterruptedException?
  • 不,一点也不。这是一种用于以非常有效且用户友好的方式执行后台操作的包装器。有很多这样的教程:labs.makemachine.net/2010/05/android-asynctask-example
  • 我还建议您尝试删除 Thread.sleep 方法并检查是否可以复制问题
  • hmmm.... 为什么不使用处理程序?猜测异步任务需要从 UI 线程启动..整个代码在远程服务中运行..有建议吗?
【解决方案2】:

你在行得到一个异常(InterruptedException)

Thread.sleep(3000L);

这发生在您为 inStream 变量赋值之前, 所以

inStream = broadCastComm.getCurrentInputStream();

永远不会被执行。不能关闭为空的 Socket。

【讨论】:

  • 我现在不使用这个...inStream = broadCastComm.getCurrentInputStream();
【解决方案3】:

对不起,伙计们,问题是我没有正确解除绑定服务,这导致了所有这些问题……没有使用正确的上下文在 tabactivity 中解除绑定……不得不改用 getApplicationContext()……: )

【讨论】:

    猜你喜欢
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2022-12-12
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多