tiempo studio programacion móviles metodo ejecutar desarrollo curso cierto cada aplicaciones android multithreading timer

studio - manual de programacion android pdf



Android ejecuta el hilo en servicio cada X segundos (4)

Quiero crear un hilo en un servicio de Android que se ejecuta cada X segundos

Actualmente estoy usando, pero el método post-retrasado parece realmente retrasar mi aplicación.

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

Quiero hacer un hilo nuevo como este:

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

No estoy seguro de que la mejor manera de hacer un hilo de fondo para ejecutar en un determinado intervalo, la comprensión apreciada.


Aquí es cómo ejecuto un hilo de repetición, ya que lo verá bucles cada 1 segundo. No veo retraso con este método.

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

Y la clase:

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


Comenzar un runnable cada pocos segundos va a tener un rezago sin importar la forma en que lo cortes, ¿no? No veo por qué un Handler no debería funcionar bien.

Sin embargo, es posible que experimente algunos problemas porque tiene

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

En su lugar, debe usar el controlador y hacer algo como:

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

(Por otro lado, la convención en Java es usar camel case, no snake case. Por lo tanto, debe ser mHandler, no m_handler, etc. Solo se lo digo porque puede hacer que su código sea más fácil de leer para algunos).


Hay varias formas alternativas de hacer esto. Personalmente, prefiero usar 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);


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

Agregue el siguiente código en AndroidManifest.xml

AndroidManifest.xml

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