我正在设计我的第一个Android应用。
这个应用程序包含几个可以执行某些操作的Runnable。最初我使这个Runnable由一个Thread(每个Runnable的一个Thread)执行。每个Runnable也是Observable,因此它可以通知对Activity的更改。用户点击一个开始按钮,一个或多个Runnable启动,他们在执行期间通知gui,然后停止。一切正常。
第一个问题:这种方法是正确的吗?为了回答这个问题,请继续阅读。
我的应用程序中还需要另外两件事:
我已经看到我可以用AlarmManager和服务来做到这一点。
第二个问题:我需要一个可以异步管理多个Runnable的服务,所以当AlarmManager启动时,我要求此服务执行所请求的工作;我还将修改应用程序的第一部分:而不是Thread我将使用此服务,因此我可以确定执行不会停止。 我需要什么样的服务? IntentService可以做这个工作吗? 以这种方式进行是正确的吗?还有更好的解决方案吗?
你能举例说明我如何实现这一切吗?
我希望我能清楚地解释我的情况,否则我会尝试做得更好。
此致
答案 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