Discussion:
Running Background Process
(too old to reply)
Jaikishan Jalan
2008-07-13 14:50:47 UTC
Permalink
Hello,

I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
certain task periodically. Here is my piece of code:

public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}

private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}

I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain times
before I get this thread running. I check this by checking the server log. I
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.

Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Mark Murphy
2008-07-13 15:15:15 UTC
Permalink
Post by Jaikishan Jalan
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
certain task periodically.
To quote from the documentation:

"An IntentReceiver object is only valid for the duration of the call to
onReceiveIntent(Context, Intent). Once your code returns from this
function, the system considers the object to be finished and no longer
active.

"This has important repercussions to what you can do in an
onReceiveIntent(Context, Intent) implementation: anything that requires
asynchronous operation is not available, because you will need to return
from the function to handle the asynchronous operation, but at that
point the IntentReceiver is no longer active and thus the system is free
to kill its process before the asynchronous operation completes."

(http://code.google.com/android/reference/android/content/IntentReceiver.html)

Hence, I suspect that spawning a thread from an IntentReceiver is not
recommended.

You might consider a service, or using AlarmManager. Your current code
has a polling cycle of 15 seconds, which is rathe short, particularly if
you are hitting the Internet on each poll -- you might really be a drag
on the battery. But, if that is what you want, a 15-second poll is
probably better suited for a service.

AlarmManager probably uses fewer resources, as your program does not
even need to be in memory until it is time to do your pulse of work. But
the API suggests it is designed more for longer periods of time between
pulses of work -- it's probably more aimed at alarm-clock functionality
than it is a 15-second poll.

BTW, if you are going the service route, you could consider using
java.util.concurrent.ScheduledThreadPoolExecutor, if you need fancier
timing logic than what a simple sleep loop might give you.
--
Mark Murphy (a Commons Guy)
http://commonsware.com
Android Training on the Ranch in September! http://www.bignerdranch.com
JBQ
2008-07-13 17:38:53 UTC
Permalink
First, I'm not entirely sure what you're trying to achieve, but making
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using the
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.

You really have two options here:

-if you really want to have a process stick around, you need to have a
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When the
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing in
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.

-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the system
to free the memory associated with your process between ticks.

JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}
private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain times
before I get this thread running. I check this by checking the server log. I
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
Jaikishan Jalan
2008-07-13 17:43:25 UTC
Permalink
Thanks Mark and JBQ for your reply. Ok, ideally when the application will be
released, my application will make a network request after every 30 minutes.
So what do you recommend? - Service or Alarm Manager? My second question is
why the random behavior? Is there any reason behind why the thread sometime
runs and sometime it does not.

-Jaikishan

-----Original Message-----
From: android-***@googlegroups.com
[mailto:android-***@googlegroups.com] On Behalf Of JBQ
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process


First, I'm not entirely sure what you're trying to achieve, but making
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using the
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.

You really have two options here:

-if you really want to have a process stick around, you need to have a
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When the
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing in
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.

-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the system
to free the memory associated with your process between ticks.

JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}
private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain times
before I get this thread running. I check this by checking the server log. I
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
JBQ
2008-07-13 18:13:42 UTC
Permalink
For a 30-minute interval, I'd recommend an alarm manager. It'll save
some RAM that'll make the device more responsive for foreground
applications, and it'll save you some bookkeeping (tracking a 30-
minute interval through your service getting killed and restarted
isn't as easy as it seems).

As for the apparently random behavior, I don't actually know for sure.
My guess is that the system is running under enough memory pressure
(which is common during boot as there are many things going on) to
cause apparently inactive processes to get killed so quickly that your
thread never gets a chance to run at all.

JBQ
Post by Jaikishan Jalan
Thanks Mark and JBQ for your reply. Ok, ideally when the application will be
released, my application will make a network request after every 30 minutes.
So what do you recommend? - Service or Alarm Manager? My second question is
why the random behavior? Is there any reason behind why the thread sometime
runs and sometime it does not.
-Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
First, I'm not entirely sure what you're trying to achieve, but making
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using the
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.
-if you really want to have a process stick around, you need to have a
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When the
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing in
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.
-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the system
to free the memory associated with your process between ticks.
JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}
private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain
times
Post by Jaikishan Jalan
before I get this thread running. I check this by checking the server log.
I
Post by Jaikishan Jalan
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
Jaikishan Jalan
2008-07-13 18:17:49 UTC
Permalink
Alright. Thanks I will try to use AlarmManager (Hopefully without trouble).

Thanks,
Jaikishan

-----Original Message-----
From: android-***@googlegroups.com
[mailto:android-***@googlegroups.com] On Behalf Of JBQ
Sent: Sunday, July 13, 2008 11:14 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process


For a 30-minute interval, I'd recommend an alarm manager. It'll save
some RAM that'll make the device more responsive for foreground
applications, and it'll save you some bookkeeping (tracking a 30-
minute interval through your service getting killed and restarted
isn't as easy as it seems).

As for the apparently random behavior, I don't actually know for sure.
My guess is that the system is running under enough memory pressure
(which is common during boot as there are many things going on) to
cause apparently inactive processes to get killed so quickly that your
thread never gets a chance to run at all.

JBQ
Post by Jaikishan Jalan
Thanks Mark and JBQ for your reply. Ok, ideally when the application will be
released, my application will make a network request after every 30 minutes.
So what do you recommend? - Service or Alarm Manager? My second question is
why the random behavior? Is there any reason behind why the thread sometime
runs and sometime it does not.
-Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
First, I'm not entirely sure what you're trying to achieve, but making
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using the
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.
-if you really want to have a process stick around, you need to have a
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When the
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing in
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.
-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the system
to free the memory associated with your process between ticks.
JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}
private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain
times
Post by Jaikishan Jalan
before I get this thread running. I check this by checking the server log.
I
Post by Jaikishan Jalan
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
Jaikishan Jalan
2008-07-13 18:19:19 UTC
Permalink
Just to make this thread more useful for other people, I found an
interesting link (with example) on the similar problem:
http://www.anddev.org/autostarting_services-t1137.html

Thanks,
Jaikishan

-----Original Message-----
From: android-***@googlegroups.com
[mailto:android-***@googlegroups.com] On Behalf Of JBQ
Sent: Sunday, July 13, 2008 11:14 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process


For a 30-minute interval, I'd recommend an alarm manager. It'll save
some RAM that'll make the device more responsive for foreground
applications, and it'll save you some bookkeeping (tracking a 30-
minute interval through your service getting killed and restarted
isn't as easy as it seems).

As for the apparently random behavior, I don't actually know for sure.
My guess is that the system is running under enough memory pressure
(which is common during boot as there are many things going on) to
cause apparently inactive processes to get killed so quickly that your
thread never gets a chance to run at all.

JBQ
Post by Jaikishan Jalan
Thanks Mark and JBQ for your reply. Ok, ideally when the application will be
released, my application will make a network request after every 30 minutes.
So what do you recommend? - Service or Alarm Manager? My second question is
why the random behavior? Is there any reason behind why the thread sometime
runs and sometime it does not.
-Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
First, I'm not entirely sure what you're trying to achieve, but making
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using the
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.
-if you really want to have a process stick around, you need to have a
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When the
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing in
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.
-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the system
to free the memory associated with your process between ticks.
JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}
private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain
times
Post by Jaikishan Jalan
before I get this thread running. I check this by checking the server log.
I
Post by Jaikishan Jalan
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
hackbod
2008-07-13 19:06:16 UTC
Permalink
Yeah it is almost certainly due to the process being killed to reclaim
memory. In the situation where you just have a receiver that starts a
thread, the process will be run as a foreground process (oom_adj=0)
for the time it is in onReceiveIntent(), but upon returning from that
the system does not consider there to be any active objects running in
the process so it is lowered to an empty process (oom_adj=15).

Empty processes are killed very aggressively by the system's memory
management, so it is very likely for your process to be killed as
other things go on during boot. If you look at the logcat output, you
will probably see lines in the log about your process starting, and
then later dying. You can also use the command "adb dumpsys activity"
to see the current state of the activities and application processes
being managed by the system; this includes the current oom_adj values
for each process.

