学习了定时执行任务功能。并写了个demo学习研究下。
demo地址:http://download.csdn.net/detail/violetjack0808/9474145
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) { // TODO: 16/3/28 如果执行费时操作,可以新起线程,但是觉得线程太多不好 // new Thread(new Runnable() { // @Override // public void run() { // } // }).start(); Log.e("test", "这是一条测试信息"); AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); int minute = 1000; long triggerAtTime = 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); } }写一个BroadcastReceiver接收广播启动Service
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(); } }
大多分析都用注释的方式写在代码中了~