Android запускает поток в сервисе каждые X секунд

Я хочу создать поток в службе Android, которая запускается каждые X секунд

В настоящее время я использую, но метод postdelayed, похоже, действительно задерживает мое приложение.

@Override public int onStartCommand(Intent intent, int flags, int startId){ super.onStartCommand(intent, flags, startId); startRepeatingTask(); return startId; } private final static int INTERVAL = 20000; //20 milliseconds Handler m_handler = new Handler(); Runnable m_handlerTask = new Runnable() { @Override public void run() { // this is bad m_handler.postDelayed(m_handlerTask, INTERVAL); } }; void startRepeatingTask() { m_handlerTask.run(); } void stopRepeatingTask() { m_handler.removeCallbacks(m_handlerTask); stopSelf(); } 

Я хочу сделать новый поток следующим образом:

  public void threadRun() { Thread triggerService = new Thread(new Runnable(){ public void run(){ Looper.prepare(); try{ //do stuff here? }catch(Exception ex){ System.out.println("Exception in triggerService Thread -- "+ex); }//end catch }//end run }, "aThread"); triggerService.start(); //perhaps do stuff here with a timer? timer1=new Timer(); timer1.scheduleAtFixedRate(new methodTODOSTUFF(), 0, INTERVAL); } 

Я не уверен, что лучший способ сделать фоновый поток для запуска с определенным интервалом, проницательность оценена!

Существует несколько альтернативных способов сделать это. Лично я предпочитаю использовать ScheduledExecutorService :

 ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5); // This schedule a runnable task every 2 minutes scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() { public void run() { doSomethingUseful(); } }, 0, 2, TimeUnit.MINUTES); 

Вот как я запускаю повторяющийся поток, так как вы увидите, что он проходит каждую секунду. Я не вижу отставания в этом методе.

 final Thread t = new Thread(new RepeatingThread()); t.start(); 

И класс:

 import android.os.Handler; public class RepeatingThread implements Runnable { private final Handler mHandler = new Handler(); public RepeatingThread() { } @Override public void run() { mHandler.postDelayed(this, 1000); } } 

MyService.java

 public class MyService extends Service { public static final int notify = 5000; //interval between two services(Here Service run every 5 seconds) int count = 0; //number of times service is display private Handler mHandler = new Handler(); //run on another Thread to avoid crash private Timer mTimer = null; //timer handling @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { if (mTimer != null) // Cancel if already existed mTimer.cancel(); else mTimer = new Timer(); //recreate new mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify); //Schedule task } @Override public void onDestroy() { super.onDestroy(); mTimer.cancel(); //For Cancel Timer Toast.makeText(this, "Service is Destroyed", Toast.LENGTH_SHORT).show(); } //class TimeDisplay for handling task class TimeDisplay extends TimerTask { @Override public void run() { // run on another thread mHandler.post(new Runnable() { @Override public void run() { // display toast Toast.makeText(MyService.this, "Service is running", Toast.LENGTH_SHORT).show(); } }); } } } 

MainActivity.java

 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService(new Intent(this, MyService.class)); //start service which is MyService.java } } 

Добавьте следующий код в AndroidManifest.xml

AndroidManifest.xml

 <service android:name=".MyService" android:enabled="true" android:exported="true"></service> 

Запуск runnable каждые несколько секунд будет иметь некоторое отставание независимо от того, как вы его runnable , нет? Я не понимаю, почему Handler не должен работать нормально.

Вы можете испытывать некоторые проблемы, хотя, поскольку у вас есть

 void startRepeatingTask() { m_handlerTask.run(); } 

Вместо этого вы должны использовать обработчик и сделать что-то вроде:

 void startRepeatingTask() { m_handler.post(m_handlerTask); } 

(В стороне, конвенция на Java должна использовать случай верблюда, а не змеиный случай. Таким образом, это должен быть mHandler, а не m_handler и т. Д. Просто говорю вам, потому что это может сделать ваш код более легким для чтения для некоторых.)