Fwiw, a lot of memory optimization work has been done since M5 so in
future SDKs it is less likely for your process to be killed when
empty... but leaving it in the state where the system thinks it is
empty but you still have stuff you want running in it is a bug, and
will cause problems sooner or later.
Post by JBQ
For a 30-minute interval, I'd recommend an alarm manager. It'll save
some RAM that'll make the device more responsive for foreground
applications, and it'll save you some bookkeeping (tracking a 30-
minute interval through your service getting killed and restarted
isn't as easy as it seems).
As for the apparently random behavior, I don't actually know for sure.
My guess is that the system is running under enough memory pressure
(which is common during boot as there are many things going on) to
cause apparently inactive processes to get killed so quickly that your
thread never gets a chance to run at all.
JBQ
Post by Jaikishan Jalan
Thanks Mark and JBQ for your reply. Ok, ideally when the application will be
released, my application will make a network request after every 30 minutes.
So what do you recommend? - Service or Alarm Manager? My second question is
why the random behavior? Is there any reason behind why the thread sometime
runs and sometime it does not.
-Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
First, I'm not entirely sure what you're trying to achieve, but making
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using the
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.
-if you really want to have a process stick around, you need to have a
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When the
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing in
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.
-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the system
to free the memory associated with your process between ticks.
JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
  /* the intent source*/
  static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
  public void onReceiveIntent(Context context, Intent intent) {
    if (intent.getAction().equals(ACTION))
    {
      NewRunnable AddressLog = new NewRunnable(context);
      Thread tr = new Thread(null,AddressLog,"Address Logger");
      tr.start();
    }
  }
  private class NewRunnable implements Runnable {
    private Context context;
    // Initializing the Runnable Class
    public NewRunnable(Context c){
      context = c;
    }
    public void run(){
      while(true){
         isServerUp = true;
         if(isServerUp ){
            // Do some processing
            Thread.sleep(15 * 1000);
          }
        }catch(Exception e){}
      }
    }
  }
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain
times
Post by Jaikishan Jalan
before I get this thread running. I check this by checking the server log.
I
Post by Jaikishan Jalan
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
Jaikishan Jalan
2008-07-13 21:07:25 UTC
Permalink
So, is this the correct way ?

// My intent receiver which will listen for BOOT_COMPLETED Signal
public class AddressLogIntent extends IntentReceiver{
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
Intent AddressIntent = new
Intent(AddressLogIntent.this,AddressLogService.class);
// We want the alarm to go off 15 seconds from now.
long firstTime = SystemClock.elapsedRealtime();

// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime,
15*1000, intent);
}
}
}

public class AddressLogService extends Service
{
@Override
protected void onCreate()
{
//Simply do my processing
}
}

Is this the correct way to invoke a background process that runs after every
15 seconds after the BOOT event is completed? I created an intentreceiver
for the BOOT event and then create an Alarm Manager and schedule it after
every 15 seconds. This alarm manager will call a service that will do my
processing. I expect this alarm to run infinitely until the emulator is
closed.

Thanks,
Jaikishan

-----Original Message-----
From: android-***@googlegroups.com
[mailto:android-***@googlegroups.com] On Behalf Of hackbod
Sent: Sunday, July 13, 2008 12:06 PM
To: Android Developers
Subject: [android-developers] Re: Running Background Process


Yeah it is almost certainly due to the process being killed to reclaim
memory. In the situation where you just have a receiver that starts a
thread, the process will be run as a foreground process (oom_adj=0)
for the time it is in onReceiveIntent(), but upon returning from that
the system does not consider there to be any active objects running in
the process so it is lowered to an empty process (oom_adj=15).

Empty processes are killed very aggressively by the system's memory
management, so it is very likely for your process to be killed as
other things go on during boot. If you look at the logcat output, you
will probably see lines in the log about your process starting, and
then later dying. You can also use the command "adb dumpsys activity"
to see the current state of the activities and application processes
being managed by the system; this includes the current oom_adj values
for each process.

Fwiw, a lot of memory optimization work has been done since M5 so in
future SDKs it is less likely for your process to be killed when
empty... but leaving it in the state where the system thinks it is
empty but you still have stuff you want running in it is a bug, and
will cause problems sooner or later.
Post by JBQ
For a 30-minute interval, I'd recommend an alarm manager. It'll save
some RAM that'll make the device more responsive for foreground
applications, and it'll save you some bookkeeping (tracking a 30-
minute interval through your service getting killed and restarted
isn't as easy as it seems).
As for the apparently random behavior, I don't actually know for sure.
My guess is that the system is running under enough memory pressure
(which is common during boot as there are many things going on) to
cause apparently inactive processes to get killed so quickly that your
thread never gets a chance to run at all.
JBQ
Post by Jaikishan Jalan
Thanks Mark and JBQ for your reply. Ok, ideally when the application will be
released, my application will make a network request after every 30 minutes.
So what do you recommend? - Service or Alarm Manager? My second question is
why the random behavior? Is there any reason behind why the thread sometime
runs and sometime it does not.
-Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
First, I'm not entirely sure what you're trying to achieve, but making
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using the
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.
-if you really want to have a process stick around, you need to have a
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When the
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing in
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.
-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the system
to free the memory associated with your process between ticks.
JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
  /* the intent source*/
  static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
  public void onReceiveIntent(Context context, Intent intent) {
    if (intent.getAction().equals(ACTION))
    {
      NewRunnable AddressLog = new NewRunnable(context);
      Thread tr = new Thread(null,AddressLog,"Address Logger");
      tr.start();
    }
  }
  private class NewRunnable implements Runnable {
    private Context context;
    // Initializing the Runnable Class
    public NewRunnable(Context c){
      context = c;
    }
    public void run(){
      while(true){
         isServerUp = true;
         if(isServerUp ){
            // Do some processing
            Thread.sleep(15 * 1000);
          }
        }catch(Exception e){}
      }
    }
  }
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain
times
Post by Jaikishan Jalan
before I get this thread running. I check this by checking the server log.
I
Post by Jaikishan Jalan
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
Mark Murphy
2008-07-13 21:15:27 UTC
Permalink
Post by Jaikishan Jalan
So, is this the correct way ?
I would have the AlarmManager in the service, so you can expose IPC to
disable or change the rate of scheduling.

Just have the IntentReceiver start the service (or try having the
service itself embed an IntentReceiver to watch for your boot event --
not sure if that works).
--
Mark Murphy (a Commons Guy)
http://commonsware.com
_The Busy Coder's Guide to Android Development_ Version 1.0 Published!
hackbod
2008-07-14 02:30:43 UTC
Permalink
In M5 the alarm manager could only send a broadcast, so you will need
to have a receiver for that (could be the same one, checking the
Intent action) which then starts the service. In a future SDK you
will be able to directly start a service.

