2015-09-29 3 views
3

Я попытался переопределить onBackPressed, чтобы не только завершить текущую деятельность, но и прервать поток, поскольку я вызываю намерение для следующего действия внутри. Когда я снова нажал, активность всплеска закончилась, но поток продолжал работать и вызывать намерение следующего действия. Теперь, когда я включаю прерывание потока в BackPressed, приложение падает, когда я нажимаю. Что я делаю не так?Как прервать поток onBackPressed без сбоев?

skipscreen.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View view) { 
      SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE); 
      savestate.edit().putBoolean("skip", true).apply(); 
      skip= true; 
      homeintent(); 
     } 
    }); 
    Thread splashthread = new Thread() { 
     @Override 
     public void run() { 
       try { 
        sleep(3000); 
        if (!skip) { homeintent();} 
       } catch (InterruptedException Interrupt) { 
        Interrupt.printStackTrace(); 
       } 
      } 
    }; 
    splashthread.start(); 
} 
private void homeintent() { 
    Intent i = new Intent(splash.this, home.class); 
    startActivity(i); 
    finish(); 
} 
@Override 
public void onBackPressed() { 
    splashthread.interrupt(); 
    finish(); 
    } 
} 

ОБНОВЛЕНО: (Это решение сработало для меня).

skipscreen.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View view) { 
      SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE); 
      savestate.edit().putBoolean("skip", true).apply(); 
      skip= true; 
      homeintent(); 
     } 
    }); 
    Thread splashthread = new Thread() { 
     @Override 
     public void run() { 
       try { 
        sleep(3000); 
        if (!skip) { homeintent();} 
       } catch (InterruptedException Interrupt) { 
        Interrupt.printStackTrace(); 
       } 
      } 
    }; 
    splashthread.start(); 
} 
private void homeintent() { 
    if (!ThreadInterrupted) { 
      Intent i = new Intent(splash.this, home.class); 
      startActivity(i); 
    } 
      finish(); 
} 
@Override 
public void onBackPressed() { 
     SharedPreferences savestate= getSharedPreferences("ThreadInterrupted", MODE_PRIVATE); 
     savestate.edit().putBoolean("ThreadInterrupted", true).apply(); 
     ThreadInterrupted = true; 
     homeintent(); 
    } 
} 
+0

вы попробуйте простую проверку нулевой в 'homeintent()', то 'если (splash.this! = NULL)'? – Droidekas

+0

Какое исключение вы получаете? можете ли вы опубликовать свой стек? –

+0

Ссылка 'spashthread' является локальной для onClickListener. Вам нужно назначить его глобальной ссылке и поместить проверку nullpointer, как сказал @Droidekas. – DeeV

ответ

1

Чтобы дать вам ответ succint, а также объяснить, как это сделать в будущем, взгляните на класс Handler и метод Handler.postDelayed().

private Handler homeIntenthandler; 
    @Override 
    protected void onCreate(){ 

    //other things 
     skipscreen.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View view) { 
       SharedPreferences savestate = getSharedPreferences("skip", MODE_PRIVATE); 
       savestate.edit().putBoolean("skip", true).apply(); 
       skip= true; 
       homeintent(); 
      } 
     }); 

//initialise handler and set timer; 
     homeIntenthandler= new Handler(); 
     homeIntenthandler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       homeintent(); 
      } 
     },3000); 
    } 
    } 
    private void homeintent() { 
     Intent i = new Intent(splash.this, home.class); 
     startActivity(i); 
     finish(); 
    } 
    @Override 
    public void onBackPressed() { 
     if(homeIntenthandler!=null) 
     homeIntenthandler.removeCallbacksAndMessages(null) 
     finish(); 
     } 
    } 

Handler.removeCallbacksAndMessages(null) на основе документации, предоставленной для same

+0

Считаете ли вы, что лучше использовать обработчик, а не Кстати, что вы думаете о обновленном коде? Точно? –

+0

Обработчик предназначен для таких целей. И да обновленный код будет работать. вы поддерживаете много нужного кода, как общие настройки и сохраненные состояния, которых можно избежать. – Droidekas

+0

Я думаю, что вы правы. Позвольте мне попробовать, и я вернусь к решение вопроса. –

1

Когда вы вызываете метод прерывания() в своем потоке, находясь во сне, вызывается InterruptedException.

Вы можете проверить погоду внутри нити она должна продолжать:

Thread splashthread = new Thread() { 
    @Override 
    public void run() { 
      while (shouldContinue) { 
        doSomeWork(); 
      } 
    } 
}; 

Вы можете изменить shouldContinue ложь в вашем onBackPressed методе:

@Override 
public void onBackPressed() { 
     shouldContinue = false; 
     finish(); 
} 
+0

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

+0

Нет необходимости использовать SharedPreferences. Можете ли вы разместить свой стек? –

+0

На самом деле, я просто решил это, изменив вашу идею в некоторых вещах.Я отправлю редактирование через секунду. –

0

Уди Я ответил на ваш вопрос. Но я призываю вас использовать TimerTask и Timer вместо Thread.

Timer timer; 
TimerTask timertask; 
timer = new Timer(); 
timertask = new TimerTask() { 
    @Override 
    public void run() { 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       homeintent();   
      } 
     }); 
    } 
}; 
timer.schedule(timertask, 3000); 

@Override 
public void onBackPressed() { 
    if(timertask!=null){ 
     timertask.cancel(); 
    } 
    if(timer!=null){ 
     timer.cancel(); 
    } 
    finish(); 
} 
+0

Это уже решена, но хорошая идея! –

+1

Таймер иногда не является хорошим выбором, так как андроид говорит: «Если есть текущая работа, это не влияет», что означает, что если цикл продолжается, таймер не отменяется до тех пор, пока цикл не завершит его выполнение. нить и размещение логической проверки внутри цикла, мы можем решить эту проблему. – penguin

0

Вы можете создать летучийboolean проверку, чтобы остановить нить прогрессировала, см следующий код:

private volatile boolean cancelled = false; 

Thread splashthread = new Thread() { 
    @Override 
    public void run() { 
      if (cancelled) { 
       return; // or handle this however you want 
      }else{ 
       // do what ever you want to do here 
      } 
     } 
}; 
splashthread.start(); 

И в onBackPressed сделать что-то вроде этого:

@Override 
public void onBackPressed() { 
    cancelled = true; 
    finish(); 
} 

ключевое слово volatile рекомендуется, потому что, как правило, th чтение выполнения отмены не обязательно будет тем же самым потоком, который отменяется. Маркировка boolean check as volatile гарантирует, что поток, проверяющий флаг, увидит текущее значение.

+0

Я использовал volatile boolean для обновленного решения (просто не публиковал весь код). Спасибо! –