Android Lifecycle - how to ensure that one method is always called? - android

What must I do in order to ensure that the app is always initialised, even if the user or OS kills it?
public static void init(){/*some init and checks here*/}
if an MyAlarmReceiver.onReceive() or MyBroadcastReceiver.onReceive() is called by the OS... how to automatically call init() without putting it as the first statement in the MyAlarmReceiver.onReceive(), MyBroadcastReceiver.onReceive(), etc?

Create a class that extends Application and put the statement in the onCreate method
Ref: https://developer.android.com/reference/android/app/Application.html#onCreate()

You can add a static block in your class, this code block will be executed when this class this loaded by ClassLoader, that means any usage of this class will cause the ClassLoader load this class into memory
public class Test extends BroadcastReceiver{
static{
//do something
}
}

Related

Call startSerice() from anywhere in the app code

I would like to automatically insert some crafted code to any possible parts of the target app code. This crafted code includes a "context.startService()" to contact with a remote service from another app. How can I automatically get this context instance so that I can call startService() from anywhere within the app code?
Thanks a lot in advance. Any inputs are highly appreciated.
If I understand correctly, you want to start a service from anywhere within your codebase without passing around context objects. The solution below is a way to do this but look at this post to get a better understanding of why this isn't always the best solution.
Create a class that extends from Application:
import android.app.Application;
public class MyApplication extends Application {
private static Application sInstance;
public MyApplication() {
sInstance = this;
}
public static Application getInstance() {
return sInstance;
}
}
This will give you access to your application's context so you can start a service from anywhere.
Now in some part of your code:
void foo() {
MyApplication.getInstance().startService(new Intent(MY_SERVICE));
}
create a new method, that gets your context, and then calls your service with said context, then call that method instead.
shouldnt change your code much....

Why extend the Android Application class?

