线程中断后如何确保通过某个地方?

Posted

技术标签:

【中文标题】线程中断后如何确保通过某个地方?【英文标题】:How can I make sure go through somewhere after thread be interrupted? 【发布时间】:2016-09-08 09:11:25 【问题描述】:

我为计划的 ui 上的动画更改图像创建了一个线程。按钮单击时会中断,并设置固定图像。 但是如果runOnUiThread中的setImage在onClick中的setImage之后不小心发生了,那就是错误的图像了。

这段代码中是否有任何方法可以确保在从 InterruptedException 返回后通过某个地方。 (我不希望 ui 线程有更多延迟)

请帮忙谢谢!

    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 但并没有真正取消,我用 isCanceled() 弄错了 记录图片如下

【问题讨论】:

【参考方案1】:

对于这种类型的后台工作,您最好使用AsyncTask,因为它允许您根据任务是继续还是中断来执行单独的 UI 操作。

例如,在下面这个示例中的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
    

如果后台操作成功,您将使用在 UI 线程上运行的 onPostExecute() 中的新图像更新您的 UI。如果您中断线程,例如单击按钮,您将取消任务,而不是 onPostExecute(),而是调用 onCancelled() 方法。这个方法也在 UI 线程上运行,你可以在那里用默认图像更新你的 UI。

【讨论】:

hmmm .. AsyncTask 有同样的问题,我在 AsyncTask onProgressUpdate 而不是 onPostExecute 中需要什么,它将结束 while 线程。问题发生在我所做的 void ImageViewAnimatedChange 中,其中使用了 anim_in 和 anim_out,所以在我 setImage(this without anim) 后仍然会发生

以上是关于线程中断后如何确保通过某个地方?的主要内容,如果未能解决你的问题,请参考以下文章

线程中断线程让步线程睡眠线程合并

并发基础 java线程的中断机制

详细分析Java中断机制-转载

中断线程

线程中断

学多线程的看过来,带你学习多线程中断机制