Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
238 views
in Technique[技术] by (71.8m points)

android - Using startForeground() with an Intent Service

I am trying to keep alive a service that reacts to screen on/off changes. The service would work perfectly for awhile, but then eventually it would be killed. I am now attempting to use startForeground() to keep the process alive, but it still seems to be dying. I understand that there is no way to keep a process alive forever, without error, but I feel like I must be doing something wrong, as adding startForeground() added no extra life to the process. Also, as a side note, Logcat complains about a leak, as unregisterReceiver() is not called (except manually by a button press from the user).. however, due to the nature of what I am trying to accomplish, the receiver needs to run until explicitly told to stop.

Any suggestions?

Relevant Code:

public class UpdateService extends IntentService {

        public UpdateService() {
        super(null);

    }

        @Override
        protected void onHandleIntent(Intent intent) {

            final int myID = 1234;


            Intent notificationintent = new Intent(this, Main.class);
            notificationintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            PendingIntent pendIntent = PendingIntent.getActivity(this, 0, notificationintent, 0);


            Notification notice = new Notification(R.drawable.icon_image, "***********", System.currentTimeMillis());


            notice.setLatestEventInfo(this, "*************", "***********", pendIntent);

            notice.flags |= Notification.FLAG_NO_CLEAR;
            startForeground(myID, notice);

            boolean screenOn = intent.getBooleanExtra("screen_state", false);


// Blah Blah Blah......


        }

        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

(Updated) I suppose there are the following possible cases:

1) documentation for IntentService states:

the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

So, it might be that your service is normally stopped after onHandleIntent() is finished (especially, as you mentioned that startForeground() added no extra life to the process).

2) You might try to check if it's somehow can be related to device going to sleep (or maybe you are starting your service by schedule and awkening device - in this case you might need to acquire WakeLock)

3) In the very rare cases, the system still can kill foreground process - so if you do a lot of allocations (really lot) and some other work in onHandleIntent() (instead of "Blah Blah Blah" at your code) - you might run into it - but I suppose it's not the case.

As question's title is "Using startForeground() with an IntentService" - would like to clarify that too: I believe nothing (architecture, best practices, android framework, java docs for IntentService) prevents you from running your intent service as a foreground. Of course you need to thought out carefully its usage and whether you actually need a foreground service. Some ideas are available here. For sample code see below. (Sample code can end up showing multiple notifications if you queued multiple jobs/intents into IntentService, so there might be better solution depending on your need.)


public class ForegroundService extends IntentService {

    private static final String TAG = "FrgrndSrv";

    public ForegroundService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        Notification.Builder builder = new Notification.Builder(getBaseContext())
                .setSmallIcon(R.drawable.ic_foreground_service)
                .setTicker("Your Ticker") // use something from something from R.string
                .setContentTitle("Your content title") // use something from something from
                .setContentText("Your content text") // use something from something from
                .setProgress(0, 0, true); // display indeterminate progress

        startForeground(1, builder.build());
        try {
            doIntesiveWork();
        } finally {
            stopForeground(true);
        }
    }

    protected void doIntesiveWork() {
        // Below should be your logic that takes lots of time
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...