An extended Application class can declare global variables. Are there other reasons?
Introduction:
If we consider an apk file in our mobile, it is comprised of
multiple useful blocks such as, Activitys, Services and
others.
These components do not communicate with each other regularly and
not forget they have their own life cycle. which indicate that
they may be active at one time and inactive the other moment.
Requirements:
Sometimes we may require a scenario where we need to access a
variable and its states across the entire Application regardless of
the Activity the user is using,
An example is that a user might need to access a variable that holds his
personnel information (e.g. name) that has to be accessed across the
Application,
We can use SQLite but creating a Cursor and closing it again and
again is not good on performance,
We could use Intents to pass the data but it's clumsy and activity
itself may not exist at a certain scenario depending on the memory-availability.
Uses of Application Class:
Access to variables across the Application,
You can use the Application to start certain things like analytics
etc. since the application class is started before Activitys or
Servicess are being run,
There is an overridden method called onConfigurationChanged() that is
triggered when the application configuration is changed (horizontal
to vertical & vice-versa),
There is also an event called onLowMemory() that is triggered when
the Android device is low on memory.
Application class is the object that has the full lifecycle of your application. It is your highest layer as an application. example possible usages:
You can add what you need when the application is started by overriding onCreate in the Application class.
store global variables that jump from Activity to Activity. Like Asynctask.
etc
Sometimes you want to store data, like global variables which need to be accessed from multiple Activities - sometimes everywhere within the application. In this case, the Application object will help you.
For example, if you want to get the basic authentication data for each http request, you can implement the methods for authentication data in the application object.
After this,you can get the username and password in any of the activities like this:
MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();
And finally, do remember to use the Application object as a singleton object:
public class MyApplication extends Application {
private static MyApplication singleton;
public MyApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
For more information, please Click Application Class
Offhand, I can't think of a real scenario in which extending Application is either preferable to another approach or necessary to accomplish something. If you have an expensive, frequently used object you can initialize it in an IntentService when you detect that the object isn't currently present. Application itself runs on the UI thread, while IntentService runs on its own thread.
I prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences. There are also ways to pass data from a Fragment to its parent Activity using interfaces.
The Application class is a singleton that you can access from any activity or anywhere else you have a Context object.
You also get a little bit of lifecycle.
You could use the Application's onCreate method to instantiate expensive, but frequently used objects like an analytics helper. Then you can access and use those objects everywhere.
Best use of application class.
Example: Suppose you need to restart your alarm manager on boot completed.
public class BaseJuiceApplication extends Application implements BootListener {
public static BaseJuiceApplication instance = null;
public static Context getInstance() {
if (null == instance) {
instance = new BaseJuiceApplication();
}
return instance;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onBootCompleted(Context context, Intent intent) {
new PushService().scheduleService(getInstance());
//startToNotify(context);
}
Not an answer but an observation: keep in mind that the data in the extended application object should not be tied to an instance of an activity, as it is possible that you have two instances of the same activity running at the same time (one in the foreground and one not being visible).
For example, you start your activity normally through the launcher, then "minimize" it. You then start another app (ie Tasker) which starts another instance of your activitiy, for example in order to create a shortcut, because your app supports android.intent.action.CREATE_SHORTCUT. If the shortcut is then created and this shortcut-creating invocation of the activity modified the data the application object, then the activity running in the background will start to use this modified application object once it is brought back to the foreground.
I see that this question is missing an answer. I extend Application because I use Bill Pugh Singleton implementation (see reference) and some of my singletons need context. The Application class looks like this:
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private static MyApplication sInstance;
#Contract(pure = true)
#Nullable
public static Context getAppContext() {
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() called");
sInstance = this;
}
}
And the singletons look like this:
public class DataManager {
private static final String TAG = DataManager.class.getSimpleName();
#Contract(pure = true)
public static DataManager getInstance() {
return InstanceHolder.INSTANCE;
}
private DataManager() {
doStuffRequiringContext(MyApplication.getAppContext());
}
private static final class InstanceHolder {
#SuppressLint("StaticFieldLeak")
private static final DataManager INSTANCE = new DataManager();
}
}
This way I don't need to have a context every time I'm using a singleton and get lazy synchronized initialization with minimal amount of code.
Tip: updating Android Studio singleton template saves a lot of time.
I think you can use the Application class for many things, but they are all tied to your need to do some stuff BEFORE any of your Activities or Services are started.
For instance, in my application I use custom fonts. Instead of calling
Typeface.createFromAsset()
from every Activity to get references for my fonts from the Assets folder (this is bad because it will result in memory leak as you are keeping a reference to assets every time you call that method), I do this from the onCreate() method in my Application class:
private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
super.onCreate();
appInstance = this;
quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
"fonts/Quicksand-Regular.otf");
...
}
Now, I also have a method defined like this:
public static App getAppInstance() {
return appInstance;
}
and this:
public Typeface getQuickSandRegular() {
return quicksandRegular;
}
So, from anywhere in my application, all I have to do is:
App.getAppInstance().getQuickSandRegular()
Another use for the Application class for me is to check if the device is connected to the Internet BEFORE activities and services that require a connection actually start and take necessary action.
Source: https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class
In many apps, there's no need to work with an application class directly. However, there are a few acceptable uses of a custom application class:
Specialized tasks that need to run before the creation of your first activity
Global initialization that needs to be shared across all components (crash reporting, persistence)
Static methods for easy access to static immutable data such as a shared network client object
You should never store mutable instance data inside the Application object because if you assume that your data will stay there, your application will inevitably crash at some point with a NullPointerException. The application object is not guaranteed to stay in memory forever, it will get killed. Contrary to popular belief, the app won’t be restarted from scratch. Android will create a new Application object and start the activity where the user was before to give the illusion that the application was never killed in the first place.
To add onto the other answers that state that you might wish store variables in the application scope, for any long-running threads or other objects that need binding to your application where you are NOT using an activity (application is not an activity).. such as not being able to request a binded service.. then binding to the application instance is preferred. The only obvious warning with this approach is that the objects live for as long as the application is alive, so more implicit control over memory is required else you'll encounter memory-related problems like leaks.
Something else you may find useful is that in the order of operations, the application starts first before any activities. In this timeframe, you can prepare any necessary housekeeping that would occur before your first activity if you so desired.
2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
You can access variables to any class without creating objects, if its extended by Application. They can be called globally and their state is maintained till application is not killed.
The use of extending application just make your application sure for any kind of operation that you want throughout your application running period. Now it may be any kind of variables and suppose if you want to fetch some data from server then you can put your asynctask in application so it will fetch each time and continuously, so that you will get a updated data automatically.. Use this link for more knowledge....
http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android

Unable to access the methods from one class to another class in android