Also I would highly recommend going through the ApiDemos -- there are
examples of services, alarms, and using the two together.
Post by Jaikishan Jalan
So, is this the correct way ?
// My intent receiver which will listen for BOOT_COMPLETED Signal
public class AddressLogIntent extends IntentReceiver{
   static final String ACTION = "android.intent.action.BOOT_COMPLETED";
   public void onReceiveIntent(Context context, Intent intent) {
     if (intent.getAction().equals(ACTION))
     {
         Intent AddressIntent = new
Intent(AddressLogIntent.this,AddressLogService.class);
       // We want the alarm to go off 15 seconds from now.
       long firstTime = SystemClock.elapsedRealtime();
       // Schedule the alarm!
       AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
       am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime,
15*1000, intent);
     }
   }
}
public class AddressLogService extends Service
{
    protected void onCreate()
    {
       //Simply do my processing
    }
}
Is this the correct way to invoke a background process that runs after every
15 seconds after the BOOT event is completed? I created an intentreceiver
for the BOOT event and then create an Alarm Manager and schedule it after
every 15 seconds. This alarm manager will call a service that will do my
processing. I expect this alarm to run infinitely until the emulator is
closed.
Thanks,
Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 12:06 PM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
Yeah it is almost certainly due to the process being killed to reclaim
memory.  In the situation where you just have a receiver that starts a
thread, the process will be run as a foreground process (oom_adj=0)
for the time it is in onReceiveIntent(), but upon returning from that
the system does not consider there to be any active objects running in
the process so it is lowered to an empty process (oom_adj=15).
Empty processes are killed very aggressively by the system's memory
management, so it is very likely for your process to be killed as
other things go on during boot.  If you look at the logcat output, you
will probably see lines in the log about your process starting, and
then later dying.  You can also use the command "adb dumpsys activity"
to see the current state of the activities and application processes
being managed by the system; this includes the current oom_adj values
for each process.
Fwiw, a lot of memory optimization work has been done since M5 so in
future SDKs it is less likely for your process to be killed when
empty...  but leaving it in the state where the system thinks it is
empty but you still have stuff you want running in it is a bug, and
will cause problems sooner or later.
Post by JBQ
For a 30-minute interval, I'd recommend an alarm manager. It'll save
some RAM that'll make the device more responsive for foreground
applications, and it'll save you some bookkeeping (tracking a 30-
minute interval through your service getting killed and restarted
isn't as easy as it seems).
As for the apparently random behavior, I don't actually know for sure.
My guess is that the system is running under enough memory pressure
(which is common during boot as there are many things going on) to
cause apparently inactive processes to get killed so quickly that your
thread never gets a chance to run at all.
JBQ
Post by Jaikishan Jalan
Thanks Mark and JBQ for your reply. Ok, ideally when the application
will be
Post by JBQ
Post by Jaikishan Jalan
released, my application will make a network request after every 30
minutes.
Post by JBQ
Post by Jaikishan Jalan
So what do you recommend? - Service or Alarm Manager? My second question
is
Post by JBQ
Post by Jaikishan Jalan
why the random behavior? Is there any reason behind why the thread
sometime
Post by JBQ
Post by Jaikishan Jalan
runs and sometime it does not.
-Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
First, I'm not entirely sure what you're trying to achieve, but making
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using the
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.
-if you really want to have a process stick around, you need to have a
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When the
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing in
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.
-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the system
to free the memory associated with your process between ticks.
JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
  /* the intent source*/
  static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
  public void onReceiveIntent(Context context, Intent intent) {
    if (intent.getAction().equals(ACTION))
    {
      NewRunnable AddressLog = new NewRunnable(context);
      Thread tr = new Thread(null,AddressLog,"Address Logger");
      tr.start();
    }
  }
  private class NewRunnable implements Runnable {
    private Context context;
    // Initializing the Runnable Class
    public NewRunnable(Context c){
      context = c;
    }
    public void run(){
      while(true){
         isServerUp = true;
         if(isServerUp ){
            // Do some processing
            Thread.sleep(15 * 1000);
          }
        }catch(Exception e){}
      }
    }
  }
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run
and
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
sometime it does not run. I have to try launching the emulator certain
times
Post by Jaikishan Jalan
before I get this thread running. I check this by checking the server
log.
Post by JBQ
Post by Jaikishan Jalan
I
Post by Jaikishan Jalan
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
Jaikishan Jalan
2008-07-14 08:26:55 UTC
Permalink
Alright, I wrote my service as per the discussion, but somehow it is not
running. Here is my piece of code:

public class BootCompletedIntentReceiver extends IntentReceiver {
/* the intent source*/
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
private static final String LOG_TAG = "BootCompletedIntentReceiver";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
Intent i = new Intent();
i.setClassName("com.jaikishan.smartaddress",
"com.jaikishan.smartaddress.AddressLoggerIntent");
// We want the alarm to go off 5 seconds from now.. //Ideally it will
be 30 minutes or so.
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)context.getSystemService("alarm");
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 5*1000, intent);

Log.v(LOG_TAG,"AddressLoggerIntent Sent");

}
}
}


public class AddressLoggerIntent extends IntentReceiver
{
private static final String LOG_TAG = "AddressLoggerIntent";
@Override
public void onReceiveIntent(Context context, Intent intent)
{
// Start up the service. Note that if the service is taking too
long
// to complete -- longer than our alarm's repeat rate -- then this
will
// just leave the current service running, skipping this alarm. For
// most situations this is probably a reasonable thing to do.
context.startService(new Intent(context,
AddressLoggerService.class),
null);
Log.v(LOG_TAG,"AddressLoggerService Sent");
}
}

public class AddressLoggerService extends Service {
private static final String LOG_TAG = "AddressLoggerService";
@Override
protected void onStart(int startId, Bundle arguments) {
super.onStart( startId, arguments );
Log.v(LOG_TAG, "AddressLogger Service Started");
// Do the processing
}
}

@Override
public IBinder onBind(Intent intent) {
return null;
}
}
From my BootIntentReceiver, I set the alarm Manager. Since Alarm Manager can
only send broadcast, I have an intent receiver for it. The intent receiver
calls a service that will run the business logic. However, when I observe
the Logcat, I see "AddressLoggerIntent Sent" message keeps getting printed
infinite times and nothing else happens. Other Log messages are never
printed. This shows that my service is not getting called at all ! (ideally
it should be called periodically). My AndroidManifest.xml file looks life:

<application>
<receiver android:name=".BootCompletedIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"
/>
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</receiver>
<service android:name=".AddressLoggerService"/>
<receiver android:name=".AddressLoggerIntent" />
</application>

Any help will be greatly appreciated.
In M5 the alarm manager could only send a broadcast, so you will need
to have a receiver for that (could be the same one, checking the
Intent action) which then starts the service. In a future SDK you
will be able to directly start a service.
Also I would highly recommend going through the ApiDemos -- there are
examples of services, alarms, and using the two together.
Post by Jaikishan Jalan
So, is this the correct way ?
// My intent receiver which will listen for BOOT_COMPLETED Signal
public class AddressLogIntent extends IntentReceiver{
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
Intent AddressIntent = new
Intent(AddressLogIntent.this,AddressLogService.class);
// We want the alarm to go off 15 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime,
15*1000, intent);
}
}
}
public class AddressLogService extends Service
{
@Override
protected void onCreate()
{
//Simply do my processing
}
}
Is this the correct way to invoke a background process that runs after
every
Post by Jaikishan Jalan
15 seconds after the BOOT event is completed? I created an intentreceiver
for the BOOT event and then create an Alarm Manager and schedule it after
every 15 seconds. This alarm manager will call a service that will do my
processing. I expect this alarm to run infinitely until the emulator is
closed.
Thanks,
Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 12:06 PM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
Yeah it is almost certainly due to the process being killed to reclaim
memory. In the situation where you just have a receiver that starts a
thread, the process will be run as a foreground process (oom_adj=0)
for the time it is in onReceiveIntent(), but upon returning from that
the system does not consider there to be any active objects running in
the process so it is lowered to an empty process (oom_adj=15).
Empty processes are killed very aggressively by the system's memory
management, so it is very likely for your process to be killed as
other things go on during boot. If you look at the logcat output, you
will probably see lines in the log about your process starting, and
then later dying. You can also use the command "adb dumpsys activity"
to see the current state of the activities and application processes
being managed by the system; this includes the current oom_adj values
for each process.
Fwiw, a lot of memory optimization work has been done since M5 so in
future SDKs it is less likely for your process to be killed when
empty... but leaving it in the state where the system thinks it is
empty but you still have stuff you want running in it is a bug, and
will cause problems sooner or later.
Post by JBQ
For a 30-minute interval, I'd recommend an alarm manager. It'll save
some RAM that'll make the device more responsive for foreground
applications, and it'll save you some bookkeeping (tracking a 30-
minute interval through your service getting killed and restarted
isn't as easy as it seems).
As for the apparently random behavior, I don't actually know for sure.
My guess is that the system is running under enough memory pressure
(which is common during boot as there are many things going on) to
cause apparently inactive processes to get killed so quickly that your
thread never gets a chance to run at all.
JBQ
Post by Jaikishan Jalan
Thanks Mark and JBQ for your reply. Ok, ideally when the application
will be
Post by JBQ
Post by Jaikishan Jalan
released, my application will make a network request after every 30
minutes.
Post by JBQ
Post by Jaikishan Jalan
So what do you recommend? - Service or Alarm Manager? My second
question
Post by Jaikishan Jalan
is
Post by JBQ
Post by Jaikishan Jalan
why the random behavior? Is there any reason behind why the thread
sometime
Post by JBQ
Post by Jaikishan Jalan
runs and sometime it does not.
-Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
First, I'm not entirely sure what you're trying to achieve, but
making
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using
the
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.
-if you really want to have a process stick around, you need to have
a
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When
the
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing
in
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
the service's onCreate function. In that case, you'll find that using
a Handler is a much better idea than using Thread.sleep.
-if you can work without necessarily having a process stay up all the
time, you should look at the AlarmManager, which will allow the
system
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
to free the memory associated with your process between ticks.
JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot
has
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
completed. In this, I run a thread in the background process which
do
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}
private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run
and
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
sometime it does not run. I have to try launching the emulator
certain
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
times
Post by Jaikishan Jalan
before I get this thread running. I check this by checking the
server
Post by Jaikishan Jalan
log.
Post by JBQ
Post by Jaikishan Jalan
I
Post by Jaikishan Jalan
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way
to
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
approach this task.
Thanks,
Jaikishan
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Jaikishan Jalan
2008-07-14 09:26:25 UTC
Permalink
Alright. I guess I jumped in too quickly to shot out my problem . I figured
out a way (of course with the help of all you beautiful people :) ) to run
my service in background. What I have done is I first call a service from my
intent receiver. This service in turns creates an instance of Alarm Manager.
Since Alarm Manager broadcasts an intent, I have another intent receiver,
which receives this intent and run a service which will do run my logic. It
seems to work for me but not sure if this is the most efficient and
recommendable way to do this. Here is my piece of code:

