2017-04-13 1 views
0

私のアクティビティが作成されると、キーパッドの押下を連続的に聞き始めるスレッドを起動します(while(true)) ...これは完全に機能しますが、入力ストリームが閉じられていない状態で、散発的で信頼できないアクティビティの終了時に入力ストリームが閉じられることを確認する方法(Android)

MY CODE

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_keypad_test_button); 

    // Set the view pager for return 
    MainActivity.ViewPagerPosition = 1; 

    // These are text views that turn green when the corrosponding key is pressed 
    key0 = (TextView) findViewById(R.id.btn_keypad_0); 
    key1 = (TextView) findViewById(R.id.btn_keypad_1); 
    key2 = (TextView) findViewById(R.id.btn_keypad_2); 
    key3 = (TextView) findViewById(R.id.btn_keypad_3); 
    key4 = (TextView) findViewById(R.id.btn_keypad_4); 
    key5 = (TextView) findViewById(R.id.btn_keypad_5); 
    key6 = (TextView) findViewById(R.id.btn_keypad_6); 
    key7 = (TextView) findViewById(R.id.btn_keypad_7); 
    key8 = (TextView) findViewById(R.id.btn_keypad_8); 
    key9 = (TextView) findViewById(R.id.btn_keypad_9); 
    keyClear = (TextView) findViewById(R.id.btn_keypad_clear); 
    keyEnter = (TextView) findViewById(R.id.btn_keypad_enter); 
    keyF1 = (TextView) findViewById(R.id.btn_keypad_f1); 
    keyF2 = (TextView) findViewById(R.id.btn_keypad_f2); 
    keyF3 = (TextView) findViewById(R.id.btn_keypad_f3); 
    keyF4 = (TextView) findViewById(R.id.btn_keypad_f4); 
    keyF5 = (TextView) findViewById(R.id.btn_keypad_f5); 
    keyF6 = (TextView) findViewById(R.id.btn_keypad_f6); 
    keyF7 = (TextView) findViewById(R.id.btn_keypad_f7); 
    keyF8 = (TextView) findViewById(R.id.btn_keypad_f8); 

    // This is for later checking to see if all keys have been pressed at some point 
    allKeys = new TextView[] { key0, key1, key2, key3, key4, key5, key6, key7, key8, key9, 
      keyClear, keyEnter, keyF1, keyF2, keyF3, keyF4, keyF5, keyF6, keyF7, keyF8 }; 

    // I eventually set whether all keys have been pressed by looking at their tags 
    for (TextView button : allKeys) { 
     button.setTag(0); 
    } 

    // I use this method to create a rest api to work with my hardware keypad 
    createRestAPI(); 

    clockUserAPI.getKeyboardStream().enqueue(new Callback<ResponseBody>() { 
     @Override 
     public void onResponse(Call<ResponseBody> call, final Response<ResponseBody> response) { 

      if (response == null) Log.v(TAG, "Null response"); 

      else { 

       Log.v(TAG, "About to start thread"); 
       Thread keyboardInputThread = new Thread(new Runnable() { 
        @Override 
        public void run() { 

         running = true; 

         InputStream inputStream = null; 
         try { 
          // THIS IS WHERE THE INPUT STREAM IS DEFINED 
          inputStream = response.body().byteStream(); 
          byte[] buffer = new byte[256]; 

          // PRETTY MUCH while(true) ... THIS CONTINUOUSLY LISTENS FOR KEYPAD PRESSES 
          while (running) { 

           Log.v(TAG, "Reading..."); 

           int bytesRead = inputStream.read(buffer, 0, buffer.length); 
           Log.v(TAG, bytesRead + " Bytes read"); 

           String fullResponse = new String(buffer, 0, bytesRead, StandardCharsets.UTF_8); 
           Log.v(TAG, "Full response: " + fullResponse); 

           // I use this method to parse the json response for the key I want 
           processResponse(fullResponse); 
          } 

         } catch (IOException e) { 
          Log.v(TAG, "Exception..."); 

          e.printStackTrace(); 

         } finally { 

          // I TRY TO CLOSE THE INPUT STREAM HERE BUT THE PROGRAM NEVER REACHES THIS POINT. 
          try { 
           Log.v(TAG, "Closiing input stream..."); 

           inputStream.close(); 
           Log.v(TAG, "Success"); 

          } catch (IOException e1) { 
           e1.printStackTrace(); 
           Log.v(TAG, "Failure..."); 

          } 
         } 
        } 
       }); 
       keyboardInputThread.start(); 

      } 
     } 

     @Override 
     public void onFailure(Call<ResponseBody> call, Throwable t) { 
      Log.d(TAG, "Response error failure: throwable=" + t); 
     } 
    }); 
} 

私の理論は、tryブロックが終了されることはありませんので、入力ストリームが閉じられることはありませんということです。それは連続的にwhile(true)を実行します。私はこの場合に必要です。では、ユーザーがクリックしたときに入力ストリームをどこで閉じるのですか?私はonStop()onDestroy()を試しましたが、それらも呼ばれることは保証されていません。

+0

@Override ます。public void(){// あなたのコード。 } tryしました –

+0

[onPause](https://developer.android.com/guide/components/activities/activity-lifecycle.html#onpause)を使用して、ユーザーがあなたのアクティビティを離れるたびに実行をfalseに設定します。しかし、あなたの読んだコールは入力を待っている間もブロックされるので、あなたもそれを考慮する必要があります。 – Steveadoo

+0

@android_jain:入力ストリームonPauseを閉じると例外が発生します:java.lang.IllegalStateException:入力/出力のアンバランス –

答えて

0

は、あなたの活動のクラスにonPauseを追加します - onBackPressed

/** 
    * Called as part of the activity lifecycle when an activity is going into 
* the background, but has not (yet) been killed. The counterpart to 
* {@link #onResume}. 
* 
* <p>When activity B is launched in front of activity A, this callback will 
* be invoked on A. B will not be created until A's {@link #onPause} returns, 
* so be sure to not do anything lengthy here.**/ 

    @Override 
    public void onPause() { 
     super.onPause(); 
     if (inputStream != null) { 
      try { 
       inputStream .close(); 
      } 
      catch(IOException ioex) { 
       //Very bad things just happened... handle it 
      } 
     } 
    } 
+0

これは私にエラーをもたらします:java.lang.RuntimeException:アクティビティを停止できません{ com.example.testmode/com.example.testmode.TestFragments.KeypadTestActivity}:java.lang.IllegalStateException:Unbalanced enter/exit –

+0

コードを編集したところで、今すぐ確認できます。 –

関連する問題