Unable to access the methods from one class to another class in android.
Actually, what I am trying is
ClassA.java
class ClassA extends Activity
{
method_1();
}
ClassB.java
class ClassB extends BroadCastReciever
{
// I need to access the method_1 from the class ClassA.
}
How can I do this?
First Solution
Declare your method1() as follows -
public static void method_1()
{
}
Then you can access it from ClassB as follows -
ClassA.method1();
Second Solution
Create an object of ClassA and access method1() from ClassB as follows-
ClassA classA = new ClassA();
classA.method1();
EDIT:
If both the classes are in the same package then you can use protected instead of public in the First Solution.
inside ClassA declare public method from ClassB create object of ClassA and access method using object
write below code inside ClassB
Like
ClassA classa = new ClassA();
classa.method_1();
Note :
if possible don't create class as static if it is not necessary.
provide class modifier to public.
mark method_1(); as public and static
Eg:
class ClassA extends Activity
{
public void static method_1();
}
Then you should be able to access method_1(); without creating a object of class A.
i guess you cant access a method from a class that extends an activity in android , however you can add an inner or helper class to the activity class like this example :
Call a public method in the Activity class from another class?
there is two way to access it
1) you need to create method as public static method() so that you can access it anywhere by calling class name dot method name like Aaa.method();
2)or you need a object to call method like passing Aaa's object to broadcast class and call method on it.
EDIT:
if you are passing context from activity A to brodcast class then you can convert context into activity object to call its public methods.
like:
in brodcast class:
((yourActivityName)context).method();
Basically you can call any method from another class, as long as it's public. If the method is static, you don't even need to instantiate it. But read some tutorials to get the basic idea of OOP instead of just looking for a solution for your specific problem, it'll help a lot more!
You should never be able to to that ... How do you know if the activity is still alive? The best way to send messages from BroadcastReceivers to Activities (where you register a custom receiver in onCreate/onresume and unregister in onDestroy/onPause) is to send another broadcast message from BroadcastReceiver.
But you could catch the initial broadcast already in activity. Consider using OrderedBroadcastReceivers.

Is it possible to call class which extends Application android?

I have a class which extends Application and i want to call it from code, it have
#Override
public void onCreate()
I need to call this from an Activity. I know how to call it when app starts for that i need to include in manifest:
android:name=""
Thanks.
You should avoid Calling Applications onCreate manually, as it will get started automatically if anything is configured correctly. However, If you want to call Methods from your overridden Application you can do it like this:
public class MyApplication extends Application{
public void someMethod(){}
}
then inside any Activity:
MyApplication app = (MyApplication)getApplication()
app.someMethod();
Try this :
public class YourApplication extends Application
{
public void sayHello {
System.out.println("Hello")
}
}
Then call it in any activity by:
YourApplication appState = ((YourApplication)this.getApplication());
appState.sayHello();
Application class onCreate() gets called when the Application starts. If you want to call a method that you have declared in your Application class you can call it like,
((Application_Class_Name)getApplicationContext()).calling_method();
From any other class that extends Activity, else you have to use context to get the instance of getApplicationContext() to call from Non Activity class.
Eg - If you want to call it from Adapter class you need to pass the context of the Activity to adapter class and get the instance of Application,
((Application_Class_Name)mContext.getApplicationContext()).calling_method();
From Activity you simply call ((YourAppName)getApplicationContext()).
And also, you don't need onCreate() in your Application (unless you know you do). You can set some methods there and then call them with e.g. ((YourAppName)getApplicationContext()).myMethod(). Your app is alive as long as any of its activities is.
You should't call onCreate() method by yourself... Android does it for you... The main purpose of such a class is to keep global variable commom to whole application, since Application itself is a single instance...
And it lets you override onCreate() because you may need your Custom things in an Appliucation/ACtivity that the OS does create..

Is there a way to make a function that's available to all Activities?

I have a set of commands that I want my app to run when it's restarted, regardless of what activity it's on. I know I need to put an onRestart() into every one.
Since it's the same set of commands regardless of what activity it's on, is there a way I could have them all refer to a single function for that? It seems like that would be better then having to copy paste the commands into each onRestart() handler. It will be a lot less work if I need to change the set of commands too.
You have a couple of options, depending on the code.
You can put it in a helper class as a static function: public static void doWork() { .. } This should work, unless whatever you are doing depends on being in the activity. You can generally just pass it what it needs though, like the Context.
Or, you could extend Activity with your own class, MyActivity and place the work in that onResume. Then extend MyActivity for each of your real activities. They will now automatically do that work when you call super.onResume(). This works well as long as you really want to do the same thing in every activity, and don't use a lot of specialized activities like ListActivity.
Edit:
public class MyHelper {
public static void doWork() {
// do your work here
}
}
public class MyActivity extends Activity {
public void onResume() {
super.onResume();
MyHelper.doWork();
}
}
A search for "static method" will provide more details.
Derive all your activities from a single class (something like ActivityBase) that, in turn derives from system-provided Activity. Then implement onRestart() in ActivityBase.
Is it your application that is restarting from scratch? Or just your activities that are restarting/resuming?
The Application class has an onCreate() method, and you can extend Application in your app to override its behavior. Just remember to change the name of the application in AndroidManifest.xml so it picks up your custom Application class when starting. This code would run before any activities start up. But it won't run every time an activity is stopped and restarted. If that's what you need, this won't do it.
You could also implement a singleton class that contains an initialize() method, or restart() method. You simply call it from onRestart() in each activity you want it in. It sounds like this special code ought to be localized away from your activities so I don't think I'd recommend extending Activity to put the code there.

Categories

Resources