public class BootCompletedIntentReceiver extends IntentReceiver {
/* the intent source*/
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
private static final String LOG_TAG = "BootCompletedIntentReceiver";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
// Once we receive the BOOT_COMPLETED intent, we will start a service
that
// will start a service which in turn will run alarm manager
Intent i = new Intent();
i.setClassName("com.jaikishan.smartaddress",
"com.jaikishan.smartaddress.AddressLogService");
Bundle b = new Bundle();
ComponentName cname = context.startService( i,b );
if( cname == null )
Log.e( LOG_TAG,"AddressLogService was not started" );
else
Log.d( LOG_TAG,"AddressLogService started" );
}
}
}


public class AddressLogService extends Service {
private static final String LOG_TAG = "BackgroundService";

@Override
protected void onStart(int startId, Bundle arguments) {
super.onStart( startId, arguments );
Log.d( LOG_TAG, "onStart" );
Intent i = new Intent();
i.setClassName("com.jaikishan.smartaddress",
"com.jaikishan.smartaddress.AddressLoggerIntent");
// We want the alarm to go off 5 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 5*1000, i);
}

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

public class AddressLoggerIntent extends IntentReceiver
{
private static final String LOG_TAG = "AddressLoggerIntent";
@Override
public void onReceiveIntent(Context context, Intent intent)
{
context.startService(new Intent(context, AddressLogger.class),
null);
}
}


public class AddressLogger extends Service {
@Override
protected void onStart(int startId, Bundle arguments) {
super.onStart( startId, arguments );
// Do business logic
}

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

Thanks,
Jaikishan
Post by Jaikishan Jalan
Alright, I wrote my service as per the discussion, but somehow it is not
public class BootCompletedIntentReceiver extends IntentReceiver {
/* the intent source*/
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
private static final String LOG_TAG = "BootCompletedIntentReceiver";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
Intent i = new Intent();
i.setClassName("com.jaikishan.smartaddress",
"com.jaikishan.smartaddress.AddressLoggerIntent");
// We want the alarm to go off 5 seconds from now.. //Ideally it will
be 30 minutes or so.
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)context.getSystemService("alarm");
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 5*1000, intent);
Log.v(LOG_TAG,"AddressLoggerIntent Sent");
}
}
}
public class AddressLoggerIntent extends IntentReceiver
{
private static final String LOG_TAG = "AddressLoggerIntent";
@Override
public void onReceiveIntent(Context context, Intent intent) {
// Start up the service. Note that if the service is taking too
long
// to complete -- longer than our alarm's repeat rate -- then this
will
// just leave the current service running, skipping this alarm.
For
// most situations this is probably a reasonable thing to do.
context.startService(new Intent(context,
AddressLoggerService.class),
null);
Log.v(LOG_TAG,"AddressLoggerService Sent");
}
}
public class AddressLoggerService extends Service {
private static final String LOG_TAG = "AddressLoggerService";
@Override
protected void onStart(int startId, Bundle arguments) {
super.onStart( startId, arguments );
Log.v(LOG_TAG, "AddressLogger Service Started");
// Do the processing
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
From my BootIntentReceiver, I set the alarm Manager. Since Alarm Manager
can only send broadcast, I have an intent receiver for it. The intent
receiver calls a service that will run the business logic. However, when I
observe the Logcat, I see "AddressLoggerIntent Sent" message keeps getting
printed infinite times and nothing else happens. Other Log messages are
never printed. This shows that my service is not getting called at all !
(ideally it should be called periodically). My AndroidManifest.xml file
<application>
<receiver android:name=".BootCompletedIntentReceiver">
<intent-filter>
<action
android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</receiver>
<service android:name=".AddressLoggerService"/>
<receiver android:name=".AddressLoggerIntent" />
</application>
Any help will be greatly appreciated.
Post by hackbod
In M5 the alarm manager could only send a broadcast, so you will need
to have a receiver for that (could be the same one, checking the
Intent action) which then starts the service. In a future SDK you
will be able to directly start a service.
Also I would highly recommend going through the ApiDemos -- there are
examples of services, alarms, and using the two together.
Post by Jaikishan Jalan
So, is this the correct way ?
// My intent receiver which will listen for BOOT_COMPLETED Signal
public class AddressLogIntent extends IntentReceiver{
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
Intent AddressIntent = new
Intent(AddressLogIntent.this,AddressLogService.class);
// We want the alarm to go off 15 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime,
15*1000, intent);
}
}
}
public class AddressLogService extends Service
{
@Override
protected void onCreate()
{
//Simply do my processing
}
}
Is this the correct way to invoke a background process that runs after
every
Post by Jaikishan Jalan
15 seconds after the BOOT event is completed? I created an
intentreceiver
Post by Jaikishan Jalan
for the BOOT event and then create an Alarm Manager and schedule it
after
Post by Jaikishan Jalan
every 15 seconds. This alarm manager will call a service that will do my
processing. I expect this alarm to run infinitely until the emulator is
closed.
Thanks,
Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 12:06 PM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
Yeah it is almost certainly due to the process being killed to reclaim
memory. In the situation where you just have a receiver that starts a
thread, the process will be run as a foreground process (oom_adj=0)
for the time it is in onReceiveIntent(), but upon returning from that
the system does not consider there to be any active objects running in
the process so it is lowered to an empty process (oom_adj=15).
Empty processes are killed very aggressively by the system's memory
management, so it is very likely for your process to be killed as
other things go on during boot. If you look at the logcat output, you
will probably see lines in the log about your process starting, and
then later dying. You can also use the command "adb dumpsys activity"
to see the current state of the activities and application processes
being managed by the system; this includes the current oom_adj values
for each process.
Fwiw, a lot of memory optimization work has been done since M5 so in
future SDKs it is less likely for your process to be killed when
empty... but leaving it in the state where the system thinks it is
empty but you still have stuff you want running in it is a bug, and
will cause problems sooner or later.
Post by JBQ
For a 30-minute interval, I'd recommend an alarm manager. It'll save
some RAM that'll make the device more responsive for foreground
applications, and it'll save you some bookkeeping (tracking a 30-
minute interval through your service getting killed and restarted
isn't as easy as it seems).
As for the apparently random behavior, I don't actually know for sure.
My guess is that the system is running under enough memory pressure
(which is common during boot as there are many things going on) to
cause apparently inactive processes to get killed so quickly that your
thread never gets a chance to run at all.
JBQ
Post by Jaikishan Jalan
Thanks Mark and JBQ for your reply. Ok, ideally when the application
will be
Post by JBQ
Post by Jaikishan Jalan
released, my application will make a network request after every 30
minutes.
Post by JBQ
Post by Jaikishan Jalan
So what do you recommend? - Service or Alarm Manager? My second
question
Post by Jaikishan Jalan
is
Post by JBQ
Post by Jaikishan Jalan
why the random behavior? Is there any reason behind why the thread
sometime
Post by JBQ
Post by Jaikishan Jalan
runs and sometime it does not.
-Jaikishan
-----Original Message-----
Sent: Sunday, July 13, 2008 10:39 AM
To: Android Developers
Subject: [android-developers] Re: Running Background Process
First, I'm not entirely sure what you're trying to achieve, but
making
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
your code wake up every 15 seconds might cost your users a lot of
battery life for little result, when the user isn't actively using
the
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
device. If you do some network activity every 15 seconds over a cell
network, you'll only have a few hours of battery life.
-if you really want to have a process stick around, you need to have
a
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Service in that process, so that the system can make the appropriate
decisions when it tries to make space for other applications. When
the
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
process that hosts your service is killed, it'll eventually get
restarted automatically, so you can restart whatever you were doing
in
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
the service's onCreate function. In that case, you'll find that
using
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
a Handler is a much better idea than using Thread.sleep.
-if you can work without necessarily having a process stay up all
the
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
time, you should look at the AlarmManager, which will allow the
system
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
to free the memory associated with your process between ticks.
JBQ
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot
has
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
completed. In this, I run a thread in the background process which
do
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}
private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes
run
Post by Jaikishan Jalan
and
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
sometime it does not run. I have to try launching the emulator
certain
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
times
Post by Jaikishan Jalan
before I get this thread running. I check this by checking the
server
Post by Jaikishan Jalan
log.
Post by JBQ
Post by Jaikishan Jalan
I
Post by Jaikishan Jalan
am not sure why this is happening. Can any point me out why this
is
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
happening? Or is anyone can suggest there is any other better way
to
Post by Jaikishan Jalan
Post by JBQ
Post by Jaikishan Jalan
Post by Jaikishan Jalan
approach this task.
Thanks,
Jaikishan
--
Thanks,
Jaikishan
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Mark Murphy
2008-07-14 12:19:11 UTC
Permalink
Post by Jaikishan Jalan
Alright. I guess I jumped in too quickly to shot out my problem . I
figured out a way (of course with the help of all you beautiful people
:) ) to run my service in background. What I have done is I first call a
service from my intent receiver. This service in turns creates an
instance of Alarm Manager. Since Alarm Manager broadcasts an intent, I
have another intent receiver, which receives this intent and run a
service which will do run my logic. It seems to work for me but not sure
if this is the most efficient and recommendable way to do this.
As hackbod indicated, the next SDK may allow you to drop the second
IntentReceiver outright, due to improvements in AlarmManager.

