如何确保我的输入流在活动退出(Android)时关闭?

时间:2017-04-13 13:59:24

标签: android inputstream

当我的活动被创建时,我启动了一个线程,它开始持续按键盘按下(while(true)) ...这很有效,但是当我点击后输入流不被关闭而下一个时间我打开那个活动反应是零星的,不可靠的。

我的代码

@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(),但这些也不能保证被调用。

1 个答案:

答案 0 :(得分:0)

在您的活动类中添加onPause: -

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