我需要什么样的服务?自定义IntentService?

时间:2013-01-24 12:57:12

标签: android service alarmmanager runnable intentservice

我正在设计我的第一个Android应用。

这个应用程序包含几个可以执行某些操作的Runnable。最初我使这个Runnable由一个Thread(每个Runnable的一个Thread)执行。每个Runnable也是Observable,因此它可以通知对Activity的更改。用户点击一个开始按钮,一个或多个Runnable启动,他们在执行期间通知gui,然后停止。一切正常。

第一个问题:这种方法是正确的吗?为了回答这个问题,请继续阅读。

我的应用程序中还需要另外两件事:

  1. 确保我的工作执行不会停止,即使用户离开我的应用程序做其他事情也是如此;
  2. 计划必须在后台启动和执行的Runnable的执行。示例:用户决定要在16:00每天执行“作业”。
  3. 我已经看到我可以用AlarmManager和服务来做到这一点。

    第二个问题:我需要一个可以异步管理多个Runnable的服务,所以当AlarmManager启动时,我要求此服务执行所请求的工作;我还将修改应用程序的第一部分:而不是Thread我将使用此服务,因此我可以确定执行不会停止。 我需要什么样的服务? IntentService可以做这个工作吗? 以这种方式进行是正确的吗?还有更好的解决方案吗?

    你能举例说明我如何实现这一切吗?

    我希望我能清楚地解释我的情况,否则我会尝试做得更好。

    此致

1 个答案:

答案 0 :(得分:0)

  

第一个问题:这种做法是正确的吗?

不,您应该在Runnable的{​​{1}}中实施并运行Thread

如果您不需要Service同时处理多个请求,IntentService将是您的最佳选择。如果您启动Service,即使启动它的Service转到后台或停止,它也会继续在后台运行。

Activity可以发送指示需要更新UI的广播。 Runnable应注册Activity以收听广播消息并相应地更新UI。

您可以使用BroadcastReceiver按计划安排执行作业。一种方法是安排AlarmManager通过运行相应的工作来发送由您AlarmManager接收的广播。

以下是结合所有内容的示例:

以下是IntentService

IntentService

这是public class MyIntentService extends IntentService { public static final String ACTION_START_JOB = "com.mycompany.myapplication.START_JOB"; public static final String ACTION_UPDATE_UI = "com.mycompany.myapplication.UPDATE_UI"; private final IBinder mBinder = new MyBinder(); // You can have as many Runnables as you want. Runnable run = new Runnable() { @Override public void run() { // Code to run in this Runnable. // If the code needs to notify an Activity // for a UI update, it will send a broadcast. Intent intent = new Intent(ACTION_UPDATE_UI); sendBroadcast(intent); } }; public MyIntentService() { super("MyIntentService"); } @Override public void onCreate() { // You need to register your BroadcastReceiver to listen // to broadcasts made by the AlarmManager. // The BroadcastReceiver will fire up your jobs when these // broadcasts are received. IntentFilter filter = new IntentFilter(ACTION_START_JOB); registerReceiver(jobBroadcastReceiver, filter); } @Override public void onDestroy() { // You should unregister the BroadcastReceiver when // the Service is destroyed because it's not needed // any more. unregisterReceiver(jobBroadcastReceiver); } /** * This method is called every time you start this service from your * Activity. You can Spawn as many threads with Runnables as you want here. * Keep in mind that your system have limited resources though. */ @Override protected void onHandleIntent(Intent intent) { Intent intentFireUp = new Intent(); intentFireUp.setAction(ACTION_START_JOB); PendingIntent pendingIntentFireUpRecording = PendingIntent .getBroadcast(MyIntentService.this, 0, intentFireUp, 0); AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Calendar cal = Calendar.getInstance(); int year = 2013, month = 5, day = 10, hourOfDay = 7, minute = 13, second = 0; cal.set(year, month, day, hourOfDay, minute, second); long startTime = cal.getTimeInMillis() + 5 * 60 * 1000; // starts 5 // minutes from // now long intervalMillis = 24 * 60 * 60 * 1000; // Repeat interval is 24 // hours (in milliseconds) // This alarm will send a broadcast with the ACTION_START_JOB action // daily // starting at the given date above. alarm.setRepeating(AlarmManager.RTC_WAKEUP, startTime, intervalMillis, pendingIntentFireUpRecording); // Here we spawn one Thread with a Runnable. // You can spawn as many threads as you want. // Don't overload your system though. new Thread(run).run(); } @Override public IBinder onBind(Intent intent) { return mBinder; } // Depending on your implementation, you may need to bind // to this Service to run one of its methods or access // some of its fields. In that case, you will need a Binder // like this one. public class MyBinder extends Binder { MyIntentService getService() { return MyIntentService.this; } } // Spawns a Thread with Runnable run when a broadcast message is received. // You may need different BroadcastReceivers that fire up different jobs. BroadcastReceiver jobBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { new Thread(run).run(); } }; }

Activity

不要忘记在public class MyActivity extends Activity { Service mService; boolean mBound = false; ToggleButton mButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton = (ToggleButton) findViewById(R.id.recordStartStop); mButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (mButton.isChecked()) { Intent intent = new Intent(MyActivity.this, MyIntentService.class); startService(intent); } } }); } @Override protected void onStart() { super.onStart(); } @Override protected void onResume() { super.onResume(); IntentFilter filter = new IntentFilter(MyIntentService.ACTION_UPDATE_UI); registerReceiver(uiUpdateBroadcastReceiver, filter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(uiUpdateBroadcastReceiver); } BroadcastReceiver uiUpdateBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Here goes the code to update your User Interface } }; ServiceConnection myServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mService = null; mBound = false; } // If you need @Override public void onServiceConnected(ComponentName name, IBinder service) { MyIntentService mService = ((MyBinder) service).getService(); mBound = true; } }; } 文件中添加Service定义:

AndroidManifest.xml