0

Je crée un fil pour l'image de changement animée sur l'interface utilisateur programmée. Il sera interrompu pendant que le bouton cliquera, et définira une image fixe. Mais si setImage dans runOnUiThread se produit accidentellement après setImage dans onClick, ce sera la mauvaise image.Comment puis-je m'assurer de passer quelque part après l'interruption du fil?

Y at-il un moyen quelconque dans ce code peut s'assurer de passer quelque part après le retour de InterruptedException. (Je ne veux plus de délai sur le fil de l'interface utilisateur)

Merci de nous aider!

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

// une fois onClick

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

Edit: Je réécris cette partie comme l'a suggéré.

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

// commencent

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

// fin onClick

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

puis travailler parfois parfois pas le problème, fonctionne pas alors que "doInBackground" est pas dans la bande de roulement du sommeil! Il ne va à onCancel mais annule pas vraiment, je suis faux avec isCanceled() pics Journaux comme suivre enter image description here

Répondre

0

Vous pouvez être mieux d'utiliser un AsyncTask pour ce type de travail de fond, car il vous permet d'effectuer séparément Opérations d'interface utilisateur selon que la tâche se déroule ou est interrompue.

Par exemple, dans cet exemple AsyncTask ci-dessous:

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

Si l'opération d'arrière-plan réussit, vous actualiserait votre interface utilisateur avec la nouvelle image dans onPostExecute(), qui fonctionne sur le thread d'interface utilisateur. Si vous interrompez le thread, par exemple avec un clic sur un bouton, vous annulez la tâche et à la place de onPostExecute(), la méthode onCancelled() sera appelée à la place. Cette méthode s'exécute également sur le thread d'interface utilisateur et vous pouvez simplement mettre à jour votre interface utilisateur avec l'image par défaut.

+0

hmmm .. sorte du même problème avec AsyncTask, et ce dont j'ai besoin dans AsyncTask onProgressUpdate pas sur PostExecute, il va se terminer le thread. Le problème provient de void ImageViewAnimatedChange que j'ai fait, ceci utilise anim_in et anim_out dedans, donc ça arrive encore après setImage (ceci sans anim) –