In the interim...you seem to have twice as many IntentReceivers and
Services than would seem necessary.

If this were my app, I would aim for:

-- IntentReceiver (A) receives the BOOT_COMPLETED Intent and uses that
to start the service

-- Service (B), on startup, registers an inner class IntentReceiver via
registerReceiver() for my private Intent, then sets up AlarmManager to
raise that Intent every N minutes, with the inner class IntentReceiver
doing the desired work.

Then, if that worked, I'd try to get rid of (A) by registering the
BOOT_COMPLETED intent-filter on (B), to see if I can knock this down to
a single service class (plus an inner IntentReceiver class).
--
Mark Murphy (a Commons Guy)
http://commonsware.com
Android Training on the Ranch in September! http://www.bignerdranch.com
Jaikishan Jalan
2008-07-14 18:28:45 UTC
Permalink
Super! Thanks Mark, your suggestion helped me to reduce the redudancy of my
code. Now my code works perfectly fine.

Thanks,
Jaikishan
Post by Mark Murphy
Post by Jaikishan Jalan
Alright. I guess I jumped in too quickly to shot out my problem . I
figured out a way (of course with the help of all you beautiful people
:) ) to run my service in background. What I have done is I first call a
service from my intent receiver. This service in turns creates an
instance of Alarm Manager. Since Alarm Manager broadcasts an intent, I
have another intent receiver, which receives this intent and run a
service which will do run my logic. It seems to work for me but not sure
if this is the most efficient and recommendable way to do this.
As hackbod indicated, the next SDK may allow you to drop the second
IntentReceiver outright, due to improvements in AlarmManager.
In the interim...you seem to have twice as many IntentReceivers and
Services than would seem necessary.
-- IntentReceiver (A) receives the BOOT_COMPLETED Intent and uses that
to start the service
-- Service (B), on startup, registers an inner class IntentReceiver via
registerReceiver() for my private Intent, then sets up AlarmManager to
raise that Intent every N minutes, with the inner class IntentReceiver
doing the desired work.
Then, if that worked, I'd try to get rid of (A) by registering the
BOOT_COMPLETED intent-filter on (B), to see if I can knock this down to
a single service class (plus an inner IntentReceiver class).
--
Mark Murphy (a Commons Guy)
http://commonsware.com
Android Training on the Ranch in September! http://www.bignerdranch.com
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Jaikishan Jalan
2008-07-14 19:04:24 UTC
Permalink
Hi Mark,

After doing some more testing, I observed that its still happening that the
background service sometime runs and sometime doesn't run. However this
time, the number of time the service gets run has increased :)

public class BootCompletedIntentReceiver extends IntentReceiver {
/* the intent source*/
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
private static final String LOG_TAG = "BootCompletedIntentReceiver";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
// Once we receive the BOOT_COMPLETED intent, we will start a service
that
// will start a service which in turn will run alarm manager
Intent i = new Intent();
i.setClassName("com.smartaddress",
"com.smartaddress.AddressLogService");
Bundle b = new Bundle();
ComponentName cname = context.startService( i,b );
if( cname == null )
Log.e( LOG_TAG,"AddressLogService was not started" );
else
Log.d( LOG_TAG,"AddressLogService started" );
}
}
}

public class AddressLogService extends Service {
private static final String LOG_TAG = "BackgroundService";
@Override
protected void onStart(int startId, Bundle arguments) {
super.onStart( startId, arguments );
Log.d( LOG_TAG, "onStart" );
Intent i = new Intent();
i.setClassName("com.smartaddress",
"com.smartaddress.AddressLoggerIntent");
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 10 *1000, i);
}

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

public class AddressLoggerIntent extends IntentReceiver
{
private static final String LOG_TAG = "AddressLoggerIntent";
@Override
public void onReceiveIntent(Context context, Intent intent)
{
Log.v(LOG_TAG, "AddressLogger Service Started");
// Logic
}
}

Any idea why it is happening now ? I am confused and a little frustated now
with this random behavior.

Thanks,
Jaikishan
Post by Jaikishan Jalan
Super! Thanks Mark, your suggestion helped me to reduce the redudancy of
my code. Now my code works perfectly fine.
Thanks,
Jaikishan
Post by Mark Murphy
Post by Jaikishan Jalan
Alright. I guess I jumped in too quickly to shot out my problem . I
figured out a way (of course with the help of all you beautiful people
:) ) to run my service in background. What I have done is I first call a
service from my intent receiver. This service in turns creates an
instance of Alarm Manager. Since Alarm Manager broadcasts an intent, I
have another intent receiver, which receives this intent and run a
service which will do run my logic. It seems to work for me but not sure
if this is the most efficient and recommendable way to do this.
As hackbod indicated, the next SDK may allow you to drop the second
IntentReceiver outright, due to improvements in AlarmManager.
In the interim...you seem to have twice as many IntentReceivers and
Services than would seem necessary.
-- IntentReceiver (A) receives the BOOT_COMPLETED Intent and uses that
to start the service
-- Service (B), on startup, registers an inner class IntentReceiver via
registerReceiver() for my private Intent, then sets up AlarmManager to
raise that Intent every N minutes, with the inner class IntentReceiver
doing the desired work.
Then, if that worked, I'd try to get rid of (A) by registering the
BOOT_COMPLETED intent-filter on (B), to see if I can knock this down to
a single service class (plus an inner IntentReceiver class).
--
Mark Murphy (a Commons Guy)
http://commonsware.com
Android Training on the Ranch in September! http://www.bignerdranch.com
--
Thanks,
Jaikishan
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Mark Murphy
2008-07-14 19:13:24 UTC
Permalink
Post by Jaikishan Jalan
After doing some more testing, I observed that its still happening that
the background service sometime runs and sometime doesn't run.
You might consider replacing:

long firstTime = SystemClock.elapsedRealtime();

with:

long firstTime = SystemClock.elapsedRealtime() + 10 *1000;

