Under some conditions, my application gets started by calling one of
my Broadcast-Receivers or Services (etc), but I want to prevent the
component that is used for the intent to get started.
Why: Because I need to do some prior initialization work do run, before any
component should start. But this work can be a long running thing,
therefore I can not just execute it inside of my application subclass on the main thread.
I am subclassing the Application in my app. Therefore my approach would be
to somehow intervent the intent in the onCreate() of my application subclass and
instead, start a specific service of mine, which runs the prior-initialization
and re-calls the intent, that was intentionally used after that.
Can you image any possibly do get this done?
Thank you!
Ps.: I have a lot components that could possibly start my application. I do not want to include my condition-code inside of every component.
but I want to prevent the component that is used for the intent to get started.
Other than crashing your app, this is not possible. And, even then, the component would never be started.
Therefore my approach would be to somehow intervent the intent in the onCreate() of my application subclass and instead, start a specific service of mine, which runs the prior-initialization and re-calls the intent, that was intentionally used after that.
Short of a custom ROM with a custom framework implementation, this is not possible. You do not have access to the information that you need, nor do you have any means of stopping the component.
And, if you are in a case where a custom ROM is a possibility, move this initialization work to a core OS process (i.e., not an Android SDK app, but a standard Linux process started at boot time), and have your app use IPC to get this data.
Related
I'm developing a geolocation based app for Android. I'm still beginning to understand how the framework works, so I'm not really sure if I'm doing things right.
The app has some custom View classes that are created within Activity classes and Layout components and mostly only render data. There is also a single Service that gets GPS updates using the Location API, read/write data, handle data and send it to the Views using Broadcasts. The Service is supposed to run as long as the app itself, but keep working on background indefinitely when the app is minimized.
The service is started on the base activity (which all activities extend) using:
startService(new Intent(BaseActivity.this, MyService.class));
It then proceeds to do its thing on an overrided onCreate method and periodically sends Broadcasts with data which the Activities and the Views listen to independently.
For me it seemed like a good setup, but I'm not sure since I started have some ANR problems after it's been started for some time (I let it sit overnight for testing and open it in the morning to an ANR screen).
I've read around about BoundServices and IntentServices, but it looked to me that my setup makes more sense (even though this whole thing is a bit confusing for me). So, am I in the right path? Or is this ANR error a warning to change it?
I have a long running background task that I would like to start when the app launches and shutdown when the application shuts down. I'm already quite aware of the activity life cycle and what gets called when an activity gets created and destroyed.
I'm coming from an iOS background, and over there we have some calls that are made during application startup and shutdown. Is there something similar in the android world? I've searched a lot and all I'm finding are answers relating to an activity, not the entire application.
(Android is relatively new to me, so I may just not know the correct terminology to search for.)
EDIT:
I'll try an be a bit more specific. I have a background task that needs to be continuously running while the user is using the application. It will be streaming data from a server continuously while the application is active. It does not need to run when the application is in the background. It doesn't seem to make sense to me to tie the startup / shutdown of this background process to any one single activity since it may not be the same one activity that starts up when the application becomes active.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses. If that is, in fact, the case, then all I really need to do is spin up the background task when the application first launches, i.e. when it is loaded into memory and becomes active for the first time that session.
It doesn't seem to make sense to me to tie the startup / shutdown of this background task to any one single activity since it may not be the same one activity that starts up when the application becomes active.
That's reasonable. It is somewhat difficult to implement, though.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses.
You have it exactly backwards. Android pays not one whit of attention to any threads that you fork yourself, directly or via thin wrappers like AsyncTask.
In addition to that point of confusion, you appear to be equating "user switching to another app" with "app shutdown". Those may be the same thing in single-tasking operating systems. They are not the same thing in Windows, OS X, Linux, Android, etc.
So, what you seem to be seeking is having a background thread running doing this streaming work while your UI is in the foreground, and then stop when your UI is in the background. The problem is that there really isn't a straightforward way of accomplishing that in Android.
One close approximation would be to create and register a custom Application class, where you override onTrimMemory(), and stop your background work when you get to TRIM_MEMORY_UI_HIDDEN, TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_MODERATE, or TRIM_MEMORY_COMPLETE -- whichever of those that you encounter first. If, when one of those arrives, you determine that your streaming thread is still outstanding, shut it down.
In terms of startup, you could use onCreate() on that same Application singleton. The problem is that this will be called on any process creation, which may include scenarios in which you do not have UI (e.g., you are responding to some system broadcast, like ACTION_BOOT_COMPLETED), or possibly your process is going to parts of your UI that do not depend on the streaming. If you have none of those scenarios, then onCreate() in Application would be fine. Otherwise, kick off the streaming in onCreate() of whatever activities need it.
While normally we manage long-running threads with a Service, that is for cases where we explicitly want the thread to continue after our UI is in the background. Since you do not want that, you could skip the service.
It depends on what you want to do exactly. When you're just interested in the app starting for the first time you could #Override onCreate().
Or maybe you want to use onResume() as this will get called whenever a user brings the app to the foreground.
But this really depends on what exactly your background task is doing and what you want to do with it, to get an exact answer you need to provide more details.
Here is an overview for the actiity life cycle that should help you:
You can extend the default Application class and implement it's onCreate() method to detect when the app is launched. There is no corresponding method for when the app gets closed though.
Do not forget to specify it in the Manifest file.
In Android the application isn't shut down unless the system runs low on memory. You won't get a warning about that, it will just call your Service's onDestroy lifecycle method. If you want to do it when the Activity is visible on screen, use onStart and onStop. If you want to do it when the Activity is resident in memory, use onCreate and onDestroy.
I got a situation where i have two APPS for simplicity keep it as APP1 and APP2, i am passing an object remoteCallback as CALLBACK from APP1 to APP2 for future use.
where based on result APP2 will instantiate a method updateStatus(String msg) using a object remoteCallback, Everything is working fine but, when i close the APP1 and clears the memory, APP2 is unable to call the method i know what causes this problem i want to know is there any way to make the object(remoteCallback) live even the APP1 closed.
Thanks in advance.
I'd use an unbound Service here. Unbound services make that even if one of your apps close, if the conditions permit it, it will still be running in the background. If you used a bound Service, it would stop with your app if your app stopped.
This differs from an AsyncTask or a Thread, because even if they run in the background, there's a big change of being killed if Android needs more memory or is in lack of resources.
This introduce, however, a new responsibility for you: You'll have to make sure you use startService() or stopService() accordingly within your app and don't leave your Service running indefinitely.
This seems to be a good example about how it works, but you might find lots of documentation about unbound Services
There is no way we cant stop an app from destroy so instead of passing an callback to get details use BROADCAST RECEIVER.
This is the solution i adapted to this situation.
"I want to know is there any way to make the object(remoteCallback) live even the APP1 closed."
PendingIntent ?...
Its the same mechanism used on notifications.
You can start the background service and the store the object which you want to live object after the app is closing
you can declare the public static data member and you use the whole application
It's my understanding that Android services are supposed to be singletons - no more than one class instance running at a time. So you're supposed to start them via intents, as opposed to
MyService mse = new MyService();
However, in Google's in-app billing sample, that's exactly what they do in Dungeons.java, line 235. So it's obviously legal.
I'm wondering, if I start a service like this, will the framework later recognize that it's running? In other words, if I try to call startService() on the same service later on, will the framework recognize that an instance of the service already exists and dispatch startService() calls to it?
I don't know what example you are referring to. But you absolutely positively cannot instantiate an Android component (Activity, BroadcastReceiver, Service, Provider) yourself using the new keyword. These components can only be instantiated by the Android framework, as the framework needs to set up the Context of the component.
There is (unfortunately) nothing stopping you from writing Service s = new MyService();, but it will do you no good. Android will never call any of the lifecycle mathods on this Service and any calls you make to methods of the Service will probably fail spectacularly because the instance has no Context.
If you instantiate the service directly instead of using intents that guarantees the service will run within your Activities process. If that activity should be killed then down goes the service too. Is that a bad practice? Well it depends on what you wanted. If you need that service to live through potential shutdowns of activities then yes that's a bad thing to do. If you don't care or your app can tolerate those shutdowns then it's ok. However, I'd argue if you need a background job running that can be stopped when your Activity stops then you need to use AsyncTask and NOT a service.
I am writing a social game but am stuck with how to create a timer thread that works accross activities showing time lapse for an attribute such as energy. Every activity has the energy textview but the thread can update only one view at a time. Please note that im not using androids timer class but have created my own thread class.
You probably don't want to try to keep a thread running between activities. Managing it when the activity suspends will give you nothing but headaches. It's much easier to just store your time in the Application while you move from activity to activity. The Application is alive for the duration, no matter which Activity is actually loaded. The fact that you have an identically named TextView in various activities is neither here nor there... it's not the "same" TextView... it just looks (and smells) similar. So, you can just grab the clock when the app first launches and at any given time look at the difference between the current time and that time.
Then just use a Timer to update the string in whatever Activity you're in.
If you're unfamiliar with Application it's going to be a real Eureka thing for you to discover (Android tutorials overlook it ALL the time, for some reason, leaving you to do all sorts of really ugly Intent passing alternatives).
If you have any questions on how to use it, just follow up in a comment, and I'll add details.
I think you must think about using a Service :
Thus a Service itself is actually very simple, providing two main
features:
A facility for the application to tell the system about something it wants to be doing in the background (even when the user is not
directly interacting with the application). This corresponds to calls
to Context.startService(), which ask the system to schedule work for
the service, to be run until the service or someone else explicitly
stop it.
A facility for an application to expose some of its functionality to other applications. This corresponds to calls to
Context.bindService(), which allows a long-standing connection to be
made to the service in order to interact with it. When a Service
component is actually created, for either of these reasons, all that
the system actually does is instantiate the component and call its
onCreate() and any other appropriate callbacks on the main thread. It
is up to the Service to implement these with the appropriate behavior,
such as creating a secondary thread in which it does its work.