前台服务不 运行 不断

Foreground Service dont run constantly

在我的应用程序中,我使用了一个必须 运行 不断的前台服务。有时前台服务会停止。 OS 在什么情况下会终止我的服务(即使内存足够,电池已满,phone 正在充电也会发生)?

到目前为止我的代码是这样的:

public class ServiceTest extends Service {

    public static Thread serverThread = null;
    public Context context = this;

    public ServiceTest(Context context) {
        super();
        this.context = context;
    }

    public ServiceTest() {

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        if (this.serverThread == null) {
            this.serverThread = new Thread(new ThreadTest());
            this.serverThread.start();
        }

        return START_STICKY;
    }

    private class ThreadTest implements Runnable {

        @Override
        public void run() {
            Intent notificationIntent = new Intent(context, MainActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        Notification notification = new NotificationCompat.Builder(context)
                .setContentTitle("Notification title")
                .setContentText("Notification text")
                .setContentIntent(pendingIntent)
                .setAutoCancel(false)
                .setSmallIcon(R.drawable.android)
                .setOngoing(true).build();

                startForeground(101, notification);

                while(true){
                    //work to do
                }
        }


    }

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

}

There is not a single... Many problems in your code... You may be getting it "0 Errors" as it is syntactically correct but it is androidicaly wrong, your basics are poor, reading of android documentation and implementation is very poor. Android never runs very poor things...

问题:1

您是否知道常规服务应该 override onCreateonStartCommandonBindonDestroy 方法....?

I don't see onDestroy there....!!

问题:2

你知道如何通知...吗?您的 onStartCommand 实施再次毫无意义。

KEEP IT EMPTY JUST RETURN START_STICKY

问题:3

您希望如何 运行 在后台执行限制下...?首先通过仅在 oncreate 中发出通知并在需要时使用 startforeground 通知 android...

I don't see it there.... you trying to do it in onstartcommand and again it is very poorly...

嗯...看看下面的工作代码:

public class RunnerService extends Service
{
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
NotificationChannel notificationChannel;
String NOTIFICATION_CHANNEL_ID = "1";

public RunnerService() { }

@Override
public void onCreate()
{
    super.onCreate();

    Log.d("RUNNER : ", "OnCreate... \n");

    Bitmap IconLg = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground);

    mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
    mBuilder = new NotificationCompat.Builder(this, null);
    mBuilder.setContentTitle("My App")
            .setContentText("Always running...")
            .setTicker("Always running...")
            .setSmallIcon(R.drawable.ic_menu_slideshow)
            .setLargeIcon(IconLg)
            .setPriority(Notification.PRIORITY_HIGH)
            .setVibrate(new long[] {1000})
            .setVisibility(Notification.VISIBILITY_PUBLIC)
            .setOngoing(true)
            .setAutoCancel(false);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
        notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);

        // Configure the notification channel.
        notificationChannel.setDescription("Channel description");
        notificationChannel.enableLights(true);
        notificationChannel.setLightColor(Color.RED);
        notificationChannel.setVibrationPattern(new long[]{1000});
        notificationChannel.enableVibration(true);
        notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        mNotifyManager.createNotificationChannel(notificationChannel);

        mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
        startForeground(1, mBuilder.build());
    }
    else
    {
        mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
        mNotifyManager.notify(1, mBuilder.build());
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    Log.d("RUNNER : ", "\nPERFORMING....");

    return START_STICKY;
}

@Override
public void onDestroy()
{
    Log.d("RUNNER : ", "\nDestroyed....");
    Log.d("RUNNER : ", "\nWill be created again automaticcaly....");
    super.onDestroy();
}


@Override
public IBinder onBind(Intent intent)
{
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("NOT_YET_IMPLEMENTED");
}
}

如何检查....???

从最近列表中删除该应用程序,您应该会在日志中看到 logcat...

中的“Performing”消息

它在什么情况下停止...?

It never stops ( until next boot..!! )... Yes it stops when user force stops application. And rarely if system finds it is having very low resources .... which is a very rare condition seems to occur as android has improved a lot over the time....

如何开始....?????

无论它来自 mainactivityreceiver 或任何 class :

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        {
            context.startForegroundService(new Intent(context, RunnerService.class));

        }
        else
        {
            context.startService(new Intent(context, RunnerService.class));

        }

如何查看服务是否启动....?

干脆不要......即使你想启动服务多少次......如果它已经运行ning......那么它不会再次启动。 ...如果不是 运行ning 那么...将启动它...!!

如果服务需要意图才能工作,则所选答案中的批评是不合理的。

在更高版本的 Android 上,系统将在设备锁定时暂停任何前台服务,以最大限度地减少功耗 ,即使 returns START_STICKY。所以,要不断的做一个前台任务,需要wakelock。

以下是 android 文档描述的内容 wakeLock

To avoid draining the battery, an Android device that is left idle quickly falls asleep. However, there are times when an application needs to wake up the screen or the CPU and keep it awake to complete some work.

要使前台服务 运行 不断,请从 onCreate().

内部获取 wakeLock
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
        "MyApp::MyWakelockTag");
wakeLock.acquire();

有关详细信息,请查看 official Android Documentation