Android服务重新创建

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android服务重新创建相关的知识,希望对你有一定的参考价值。

我正在编写一个应用程序,以便在首选日期和时间通知用户(假设每个月的第一天)

我搜索并阅读了一些帖子,建议我使用AlarmManagerBroadcastReceiverService

它的工作原理,但Service似乎创建了多次,Notification随机显示。我添加了log.i()来跟踪它。它收到了BOOT_RECEIVED或首先启动了应用程序的Service,初始服务和创建服务被记录,通知正确和正常显示。一段时间后,再次创建服务而没有销毁日志,并再次显示通知。这是正常的吗?

日志

02-23 20:17:15.235: I/CMP(19210): Init Service
02-23 20:17:15.235: I/CMP(19210): Start Service
02-23 20:17:15.285: I/CMP(19210): Create Service
02-23 20:17:15.295: I/CMP(19210): 10157
02-23 20:17:15.295: I/CMP(19210): ON START COMMAND
02-23 20:17:25.785: I/CMP(19210): action_notify
02-23 20:21:12.415: I/CMP(23666): Create Service
02-23 20:21:12.515: I/CMP(23666): 10157
02-23 20:21:12.525: I/CMP(23666): ON START COMMAND
02-23 20:21:22.515: I/CMP(23666): action_notify

服务类

public class AppService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("CMP", "Create Service");
        Utility.scheduleNotification(this.getBaseContext());
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        Log.i("CMP", "ON START COMMAND");
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("CMP", "Destroy Service");
        Utility.cancelScheduleNotification(getBaseContext());
    }
}

广播接收器

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            Common.setSettings(context);
            if (Utility.isEnabledService(context)) {
                Utility.initService(context);
                Utility.startService(context);  
            }
        } else if (intent.getAction().equals(Utility.ACTION_NOTIFY)) {
            Log.i("CMP", "action_notify");
            Utility.genNotify(context, intent);
        }    
    }
}

一些功能

public static void scheduleNotification(Context context) {
    Common.setSettings(context);

    if (ScheduleTask.getAlarmManager() == null)
        ScheduleTask.initAlarmManager(context);

    Calendar cal = Calendar.getInstance();
    cal.Add(Calendar.SECOND, 10);

    Intent intent = new Intent(context, AlarmReceiver.class);
    intent.setAction(Utility.ACTION_NOTIFY);
    intent.putExtra("Job", i);
    intent.putExtra("Name", name);
    intent.addCategory(String.format("Job_$1%s", name));
    PendingIntent pi = PendingIntent.getBroadcast(context, i, intent, PendingIntent. FLAG_ONE_SHOT);
    ScheduleTask.getAlarmManager().set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
    Log.i("CMP", String.valueOf(pi.getCreatorUid()));
}

public static void genTimeSheetNotify(Context context, Intent intent) {
     Intent notificationIntent = new Intent(context, MainActivity.class);
    PendingIntent pi = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);

    Bundle extras = intent.getExtras();

    Notification notification = new Notification.Builder(context)
        .setContentTitle("Test Notify")
        .setContentText("Testing Notify")
        .setSmallIcon(android.R.drawable.ic_dialog_info)
        .setVibrate(new long[] { 0, 100, 200, 300 })
        .setLights(0xff00ff00, 100, 100)
        .setContentIntent(pi)
        .setAutoCancel(true)
        .build();

    if (Notify.getNotificationManager() == null)
        Notify.initNotificationManager(context);

    Notify.getNotificationManager().notify(extras.getInt("Job"), notification);
}

public static void genTimeSheetNotify(Context context, Intent intent) {
    Intent notificationIntent = new Intent(context, MainActivity.class);
    // notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    PendingIntent pi = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);

    Bundle extras = intent.getExtras();

    Notification notification = new Notification.Builder(context)
        .setContentTitle("TimeSheet Submission")
        .setContentText(String.format("Timesheet of %1$s is due today.", extras.get("Name").toString()))
        .setSmallIcon(android.R.drawable.ic_dialog_info)
        .setVibrate(new long[] { 0, 100, 200, 300 })
        .setLights(0xff00ff00, 100, 100)
        .setContentIntent(pi)
        .setAutoCancel(true)
        .build();

    if (Notify.getNotificationManager() == null)
        Notify.initNotificationManager(context);

    Notify.getNotificationManager().notify(extras.getInt("Job"), notification);
}
答案

系统正在终止并重新启动服务(因为它是粘性的)。因此,通知是随机创建的。您需要在onStartCommand()中检查null的意图,因为当系统启动服务时,intent将为null。

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent != null)
        {
             //create notification here
        }
        return START_STICKY;
    }

以上是关于Android服务重新创建的主要内容,如果未能解决你的问题,请参考以下文章

Android Honeycomb:如何更改 FrameLayout 中的片段,而不重新创建它们?

Android Honeycomb:如何更改 FrameLayout 中的片段,而不重新创建它们?

Android:使用支持片段管理器时复制片段

片段必须是公共静态类才能从实例状态正确重新创建

在 android 首选项片段中使用 startService()

使用 ActionBar 旋转 Android 的双片段