(where 10 *1000 is the time you're using between clock pulses).

In your current code, it may be that firstTime is technically in the past
by the time AlarmManager tries using the value, due to other processing in
the emulator, or just the clock ticking forward in between statements.
Setting the first time to be in the near future should resolve this
problem.

If that doesn't help, could you clarify what you mean when you say
"sometime runs and sometime doesn't run"? For example, I see various Log
statements in your code. When you don't get the expected behavior, what is
the log telling you?
--
Mark Murphy (a Commons Guy)
http://commonsware.com
_The Busy Coder's Guide to Android Development_ -- Available Now!
Jaikishan Jalan
2008-07-14 19:41:14 UTC
Permalink
Tried just now what you said. Still, the background process didnt start. I
am sure if I will launch the emulator one or twice more, I will get the
service running. The thing, is I dont get any of the log message at all
starting from the BootCompletedIntentReceiver. Do you think because I get
this BOOT_COMPLETED Intent sometime and sometime not ? Weird even when I am
writing this!

-Jaikishan
Post by Jaikishan Jalan
Post by Jaikishan Jalan
After doing some more testing, I observed that its still happening that
the background service sometime runs and sometime doesn't run.
long firstTime = SystemClock.elapsedRealtime();
long firstTime = SystemClock.elapsedRealtime() + 10 *1000;
(where 10 *1000 is the time you're using between clock pulses).
In your current code, it may be that firstTime is technically in the past
by the time AlarmManager tries using the value, due to other processing in
the emulator, or just the clock ticking forward in between statements.
Setting the first time to be in the near future should resolve this
problem.
If that doesn't help, could you clarify what you mean when you say
"sometime runs and sometime doesn't run"? For example, I see various Log
statements in your code. When you don't get the expected behavior, what is
the log telling you?
--
Mark Murphy (a Commons Guy)
http://commonsware.com
_The Busy Coder's Guide to Android Development_ -- Available Now!
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Jaikishan Jalan
2008-07-14 19:44:49 UTC
Permalink
If it can help, here is how my AndroidManifest.xml looks like.

<receiver android:name=".BootCompletedIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"
/>
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</receiver>
<service android:name=".AddressLogService"/>
<receiver android:name=".AddressLoggerIntent" />

Suprise, I launched my emulator again and the service started !

Thanks,
Jaikishan
Post by Jaikishan Jalan
Tried just now what you said. Still, the background process didnt start. I
am sure if I will launch the emulator one or twice more, I will get the
service running. The thing, is I dont get any of the log message at all
starting from the BootCompletedIntentReceiver. Do you think because I get
this BOOT_COMPLETED Intent sometime and sometime not ? Weird even when I am
writing this!
-Jaikishan
Post by Jaikishan Jalan
Post by Jaikishan Jalan
After doing some more testing, I observed that its still happening that
the background service sometime runs and sometime doesn't run.
long firstTime = SystemClock.elapsedRealtime();
long firstTime = SystemClock.elapsedRealtime() + 10 *1000;
(where 10 *1000 is the time you're using between clock pulses).
In your current code, it may be that firstTime is technically in the past
by the time AlarmManager tries using the value, due to other processing in
the emulator, or just the clock ticking forward in between statements.
Setting the first time to be in the near future should resolve this
problem.
If that doesn't help, could you clarify what you mean when you say
"sometime runs and sometime doesn't run"? For example, I see various Log
statements in your code. When you don't get the expected behavior, what is
the log telling you?
--
Mark Murphy (a Commons Guy)
http://commonsware.com
_The Busy Coder's Guide to Android Development_ -- Available Now!
--
Thanks,
Jaikishan
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Mark Murphy
2008-07-14 19:54:48 UTC
Permalink
Post by Jaikishan Jalan
The thing, is I dont get any of the log message at all
starting from the BootCompletedIntentReceiver.
Ick.
Post by Jaikishan Jalan
Do you think because I get
this BOOT_COMPLETED Intent sometime and sometime not ?
Off the cuff, that's the most likely reason, though it suggests either a
bug in Android or that you and I are missing something.

Try an IntentReceiver that does nothing but watch for BOOT_COMPLETED and
log a message when it arrives. If that sporadically fails, that really
feels like an unreliable Intent.

It is possible this is a bug related to this one already reported:

http://code.google.com/p/android/issues/detail?id=589&can=1&q=BOOT&colspec=ID%20Type%20Version%20Security%20Status%20Owner%20Summary

In their case, "sometimes Android does not think our application has the
right to access the location manager" when it attempts to get a location
at startup. Translated to your situation, it may be that
RECEIVE_BOOT_COMPLETED is not always recognized at the outset, and so your
IntentReceiver isn't included in the list of valid destinations, so you
don't get the Intent. But that's a complete guess.
--
Mark Murphy (a Commons Guy)
http://commonsware.com
_The Busy Coder's Guide to Android Development_ -- Available Now!
hackbod
2008-07-15 01:07:09 UTC
Permalink
Post by Mark Murphy
-- Service (B), on startup, registers an inner class IntentReceiver via
registerReceiver() for my private Intent, then sets up AlarmManager to
raise that Intent every N minutes, with the inner class IntentReceiver
doing the desired work.
This needs to be a top-level IntentReceiver (it could be the same as
the BOOT_COMPLETED one). Otherwise, when your service stops because
it is done with its work, upon being destroyed the registered intent
receiver will be unregistered (and you should see in the log a message
about it being leaked). Even if you have the service run all the
time, defeating the purpose of using the alarm manager, under very low
memory situations the system could need to kill its process, again
causing the registered receiver to be unregistered.
Mark Murphy
2008-07-15 01:31:02 UTC
Permalink
Post by hackbod
Post by Mark Murphy
-- Service (B), on startup, registers an inner class IntentReceiver via
registerReceiver() for my private Intent, then sets up AlarmManager to
raise that Intent every N minutes, with the inner class IntentReceiver
doing the desired work.
This needs to be a top-level IntentReceiver (it could be the same as
the BOOT_COMPLETED one). Otherwise, when your service stops because
it is done with its work, upon being destroyed the registered intent
receiver will be unregistered (and you should see in the log a message
about it being leaked). Even if you have the service run all the
time, defeating the purpose of using the alarm manager, under very low
memory situations the system could need to kill its process, again
causing the registered receiver to be unregistered.
To make sure I'm interpreting this correctly...the IntentReceiver that
is the recipient of the Intents raised by the AlarmManager must be one
registered in AndroidManifest.xml (vs. one registered via
registerReceiver()), or else it will fall out of memory if/when the
service does. And at that point, the AlarmManager is (presumably) still
set up to send Intents to a non-existent IntentReceiver.

I hadn't thought that all the way through, but it makes sense. That's a
facet of top-level IntentReceivers that I hadn't appreciated -- they're
"wired into" the Android runtime in such a way that they're always
registered, regardless of memory conditions.

Question: for Jaikishan's scenario, does he need the service? In other
words, does the IntentReceiver that handles Intents from the
AlarmManager have any particular speed requirement? I was under the
impression that IntentReceivers tied to activities might run on the UI
thread and so had to get their task done quickly...but will an
AlarmManager-triggered IntentReceiver have that same limitation? Or can
it do some network I/O and such before returning from onReceiveIntent(),
without impacting any foreground activity?

I'm just trying to figure out the right pattern for this case. I don't
think it's a stretch to say that a fair number of Android apps will be
of the poll-network-for-changes-and-do-something pattern, and so this is
an important area for us to get a best practice down pat. Heck, I'm
hoping we'll work up a common service or something, where activities can
register URLs to be polled and Intents to be fired if/when those
documents change, so we can optimize network access and minimize battery
consumption.

Thanks!
--
Mark Murphy (a Commons Guy)
http://commonsware.com
_The Busy Coder's Guide to Android Development_ Version 1.0 Published!
hackbod
2008-07-15 09:51:14 UTC
Permalink
Post by Mark Murphy
To make sure I'm interpreting this correctly...the IntentReceiver that
is the recipient of the Intents raised by the AlarmManager must be one
registered in AndroidManifest.xml (vs. one registered via
registerReceiver()), or else it will fall out of memory if/when the
service does. And at that point, the AlarmManager is (presumably) still
set up to send Intents to a non-existent IntentReceiver.
Yep. So it will just broadcast the Intent, there will be nobody
around to receive it, and *poof* that is the end of it.
Post by Mark Murphy
I hadn't thought that all the way through, but it makes sense. That's a
facet of top-level IntentReceivers that I hadn't appreciated -- they're
"wired into" the Android runtime in such a way that they're always
registered, regardless of memory conditions.
Yep, this is one of the key uses of receivers, they allow your
application to declare events it is interested in finding out about
even when it is not running. (Also they are a little cleaner to use
with the alarm manager, since because they are published in the
manifest, they are associated with an actual component, so the Intent
you make can be explicitly targeted at that component rather than
defining an ad-hoc action name.)
Post by Mark Murphy
Question: for Jaikishan's scenario, does he need the service? In other
words, does the IntentReceiver that handles Intents from the
AlarmManager have any particular speed requirement? I was under the
impression that IntentReceivers tied to activities might run on the UI
thread and so had to get their task done quickly...but will an
AlarmManager-triggered IntentReceiver have that same limitation? Or can
it do some network I/O and such before returning from onReceiveIntent(),
without impacting any foreground activity?
The onReceive() function does run on the main thread, so you can't
spend a lot of time in it. Currently, even if your main thread is not
being asked to do other things like handle input events, if the
receiver takes more than 10 seconds then the user will get an
Application Not Responding dialog. So if you are going to do a longer-
running (or asynchronous) thing, you will need to have that wrapped in
a service. Of course networking stuff definitely falls in this
category.
Post by Mark Murphy
I'm just trying to figure out the right pattern for this case. I don't
think it's a stretch to say that a fair number of Android apps will be
of the poll-network-for-changes-and-do-something pattern, and so this is
an important area for us to get a best practice down pat.
The "Alarm Service" sample code in ApiDemos at
http://code.google.com/android/samples/ApiDemos/src/com/google/android/samples/app/
is intended to provide the best practices for this. The current
example is a little overly complex because of the need of the
intermediate receiver. In a future SDK where you can have the alarm
manager directly start a service, this is a lot cleaner.
Post by Mark Murphy
Heck, I'm
hoping we'll work up a common service or something, where activities can
register URLs to be polled and Intents to be fired if/when those
documents change, so we can optimize network access and minimize battery
consumption.
Yeah this would be a useful facility.
Jaikishan Jalan
2008-07-15 10:01:36 UTC
Permalink
Hello,

As I mentioned in my last email about the random behavior of my application,
I have observed that my application many times does not receive
BOOT_COMPLETED action. Due to this my background process does not get
started. Is this a known bug that it is not definite that your
intentreceiver (listening to BOOT_COMPLETED) will not get executed everytime
when you launch the emulator? I have verified this by simply printing a log
message. Sometimes the message is logged ( when my application receive the
intent ) and many times it does not. Can anyone from Google Android team
confirm this?
Post by hackbod
Post by Mark Murphy
To make sure I'm interpreting this correctly...the IntentReceiver that
is the recipient of the Intents raised by the AlarmManager must be one
registered in AndroidManifest.xml (vs. one registered via
registerReceiver()), or else it will fall out of memory if/when the
service does. And at that point, the AlarmManager is (presumably) still
set up to send Intents to a non-existent IntentReceiver.
Yep. So it will just broadcast the Intent, there will be nobody
around to receive it, and *poof* that is the end of it.
Post by Mark Murphy
I hadn't thought that all the way through, but it makes sense. That's a
facet of top-level IntentReceivers that I hadn't appreciated -- they're
"wired into" the Android runtime in such a way that they're always
registered, regardless of memory conditions.
Yep, this is one of the key uses of receivers, they allow your
application to declare events it is interested in finding out about
even when it is not running. (Also they are a little cleaner to use
with the alarm manager, since because they are published in the
manifest, they are associated with an actual component, so the Intent
you make can be explicitly targeted at that component rather than
defining an ad-hoc action name.)
Post by Mark Murphy
Question: for Jaikishan's scenario, does he need the service? In other
words, does the IntentReceiver that handles Intents from the
AlarmManager have any particular speed requirement? I was under the
impression that IntentReceivers tied to activities might run on the UI
thread and so had to get their task done quickly...but will an
AlarmManager-triggered IntentReceiver have that same limitation? Or can
it do some network I/O and such before returning from onReceiveIntent(),
without impacting any foreground activity?
The onReceive() function does run on the main thread, so you can't
spend a lot of time in it. Currently, even if your main thread is not
being asked to do other things like handle input events, if the
receiver takes more than 10 seconds then the user will get an
Application Not Responding dialog. So if you are going to do a longer-
running (or asynchronous) thing, you will need to have that wrapped in
a service. Of course networking stuff definitely falls in this
category.
Post by Mark Murphy
I'm just trying to figure out the right pattern for this case. I don't
think it's a stretch to say that a fair number of Android apps will be
of the poll-network-for-changes-and-do-something pattern, and so this is
an important area for us to get a best practice down pat.
The "Alarm Service" sample code in ApiDemos at
http://code.google.com/android/samples/ApiDemos/src/com/google/android/samples/app/
is intended to provide the best practices for this. The current
example is a little overly complex because of the need of the
intermediate receiver. In a future SDK where you can have the alarm
manager directly start a service, this is a lot cleaner.
Post by Mark Murphy
Heck, I'm
hoping we'll work up a common service or something, where activities can
register URLs to be polled and Intents to be fired if/when those
documents change, so we can optimize network access and minimize battery
consumption.
Yeah this would be a useful facility.
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
hackbod
2008-07-16 00:26:58 UTC
Permalink
It is not an issue I am aware of. That facility is used extensively
by our own apps, and I don't know of them having a problem with it.
Post by Jaikishan Jalan
Hello,
As I mentioned in my last email about the random behavior of my application,
I have observed that my application many times does not receive
BOOT_COMPLETED action. Due to this my background process does not get
started. Is this a known bug that it is not definite that your
intentreceiver (listening to BOOT_COMPLETED) will not get executed everytime
when you launch the emulator? I have verified this by simply printing a log
message. Sometimes the message is logged ( when my application receive the
intent ) and many times it does not. Can anyone from Google Android team
confirm this?
Post by Mark Murphy
To make sure I'm interpreting this correctly...the IntentReceiver that
is the recipient of the Intents raised by the AlarmManager must be one
registered in AndroidManifest.xml (vs. one registered via
registerReceiver()), or else it will fall out of memory if/when the
service does. And at that point, the AlarmManager is (presumably) still
set up to send Intents to a non-existent IntentReceiver.
Yep.  So it will just broadcast the Intent, there will be nobody
around to receive it, and *poof* that is the end of it.
Post by Mark Murphy
I hadn't thought that all the way through, but it makes sense. That's a
facet of top-level IntentReceivers that I hadn't appreciated -- they're
"wired into" the Android runtime in such a way that they're always
registered, regardless of memory conditions.
Yep, this is one of the key uses of receivers, they allow your
application to declare events it is interested in finding out about
even when it is not running.  (Also they are a little cleaner to use
with the alarm manager, since because they are published in the
manifest, they are associated with an actual component, so the Intent
you make can be explicitly targeted at that component rather than
defining an ad-hoc action name.)
Post by Mark Murphy
Question: for Jaikishan's scenario, does he need the service? In other
words, does the IntentReceiver that handles Intents from the
AlarmManager have any particular speed requirement? I was under the
impression that IntentReceivers tied to activities might run on the UI
thread and so had to get their task done quickly...but will an
AlarmManager-triggered IntentReceiver have that same limitation? Or can
it do some network I/O and such before returning from onReceiveIntent(),
without impacting any foreground activity?
The onReceive() function does run on the main thread, so you can't
spend a lot of time in it.  Currently, even if your main thread is not
being asked to do other things like handle input events, if the
receiver takes more than 10 seconds then the user will get an
Application Not Responding dialog.  So if you are going to do a longer-
running (or asynchronous) thing, you will need to have that wrapped in
a service.  Of course networking stuff definitely falls in this
category.
Post by Mark Murphy
I'm just trying to figure out the right pattern for this case. I don't
think it's a stretch to say that a fair number of Android apps will be
of the poll-network-for-changes-and-do-something pattern, and so this is
an important area for us to get a best practice down pat.
The "Alarm Service" sample code in ApiDemos at
http://code.google.com/android/samples/ApiDemos/src/com/google/androi...
is intended to provide the best practices for this.  The current
example is a little overly complex because of the need of the
intermediate receiver.  In a future SDK where you can have the alarm
manager directly start a service, this is a lot cleaner.
Post by Mark Murphy
Heck, I'm
hoping we'll work up a common service or something, where activities can
register URLs to be polled and Intents to be fired if/when those
documents change, so we can optimize network access and minimize battery
consumption.
Yeah this would be a useful facility.
--
Thanks,
Jaikishan
Jaikishan Jalan
2008-07-16 07:14:51 UTC
Permalink
Oh. I wonder where could be the problem. One possible location could be in
my AndroidManifest.xml. Here is how it looks like :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.smartaddress">
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="@drawable/icon">
<activity android:name=".SearchMap"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".BootCompletedIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"
/>
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
</application>
</manifest>

Do you think this is ok ?
Post by hackbod
It is not an issue I am aware of. That facility is used extensively
by our own apps, and I don't know of them having a problem with it.
Post by Jaikishan Jalan
Hello,
As I mentioned in my last email about the random behavior of my
application,
Post by Jaikishan Jalan
I have observed that my application many times does not receive
BOOT_COMPLETED action. Due to this my background process does not get
started. Is this a known bug that it is not definite that your
intentreceiver (listening to BOOT_COMPLETED) will not get executed
everytime
Post by Jaikishan Jalan
when you launch the emulator? I have verified this by simply printing a
log
Post by Jaikishan Jalan
message. Sometimes the message is logged ( when my application receive
the
Post by Jaikishan Jalan
intent ) and many times it does not. Can anyone from Google Android team
confirm this?
Post by hackbod
Post by Mark Murphy
To make sure I'm interpreting this correctly...the IntentReceiver
that
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
is the recipient of the Intents raised by the AlarmManager must be
one
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
registered in AndroidManifest.xml (vs. one registered via
registerReceiver()), or else it will fall out of memory if/when the
service does. And at that point, the AlarmManager is (presumably)
still
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
set up to send Intents to a non-existent IntentReceiver.
Yep. So it will just broadcast the Intent, there will be nobody
around to receive it, and *poof* that is the end of it.
Post by Mark Murphy
I hadn't thought that all the way through, but it makes sense. That's
a
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
facet of top-level IntentReceivers that I hadn't appreciated --
they're
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
"wired into" the Android runtime in such a way that they're always
registered, regardless of memory conditions.
Yep, this is one of the key uses of receivers, they allow your
application to declare events it is interested in finding out about
even when it is not running. (Also they are a little cleaner to use
with the alarm manager, since because they are published in the
manifest, they are associated with an actual component, so the Intent
you make can be explicitly targeted at that component rather than
defining an ad-hoc action name.)
Post by Mark Murphy
Question: for Jaikishan's scenario, does he need the service? In
other
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
words, does the IntentReceiver that handles Intents from the
AlarmManager have any particular speed requirement? I was under the
impression that IntentReceivers tied to activities might run on the
UI
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
thread and so had to get their task done quickly...but will an
AlarmManager-triggered IntentReceiver have that same limitation? Or
can
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
it do some network I/O and such before returning from
onReceiveIntent(),
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
without impacting any foreground activity?
The onReceive() function does run on the main thread, so you can't
spend a lot of time in it. Currently, even if your main thread is not
being asked to do other things like handle input events, if the
receiver takes more than 10 seconds then the user will get an
Application Not Responding dialog. So if you are going to do a longer-
running (or asynchronous) thing, you will need to have that wrapped in
a service. Of course networking stuff definitely falls in this
category.
Post by Mark Murphy
I'm just trying to figure out the right pattern for this case. I
don't
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
think it's a stretch to say that a fair number of Android apps will
be
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
of the poll-network-for-changes-and-do-something pattern, and so this
is
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
an important area for us to get a best practice down pat.
The "Alarm Service" sample code in ApiDemos at
http://code.google.com/android/samples/ApiDemos/src/com/google/androi.
..
Post by Jaikishan Jalan
Post by hackbod
is intended to provide the best practices for this. The current
example is a little overly complex because of the need of the
intermediate receiver. In a future SDK where you can have the alarm
manager directly start a service, this is a lot cleaner.
Post by Mark Murphy
Heck, I'm
hoping we'll work up a common service or something, where activities
can
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
register URLs to be polled and Intents to be fired if/when those
documents change, so we can optimize network access and minimize
battery
Post by Jaikishan Jalan
Post by hackbod
Post by Mark Murphy
consumption.
Yeah this would be a useful facility.
--
Thanks,
Jaikishan
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Mark Murphy
2008-07-16 12:29:37 UTC
Permalink
Post by Jaikishan Jalan
Oh. I wonder where could be the problem. One possible location could be
<snip>
Post by Jaikishan Jalan
Do you think this is ok ?
AFAIK, your uses-permission element is in the proper spot.

Are you sure that "android.intent.category.HOME" is the proper category,
and not "android.intent.category.DEFAULT"?
--
Mark Murphy (a Commons Guy)
http://commonsware.com
Android Training on the Ranch in September! http://www.bignerdranch.com
Jaikishan Jalan
2008-07-16 12:49:56 UTC
Permalink
I read the docs but could not really understand DEFAULT category. Can you
please explain what is the difference between - HOME and DEFAULT Category?
Post by Mark Murphy
Post by Jaikishan Jalan
Oh. I wonder where could be the problem. One possible location could be
<snip>
Post by Jaikishan Jalan
Do you think this is ok ?
AFAIK, your uses-permission element is in the proper spot.
Are you sure that "android.intent.category.HOME" is the proper category,
and not "android.intent.category.DEFAULT"?
--
Mark Murphy (a Commons Guy)
http://commonsware.com
Android Training on the Ranch in September! http://www.bignerdranch.com
--
Thanks,
Jaikishan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Mark Murphy
2008-07-16 14:02:27 UTC
Permalink
Post by Jaikishan Jalan
I read the docs but could not really understand DEFAULT category. Can
you please explain what is the difference between - HOME and DEFAULT
Category?
Heh. I can try.

The docs say that HOME is "the first activity that is displayed when the
device boots". In other words, that's for the Launcher itself.

The definition of DEFAULT seems to be somewhat inconsistent in the
current SDK documentation. On the one hand, it is described as "the
default action (center press) to perform on a piece of data", yet it is
used in the ApiDemos only for the main activity, and elsewhere in the
Intent documentation it is shown sprinkled in pretty much every
intent-filter they have.

The key for categories and intent-filter elements seem to be: when in
doubt, list anything that might match. You are penalized for not having
the right category, by not getting the Intents you expect. You are NOT
penalized for having too many -- if the Intent only matches some of what
your filter wants, that's perfectly fine.

You might try tossing in DEFAULT into your intent-filter, and maybe
LAUNCHER too, and see what happens. And, if we're lucky, hackbod or
somebody will let us know the actual category we're supposed to be
filtering upon. The only tutorial I'm seeing that spells it out, over on
anddev.org, is from January, meaning it would be on the previous version
of the SDK, so it might have changed in M5.

And, as an aside to anyone writing documentation for Android core or
third-party components: if you are going to broadcast Intents that you
expect others to pick up, please document BOTH the action AND the
category, not just the action. If not, those of us trying to receive
your Intent will have to guess, and, as a result, might be eaten by a grue.
--
Mark Murphy (a Commons Guy)
http://commonsware.com
Warescription: All titles, revisions, & ebook formats, just $35/year
Kamy
2008-07-13 21:02:57 UTC
Permalink
We might need this for auto-booting.

- Kamy
Post by Jaikishan Jalan
Hello,
I have written an intentreceiver which gets launched when the boot has
completed. In this, I run a thread in the background process which do
public class AddressLogService extends IntentReceiver{
/* the intent source*/
static final String ACTION =
"android.intent.action.BOOT_COMPLETED";
@Override
public void onReceiveIntent(Context context, Intent intent) {
if (intent.getAction().equals(ACTION))
{
NewRunnable AddressLog = new NewRunnable(context);
Thread tr = new Thread(null,AddressLog,"Address Logger");
tr.start();
}
}
private class NewRunnable implements Runnable {
private Context context;
// Initializing the Runnable Class
public NewRunnable(Context c){
context = c;
}
public void run(){
while(true){
isServerUp = true;
if(isServerUp ){
// Do some processing
Thread.sleep(15 * 1000);
}
}catch(Exception e){}
}
}
}
}
I have included the required receiver details and permission in
AndroidManifest.xml
The problem is when I launch my emulator, this thread sometimes run and
sometime it does not run. I have to try launching the emulator certain times
before I get this thread running. I check this by checking the server log. I
am not sure why this is happening. Can any point me out why this is
happening? Or is anyone can suggest there is any other better way to
approach this task.
Thanks,
Jaikishan
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Continue reading on narkive:
Loading...