在Android中,我有一个包含不同活动和服务的应用程序。这些活动用于直接用户交互,用户可以在其中更改数据,更新数据,输入数据等。
应用程序还使用用户输入的数据(库存数据)运行(后台)服务。如果某些条件匹配,该服务定期检查股票价格(例如每12小时)并向用户发出通知。
但是,作为用户,我希望能够更改此服务的设置。我启动应用程序,并可以在应用程序的一个活动中输入更新间隔,该活动存储在SharedPreference
中。例如,我可以更改该值,让服务每3小时检查一次库存数据。
我是否必须'重新启动'该服务?据我了解操作系统中的“服务”,该服务会在某些事件停止之前运行。但是,如果服务没有停止,服务不会“注意到”更新间隔已经改变!因此,在我的主要应用程序的活动中,我需要一些方法来“重启”服务,因此它会在3小时内检查股票价格,而不是在12小时内检查!
知道怎么做到这一点?谷歌搜索并没有真正帮助。也许我找错了关键字......?
答案 0 :(得分:1)
使活动与服务通信的标准方法是使用AIDL的接口。 在AIDL中,您可以定义对服务的调用以及来自服务的回调。 有了它,该服务就像你可以调用方法的另一个类。有documentation here。
答案 1 :(得分:0)
一个简单的解决方案,因为您的服务在与您的应用程序相同的过程中运行,即在您的服务的OnSharedPreferenceChangeListener
方法中将onCreate
注册到与该活动相同的SharedPreferences
更新
然后,每次在您的服务中调用偏好更改onSharedPreferenceChanged(...)
时。您可以检查更新间隔首选项何时更改并相应地更新服务,而无需重新启动它。
答案 2 :(得分:0)
您可以使用Intent
发送到您的服务数据和操作。只需在Service
类中创建一个BroadcastReceiver
并将其注册到服务生命周期。现在,您可以更新服务中的值。一个例子:
您的服务
public class CustomService extends Service {
private BroadcastReceiver mReceiver;
@Override
public void onCreate() {
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// get the action from the intent
}
}
registerReceiver(wifiChangedState, new IntentFilter("CUSTOM");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
unregisterReceiver(mReceiver);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
现在,您可以创建自定义Intent
,以便Activity
可以接收并应用的BroadcastReceiver
发送操作。
答案 3 :(得分:0)
您可以使用自定义Service
创建Binder public class CustomService extends Service {
public IBinder onBind(Intent intent) {
return new CustomBinder(this);
}
public void doSomething(){
//Do somthing with service
}
}
public class CustomBinder extends Binder {
private CustomService mCustomService;
public MyBinder(CustomService service) {
mCustomService = service;
}
public CustomService getCustomService() {
return mCustomService;
}
}
此时您可以通过ServiceConnection绑定到CustomService(由于我的声誉,我无法链接ServiceConnection ......)实现您在服务中需要的所有功能。
Intent customServiceIntent = new Intent(context, CustomService.class);
context.bindService(
customServiceIntent,
mServiceConnection,
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
);
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
CustomBinder binder = (CustomBinder) service;
binder.getCustomService().doSomething();
}
public void onServiceDisconnected(ComponentName name) {
/* Do something when service disconnect */
}
};
此方法不适用于进程上的服务。 (倍数应用程序)看看AIDL文件来实现这一点。
为确保“工作”能够及时执行,您可以使用AlarmManager启动服务。
/* define when intent will be send */
long wakeUpTimeInMillis = Calendar.getInstance().getTimeInMillis() + 1000 * 30 ; // now + 30second
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, CustomService.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_NO_CREATE);
alarmManager.set(AlarmManager.RTC_WAKEUP, wakeUpTimeInMillis, pending);
您可以向intent
添加一些额外的参数,并通过覆盖CustomService中的onStartCommand(Intent intent, int flags, int startId)
来捕获它