Как я могу убедиться, что где-то прошел после того, как поток был прерван?

Я создаю поток для анимированного изменения изображения в пользовательском интерфейсе по расписанию. Это будет прервано при нажатии кнопки и установит фиксированное изображение. Но если setImage в runOnUiThread случайно произойдет после setImage в onClick, это будет неправильное изображение.

Есть ли способ в этом коде убедиться, что он где-то проходит после возврата из InterruptedException. (Я больше не хочу задержек в потоке пользовательского интерфейса)

Пожалуйста, помогите спасибо!

    thread = new Thread(){
        @Override
        public void run() {
            while(!this.isInterrupted()){
                for(int i=0; i<imageList.size(); i++){
                    if(getActivity()==null) return;
                    getActivity().runOnUiThread(new Runnable() {
                        public void run() {
                            ImageViewAnimatedChange(getActivity().getApplication(),
                                        imgFunction, imageList.get(j), 0);
                        }
                    });
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        Log.e(TAG, e.toString());
                        return;
                    }
                }
            }
        }
    };

// один раз по клику

                        if(thread!=null) {
                            thread.interrupt(); // catch interruptException
                            thread = null;
                            imgFunction.setImageResource(R.drawable.selector);
                        }

Изменить: я переписываю эту часть, как было предложено.

public class asyncTask extends AsyncTask<String, String, String>{
    @Override
    protected String doInBackground(String... params) {
        Log.d(TAG, "doInBackground");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Log.w(TAG, e.toString());
            return null;
        }

        final List<Bitmap> imageList = getImageList();
        if(imageList.isEmpty()) return null;
        Log.d(TAG, "start while ");

        while(!isCancelled()){
            Log.d(TAG, "while:" +Boolean.toString(isCancelled()));

            for(int i=0; i<imageList.size()+1; i++){
                final int j=i;
                Log.d(TAG, "for" + Integer.toString(j));

                if (j == imageList.size())
                    publishProgress(“ok”);
                else
                    publishProgress(Integer.toString(i));

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Log.w(TAG, e.toString());
                    return null;
                }
            }
        }
        Log.d(TAG, "while end");
        return null;
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        QUtil.logE(TAG, "onPostExecute");
        imgFunction.setImageResource(R.drawable.selector);
    }

    @Override
    protected void onProgressUpdate(String... value) {
        super.onProgressUpdate(value);
        Log.d(TAG, "onProgressUpdate" + value[0]);
        if(getActivity()==null || isCancelled()) return;
        if(value[0]==“ok”)
            ImageViewAnimatedChange(getActivity().getApplication(),
                    imgFunction, null, R.drawable.selector);
        else
            ImageViewAnimatedChange(getActivity().getApplication(),
                    imgFunction, getImageList().get(Integer.parseInt(value[0])), 0);
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
        Log.e(TAG, "onCancelled");
        try {
            Thread.sleep(60);
        } catch (InterruptedException e) {
            Log.w(TAG, e.toString());
        }
        imgFunction.setImageResource(R.drawable.selector);
    }
}

//Начало

iftttAsyncTask = new IftttAsyncTask().execute("");

// конец по клику

if(asyncTask!=null) {
                            asyncTask.cancel(true); // catch interruptException
                            threadIfttt = null;
                        }

то иногда работает иногда не работает, не работает пока "doInBackground" не в спящем протекторе! Это действительно произошло в onCancel, но на самом деле не было отменено, я получил false с помощью isCanceled() Записывает фотографии следующим образом < img src="https://i.stack.imgur.com/9x09N.png" alt="введите здесь описание изображения">


person Bubble.C    schedule 12.05.2016    source источник


Ответы (1)


Возможно, вам лучше использовать AsyncTask для этого типа. фоновой работы, поскольку он позволяет выполнять отдельные операции пользовательского интерфейса в зависимости от того, выполняется задача или прерывается.

Например, в этом примере AsyncTask ниже:

public class TestTask extends AsyncTask<String, Void, String> {

    protected String doInBackground(String... args) {

        String input = args[0];
        String output = "simulated return value";

        return output;
    }

    protected void onPostExecute(String result) {
        //if your background operation succeeds, you 
        //would update your image here
    }

    protected void onCancelled() {
       //if your task is cancelled, update your UI with the
       //default image here
    }
}

Если фоновая операция завершится успешно, вы обновите свой пользовательский интерфейс новым изображением в onPostExecute(), которое выполняется в потоке пользовательского интерфейса. Если вы прервете поток, например, нажатием кнопки, вы отмените задачу, и вместо onPostExecute() будет вызван метод onCancelled(). Этот метод также работает в потоке пользовательского интерфейса, и вы можете просто обновить свой пользовательский интерфейс с изображением по умолчанию.

person NoChinDeluxe    schedule 12.05.2016
comment
хммм.. такая же проблема с AsyncTask, и что мне нужно в AsyncTask onProgressUpdate не onPostExecute, это завершит поток while. Проблема возникает из-за того, что я сделал void ImageViewAnimatedChange, в нем используются anim_in и anim_out, поэтому это все еще происходит после того, как я установилImage (это без анимации) - person Bubble.C; 13.05.2016