如何以编程方式在android中重新启动服务?

时间:2016-03-23 19:33:26

标签: android

在Android中,我有一个包含不同活动和服务的应用程序。这些活动用于直接用户交互,用户可以在其中更改数据,更新数据,输入数据等。

应用程序还使用用户输入的数据(库存数据)运行(后台)服务。如果某些条件匹配,该服务定期检查股票价格(例如每12小时)并向用户发出通知。

但是,作为用户,我希望能够更改此服务的设置。我启动应用程序,并可以在应用程序的一个活动中输入更新间隔,该活动存储在SharedPreference中。例如,我可以更改该值,让服务每3小时检查一次库存数据。

我是否必须'重新启动'该服务?据我了解操作系统中的“服务”,该服务会在某些事件停止之前运行。但是,如果服务没有停止,服务不会“注意到”更新间隔已经改变!因此,在我的主要应用程序的活动中,我需要一些方法来“重启”服务,因此它会在3小时内检查股票价格,而不是在12小时内检查!

知道怎么做到这一点?谷歌搜索并没有真正帮助。也许我找错了关键字......?

4 个答案:

答案 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)来捕获它