Android — Как остановить предыдущее выполнение службы перед ее перезапуском?

#android #service #timer #preferenceactivity

#Android #Обслуживание #таймер #preferenceactivity

Вопрос:

Я пытаюсь запустить службу из моего PreferenceActivity. Я хочу запускать службу при каждом onPreferenceChangeListenr.

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

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

Вот мой PreferenceActivity's код:-

 public class Preferences extends PreferenceActivity
{
private Button button;
ListPreference lp;
private Context context;
private long duration;

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);
    context = this;
    lp = (ListPreference)findPreference("autoduration");
    final Intent intent = new Intent(context, BackService.class);
    lp.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
    {
        public boolean onPreferenceChange(Preference preference, Object newValue)
        {
            String newSelection = newValue.toString();
            int index = lp.findIndexOfValue(newSelection);
            stopService(intent);
            if(index==0)
            {
                duration = 15000;
            }
            else if(index==1)
            {
               duration = 12000;
            }
            else if(index==2)
            {
                duration = 10000;
            }
            else if(index==3)
            {
                IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
                filter.addAction(Intent.ACTION_SCREEN_OFF);
                BroadcastReceiver receiver = new ScreenReceiver();
                registerReceiver(receiver, filter);
            }
            intent.putExtra("duration", duration);
            startService(intent);
            return true;
        }
    });


}
@Override
public void onDestroy()
{
    super.onDestroy();
    unregisterReceiver(receiver);
}
}
  

И это мой сервисный код, на который должна повлиять моя PreferenceActivity. :-

 private static Timer myTimer = new Timer();
public static final String TAG = "BackService";
private MainTask mainTask = new MainTask();    

 public void onStart(Intent intent, int startId)
    {
        Long duration = intent.getLongExtra("duration", 7000);
        startServices(duration);
    }

public void startServices(Long dur)
    {
        myTimer.scheduleAtFixedRate(mainTask,0,dur);
    }
private class MainTask extends TimerTask
    {
        @Override
        public void run() {
            Log.e(TAG, "I am HERE");
        }
    }
  

Вот мой BroadcastReceiver :-

 public class ScreenReceiver extends BroadcastReceiver {
public static boolean screenOn = true;
private static final String TAG = "ScreenReceiver";

@Override
public void onReceive(Context context, Intent intent)
{
    if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
    {
        Log.e(TAG, "I am receiver");
    }
}
}
  

Я не знаю, что я делаю не так, поэтому, пожалуйста, помогите!!

Спасибо

Ответ №1:

Возможно, ваша служба перезапускается без вашего ведома. Однако у вас проблема, потому что в этом случае myTimer не сносится. Вам нужно реализовать onDestroy метод в вашем классе, определить, останавливается ли ваша служба (потому что где-то вызывается stopSelf или Context.stopService ).

Если это так, вам следует удалить static модификатор из myTimer переменной, чтобы он не зависал между запусками службы и в onDestroy методе, который вам нужно вызвать myTimer.cancel() , чтобы остановить его, поскольку в противном случае он будет просто зависать, и у вас не будет никакой ссылки на него, чтобы отменить его.

В вашем startServices методе добавьте следующее перед вызовом myTimer.scheduleAtFixedRate :

 mainTask.cancel();
mainTask = new MainTask();
  

Комментарии:

1. он по-прежнему ведет себя так же. 🙁

2. Тогда другая возможность заключается в том, что это результат статичности объекта Timer. Я отредактирую свой ответ, чтобы объяснить, почему это может быть проблемой.

3. да, теперь она работает. 🙂 вы были правы, я не отменял объект mytimer . Теперь я вызываю MyTimer.cancel() в onDestroy(), и это работает так, как должно. Большое спасибо. 🙂

4. извините, что снова беспокою вас, но прямо сейчас я столкнулся с очень маленькой проблемой и не хочу запускать новый поток для решения этой небольшой проблемы. Я отредактировал свой код. Не могли бы вы, пожалуйста, взглянуть? и скажите мне, почему я не могу зарегистрировать свой BroadcastReceiver в случае (index==3) .