Activity
public class MainActivity extends ListActivity { private int intentNumber = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); List<String> mData = new ArrayList<String>(Arrays.asList("启动一个新的工作线程", "启动一个前台服务", // "设置一次性定时后台服务", "设置一个周期性执行的定时服务", "取消AlarmManager的定时服务")); ListAdapter mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mData); setListAdapter(mAdapter); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { switch (position) { case 0: intentNumber++; Intent intent = new Intent(this, MyIntentService.class); Bundle bundle = new Bundle(); bundle.putInt("intentNumber", intentNumber); intent.putExtras(bundle); startService(intent);//每次启动都会新建一个工作线程,但始终只有一个IntentService实例 break; case 1: startService(new Intent(this, ForegroundService.class)); break; case 2: Intent intent2 = new Intent(this, LongRunningService.class); intent2.putExtra("type", "onceAlarm"); startService(intent2); break; case 3: Intent intent3 = new Intent(this, LongRunningService.class); intent3.putExtra("type", "repeatAlarm"); startService(intent3); break; case 4: ((AlarmManager) getSystemService(ALARM_SERVICE)).cancel(PendingIntent.getBroadcast(this, 0, new Intent(this, AlarmReceiver.class), 0)); break; } } }
IntentService
/** 所有请求的Intent记录会按顺序加入到【队列】中并按顺序【异步】执行,并且每次只会执行【一个】工作线程,当所有任务执行完后IntentService会【自动】停止 */ public class MyIntentService extends IntentService { public MyIntentService() { //必须实现父类的构造方法 super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) {//注意,因为这里是异步操作,所以这里不能直接使用Toast。 int intentNumber = intent.getExtras().getInt("intentNumber");//根据Intent中携带的参数不同执行不同的任务 Log.i("bqt", "第" + intentNumber + "个工作线程启动了"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Log.i("bqt", "第" + intentNumber + "个工作线程完成了"); } @Override public IBinder onBind(Intent intent) { Log.i("bqt", "onBind"); return super.onBind(intent); } @Override public void onCreate() { Log.i("bqt", "onCreate"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("bqt", "onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public void setIntentRedelivery(boolean enabled) { super.setIntentRedelivery(enabled); Log.i("bqt", "setIntentRedelivery"); } @Override public void onDestroy() { Log.i("bqt", "onDestroy"); super.onDestroy(); } }
前台服务
/**所谓的前台服务就是状态栏显示的Notification,可以让Service没那么容易被系统杀死 */ public class ForegroundService extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Notification.Builder localBuilder = new Notification.Builder(this).setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0)) .setAutoCancel(false).setSmallIcon(R.drawable.ic_launcher).setTicker("Foreground Service Start").setContentTitle("前台服务").setContentText("正在运行..."); startForeground(1, localBuilder.build()); } @Override public void onDestroy() { Log.i("bqt", "onDestroy"); super.onDestroy(); } }
定时后台服务
public class LongRunningService extends Service { public static final int anHour = 3 * 1000;//设置每隔3秒钟打印一次时间 @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { //定时任务为:发送一条广播。在收到广播后启动本服务,本服务启动后又发送一条广播…… PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, AlarmReceiver.class), 0); //使用【警报、闹铃】服务设置定时任务。CPU一旦休眠(比如关机状态),Timer中的定时任务就无法运行;而Alarm具有唤醒CPU的功能。 AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); long triggerAtTime;//闹钟(首次)执行时间 String type = intent.getStringExtra("type"); if ("onceAlarm".equals(type)) {//)//设置在triggerAtTime时间启动由operation参数指定的组件。该方法用于设置一次性闹钟 triggerAtTime = SystemClock.elapsedRealtime() + anHour;//相对于系统启动时间,Returns milliseconds since boot, including time spent in sleep. manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent); } else if ("repeatAlarm".equals(type)) {//设置一个周期性执行的定时服务,参数表示首次执行时间和间隔时间 triggerAtTime = System.currentTimeMillis() + anHour;//相对于1970……绝对时间,Returns milliseconds since boot, including time spent in sleep. manager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime, anHour, pendingIntent); } else if ("work".equals(type)) { //开辟一条线程,用来执行具体的定时逻辑操作 new Thread(new Runnable() { @Override public void run() { Log.i("bqt", new SimpleDateFormat("yyyy.MM.dd HH-mm-ss", Locale.getDefault()).format(new Date())); } }).start(); } /**type有五个可选值: AlarmManager.ELAPSED_REALTIME 闹钟在睡眠状态下不可用,如果在系统休眠时闹钟触发,它将不会被传递,直到下一次设备唤醒;使用相对系统启动开始的时间 AlarmManager.ELAPSED_REALTIME_WAKEUP 闹钟在手机睡眠状态下会唤醒系统并执行提示功能,使用相对时间 AlarmManager.RTC 闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间 AlarmManager.RTC_WAKEUP 表示闹钟在睡眠状态下会唤醒系统并执行提示功能,使用绝对时间 AlarmManager.POWER_OFF_WAKEUP 表示闹钟在手机【关机】状态下也能正常进行提示功能,用绝对时间,但某些版本并不支持! */ return super.onStartCommand(intent, flags, startId); } }
广播接收者
public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "定时任务已经执行了", Toast.LENGTH_SHORT).show(); Intent workIntent = new Intent(context, LongRunningService.class); workIntent.putExtra("type", "work"); context.startService(workIntent); } }
清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.bqt.intentservice" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="17" android:targetSdkVersion="21" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyIntentService" android:exported="false" > <intent-filter> <action android:name="com.test.intentservice" /> </intent-filter> </service> <service android:name=".ForegroundService" /> <service android:name=".LongRunningService" /> <receiver android:name=".AlarmReceiver" /> </application> </manifest>
时间: 2024-10-16 17:17:08