學習如何每隔一段時間定時重複執行任務
阿新 • • 發佈:2019-01-27
學習了定時執行任務功能。並寫了個demo學習研究下。
參考blog:
1. 通過Service和BroadcastReceiver實現
寫一個Service執行定時發廣播操作
public class AlarmService extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { //寫一個BroadcastReceiver接收廣播啟動ServiceTODO: 16/3/28 如果執行費時操作,可以新起執行緒,但是覺得執行緒太多不好 // new Thread(new Runnable() { // @Override // public void run() { // } // }).start(); Log.e("test", "這是一條測試資訊"); AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); int minute = 1000; longtriggerAtTime = SystemClock.elapsedRealtime() + minute; Intent i = new Intent(this, AlarmReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); return super.onStartCommand(intent, flags, startId); } }
public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(context, AlarmService.class); context.startService(i); } }最後在Activity中實現迴圈。
/** * 這個Alarm的迴圈只能給Service用 * Activity啟動Service,Service傳送廣播,廣播接收器接收廣播並啟動Service,Service再次傳送廣播,如此重複 */ public class AlarmActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_alarm); Intent i = new Intent(this, AlarmService.class); startService(i); } @Override protected void onDestroy() { super.onDestroy(); Intent i = new Intent(this, AlarmService.class); stopService(i); } }最後,假如需要對UI進行操作,完全可以將BroadcastReceiver寫在Activity中,來實現定時的UI操作。
一直啟動Service我不覺得是一個好的解決方案,個人不喜歡用。
2. 通過Handler和Runnable實現迴圈
/** * 通過handler的post方法使用runnable,在runnable中使用handler的post方法post當前runnable,如此迴圈。 */ public class HandlerActivity extends AppCompatActivity { private TextView tvNumber; private static int number = 0; private Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { number++; tvNumber.setText("" + number); //延時1秒post handler.postDelayed(this, 1000); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); tvNumber = (TextView) findViewById(R.id.tvNum01); findViewById(R.id.btnStart01).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startHandleLoop(); } }); findViewById(R.id.btnStop01).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { stopHandleLoop(); } }); } /** * 開始迴圈 */ private void startHandleLoop(){ //延時1秒post handler.postDelayed(runnable, 1000); } /** * 停止迴圈 */ private void stopHandleLoop(){ handler.removeCallbacks(runnable); } }3. 通過new一個無限迴圈的執行緒,設定sleep實現迴圈
/** * 通過新建一個執行緒,無限迴圈,並設定sleep時間,實現每隔一秒重新整理的功能。 */ public class SleepActivity extends AppCompatActivity { private static int number = 0; private TextView tvNumber; private Handler handler3 = new Handler(){ @Override public void handleMessage(Message msg) { number++; tvNumber.setText("" + number); super.handleMessage(msg); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sleep); tvNumber = (TextView) findViewById(R.id.tvNum02); findViewById(R.id.btnStart02).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { new Thread(new LoopRnuable()).start(); } }); } public class LoopRnuable implements Runnable{ @Override public void run() { while (true) { try { Thread.sleep(1000); Message msg = new Message(); msg.what = 1; handler3.sendMessage(msg); } catch (InterruptedException e) { e.printStackTrace(); } } } } }4. 通過Timer實現重複迴圈
/** * 通過Timer的schedule方法使用TimerTask,TimerTask的內容是Handler傳送訊息。 * 為啥用Handler呢,因為UI變化只能在UI執行緒~~ */ public class TimerActivity extends AppCompatActivity { private static int number = 0; private TextView tvNumber; private Timer timer; private TimerTask task = new TimerTask() { @Override public void run() { //TODO 這裡可以執行定時非UI操作 Message message = new Message(); message.what = 1; handler.sendMessage(message); } }; /** * 處理UI操作 */ private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); number++; tvNumber.setText("" + number); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_timer); tvNumber = (TextView) findViewById(R.id.tvNum03); timer = new Timer(); findViewById(R.id.btnStart03).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startTimmerLoop(); } }); findViewById(R.id.btnStop03).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { stopTimerLoop(); } }); } /** * TODO 當timer被stop之後再次start會報錯 timer is canceled */ private void startTimmerLoop() { timer.schedule(task, 1000, 1000);//第二個引數是等待一秒後執行schedule,第三個引數是每隔一秒重複執行一次 } private void stopTimerLoop() { timer.cancel(); } }
大多分析都用註釋的方式寫在程式碼中了~