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>