2017-04-13 2 views
0

Lorsque mon activité est créée, je démarre un fil qui commence à écouter pour que le clavier appuie continuellement (while(true)) ... Cela fonctionne parfaitement, mais quand je clique sur le flux d'entrée n'est pas fermé et la prochaine fois que j'ouvre cette réponse d'activité est sporadique et peu fiable.Comment vous assurer que mon flux d'entrée est fermé à la sortie de l'activité (Android)?

MON 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); 
     } 
    }); 
} 

Ma théorie est que le flux d'entrée est jamais fermé parce que le bloc d'essai est jamais terminé. Il fonctionne continuellement while(true). J'ai besoin que ce soit le cas. Alors, où puis-je fermer le flux d'entrée lorsque l'utilisateur clique en arrière? J'ai essayé onStop() et onDestroy() mais ceux-ci ne sont pas garantis d'être appelés.

+0

@Override public void onBackPressed() {// votre code. } Aviez-vous essayé –

+0

Utilisez [onPause] (https://developer.android.com/guide/components/activities/activity-lifecycle.html#onpause) pour définir l'exécution sur false lorsque l'utilisateur quitte votre activité. Mais votre appel en lecture sera également bloqué en attendant la saisie, donc vous devrez en tenir compte également. – Steveadoo

+0

@android_jain: Fermeture du flux d'entrée onPause provoque une exception Causée par: java.lang.IllegalStateException: déséquilibrée entrée/sortie –

Répondre

0

Ajouter OnPause dans votre classe d'activité: -

/** 
    * 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

Cela me donne l'erreur: java.lang.RuntimeException: Impossible d'arrêter l'activité { com.example.testmode/com.example.testmode.TestFragments.KeypadTestActivity}: java.lang.IllegalStateException: entrée/sortie déséquilibrée –

+0

Je viens de modifier le code que vous pouvez vérifier maintenant. –