2010-09-12 7 views
4

Привет всем - этот код может быть немного грязным в том, как я пытаюсь очистить обработчик, поскольку я пытался отслеживать, где происходит авария ...Как убить поток и обработчик перед тем, как перейти к новому действию

у меня есть диалоговое деятельность, которая показывает ввод пароля с ProgressBar анимируемой нитью и обработчиком ...

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

public class RMO_Dialog extends Activity { 
    private ProgressBar progbar; 
    private Button dialogOK; 
    private EditText dialogPass; 
    private SharedPreferences prefs; 
    private String pass; 
    private int increment=10; 
    private Thread background; 

    private Boolean commCalled=false; 

    public void callCommunications(){ 
     progbar.setVisibility(0); 
     progbar.setProgress(0); 
     background.stop(); 
     Toast.makeText(getApplicationContext(), "Call communication should happen once.", Toast.LENGTH_LONG).show(); 
//  Intent i = new Intent(); 
//  i.setClass(RMO_Dialog.this, RMO_Comm.class); 
//  i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
//  startActivity(i); 
//   finish(); 
    } 

    public void buzzUser(){ 

     Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
     int dot = 200; 
     int dash = 500; 
     int short_gap = 200; 
     int medium_gap = 500; 
     int long_gap = 1000; 
     long[] pattern = {0,dot, short_gap, dot, short_gap, dot, medium_gap, dash, short_gap, dash, short_gap, dash, medium_gap, dot, short_gap, 
       dot, short_gap, dot, long_gap}; 

     v.vibrate(pattern, -1); 


    } 

    public void killCountdown(){ 
     progbar.setVisibility(0); 
     progbar.setProgress(0); 
     background.stop(); 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.dialogpassword); 

     buzzUser(); 

     prefs = this.getSharedPreferences("RMO", MODE_WORLD_READABLE); 
     pass = prefs.getString("password", ""); 

     dialogOK = (Button) findViewById(R.id.dialogOK); 
     dialogPass = (EditText) findViewById(R.id.dialogPass); 
     progbar = (ProgressBar) findViewById(R.id.progress); 

     progbar.setProgress(0); 

     background = new Thread(new Runnable(){ 
      @Override 
      public void run() { 
       try{ 
        while(progbar.getProgress()<=progbar.getMax()){ 
         Thread.sleep(300); 
         progressHandler.sendMessage(progressHandler.obtainMessage()); 
        } 
       }catch(java.lang.InterruptedException e){ 
        Toast.makeText(getApplicationContext(), "Error thrown.", Toast.LENGTH_LONG).show(); 
       } 

      } 

     }); 
     background.start(); 

     dialogOK.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if(dialogPass.getText().toString().equals(pass.toString())){ 
        killCountdown(); 
        Toast.makeText(getApplicationContext(), "Guardian Angel next alert has been disengaged.", Toast.LENGTH_LONG).show(); 
        Intent intent = new Intent(); 
        intent.setClass(RMO_Dialog.this, RMO.class); 
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
        startActivity(intent); 
        finish(); 
       }else{ 
        callCommunications(); 
       } 
      } 
     }); 



    } 

    Handler progressHandler = new Handler(){ 
     public void handleMessage(Message msg){ 
      progbar.incrementProgressBy(increment); 
      if(progbar.getProgress()==progbar.getMax()){ 
       Toast.makeText(getApplicationContext(), "commcalled: "+ commCalled, Toast.LENGTH_LONG).show(); 
       if(commCalled==false){ 
        commCalled=true; 
        callCommunications(); 
       } 

      } 
     } 
    }; 
} 
+0

Я исправил ваше форматирование немного, не забудьте выбрать свой код и нажать кнопку * форматирования кода * (101010) ... вы также можете отформатировать свой код после отправки вопроса, нажав * * редактируйте ** под вопросом. – Kiril

ответ

7

Thread.stop is deprecated call, вместо этого вы должны использовать метод Thread.interrupt.

public void killCountdown(int waitTime){ 
    progbar.setVisibility(0); 
    progbar.setProgress(0); 
    // deprecated: background.stop(); 
    background.interrupt(); // <-- OK 
    background.join(waitTime); // optionally wait for the thread to exit 
} 

Thread.Interrupt вызовет ThreadInterruptedException следующий раз, когда ваш поток блоков или спит, и вы уже обработки в вашем теле нити, так что это хорошо. Кроме того, вы можете включить флаг volatile, который позволит вам остановить поток, если он не блокирует или не спят, но это необязательно.

+0

Хорошее объяснение, особенно для исключения, которое я не обрабатывал в своем приложении для Android. Вы помогли мне понять спасибо! – Zonata

+0

@ Zonata отлично! Кроме того, не забудьте принять вопрос, который наилучшим образом разрешил вашу проблему, нажав на галочку слева (только под голосами). – Kiril

+0

Lirik - я бы, но это не мой вопрос;) – Zonata

2

Вы можете использовать экземпляр AsyncTask вместо выполняемого и обработчика.

Если вам нужно отменить экземпляр AsycnTask, просто вызовите .cancel(true) на ссылку на объект AsyncTask. Это позаботится об фоновом методе (doInBackground()) и обновлении прогресса (onProgressUpdate()).

Я обычно нахожу AsyncTask более простым в использовании, чем пытаться самостоятельно обрабатывать все детали.

Итак, внутри RMO_Dialog используйте вызов execute() на экземпляре класса, который вы создаете, который расширяет AsyncTask.

public class RMO_Dialog extends Activity { 

    ... 
    // Get ref to your bg task for easily cancellation if needed 
    PassWordEntry background = new PassWordEntry(); 
    // Start bg task 
    background.execute([PARAMS]); 
    ... 
    // Cancel task 
    background.cancel(true); 
    ... 

    // AsyncTask lets you encapsulate both your runnable and handler in it 
    private static class PassWordEntry() extends AsyncTask<[PARAMS], [PROGRESS], [RESULT]> { 
     protected [RESULT] doInBackground() { 
      ... // Runnable stuff here 
      return [RESULT]; 
     } 

     protected void onProgressUpdate([PROGRESS]... progress) { 
      ... // progressHandler stuff here 
     } 

     protected void onPostExecute([RESULT]) {   
      // Clean up return data when all done w BG here 
     } 
    } 

}