One of my Android apps uses a custom Application class to perform some global initialization. This done in the onCreate() method:
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
someCustomInit();
}
}
This works fine, but now I have discovers a crash log in the Developer Console which indicated that MyApplication.onCreate() did not run / has not completed at the time the crash happened: The code crashed because some initialization that is performed MyApplication.onCreate() was not complete.
How is this possible? I assumed that MyApplication.onCreate() would run before all other code? Isn't that correct?
Is it save to move someCustomInit(); to the constructor of MyApplication instead? No other code should run before the application object has been created, correct?
Or are there any side effects from using the constructor instead of onCreate()?
I assumed that MyApplication.onCreate() would run before all other code? Isn't that correct?
ContentProvider instances are created before onCreate() is called on the Application. In theory, your stack trace should show you what code of yours is being invoked prior to your initialization.
Is it save to move someCustomInit(); to the constructor of MyApplication instead?
That would depend on what is happening in someCustomInit(). Your Application is not initialized yet.
Another possibility is to override attachBaseContext(), such as how ACRA is hooked in. There, you are passed a Context object that you can use, if your initialization requires a Context.
The Application class is a singleton for your app process, but its onCreate() is not the first possible code to execute. Class field initializers, the constructor as well as any static code blocks (often used for loading native libs) will execute first. The static code blocks, in particular, will run when the class is loaded by the runtime.
Normally, this is not a problem and your safest route is to put your specific code in the onCreate() method.
How is this possible?
It is possible since Application class onCreate is called for every process of your app.
For example Service can be started in separate process so your Application can be started twice. I have met this behaviour when used Yandex.Appmetrica library. It is not bad actually, because crashes in library will not affect other parts of application.
Or are there any side effects from using the constructor instead of
onCreate()?
From the documentation:
The Application class, or your subclass of the Application class, is
instantiated before any other class when the process for your
application/package is created.
So constructor will be called twice. Any difference?
You should move your code that supposed to run only once to somewhere else, outside Application class. Probably in some Singleton which will be called from Launcher Activity or smth. Actually if you see sources of Application class you will see that comment:
There is normally no need to subclass Application. In most situations,
static singletons can provide the same functionality in a more modular
way.
Related
I have a problem getting access to an object that controls audio output and that was created in another activity. Here's the case:
I have a class that implements Runnable so that I can run it in its own thread:
public class PulseGenerator implements Runnable {...}
In my main activity I instantiate this class, pass the instance to a Thread object and start the thread:
noise = new PulseGenerator();
noiseThread = new Thread(noise);
noiseThread.start();
I have a few controls in my main activity screen to control internals of 'noise': switch audio on and off, select a waveform, change pulse width and the like. This all works just fine.
Now I want to move a few of these existing and working controls to another screen that I've called 'Settings'. (In order to make room for other additional controls on the main activity screen.) I followed the typical Android approach by creating a new activity for the new Settings screen:
public class Settings extends Activity implements OnItemSelectedListener, View.OnClickListener { ... }
This all sounds simple enough. The problem I have now is that I don't know how to get access to the 'noise' object from the new Settings screen/activity/class. When I run the app on the emulator and press a button to switch to the Settings activity, the app crashes ("Unfortunately, xxxxx has stopped.") and in Android Studio's 'Run' view, I get:
E/AndroidRuntime: FATAL EXCEPTION: main java.lang.NullPointerException
with a reference to the line number in Settings where I try to access the 'noise' object for the first time. Which makes perfect sense to me, because I have declared, but not initialized the 'noise' object. Because I don't know how, which is the core of this question.
Putting the question more generally, how do I access an object instantiated in one activity and running in its own thread, from another activity?
I am a beginning java and Android programmer and this is my first post, please don't be too brief when answering. Actually I hope it's a 'stupid' beginner's question about multi-activity app programming with an easy answer, so I can move on with my project. I appreciate any help.
PS:
- Standard methods for passing objects between activities don't apply because an object running in its own thread is not serializable. (If I understood correctly.)
- I know of workarounds that use multiple screens per activity (one of them using setVisibility(View.GONE)) and that I could probably get to work. But these solutions lack generality and that's why I don't want to use them.
There are some possibilities:
A simple solution would be stopping the thread when an Activity is about to finish and restart it in the next Activity. Of course, it depends on what the thread does and whether it is possible at all.
Wrap the noise thread in a singleton, so you can access the thread from any Activity.
Create a Service and manage the noise thread in there. Maybe you can also reimplement the thread functionality as a Service. From https://developer.android.com/guide/components/services.html:
A Service is an application component that can perform long-running operations in the background, and it does not provide a user interface.
A long-running Service lifecycle is not bound to the lifecycle of an Activity, so even if an Activity finishes, your thread would keep running and would be accessible via the Service that controls it. Mind two things: although a Service doesn't provide UI, it runs on the main UI thread, and a Service might be finished by the operating system, but it can be restarted right after.
I'm newer to Java, here's what I think XPosed works:
Before zygote_init, hook all apis and insert xposed_before_xxx and xposed_after_xxx method (where xxx is the name of the api).
Load modules. Load hook class, realize it and keep it in memory of zygote. For each injecting method, add it to the private list of xposed_before/after_xxx.
When an new app loads (forks from zygote), it also forked the hook class and the hooked method.
When an app calls xxx, it actually runs xposed_before_xxx first, and the latter calls every inject method in its private list. Then the original api is called. Then xposed_after_xxx is called, and deals with itself's list.
So for each app, hook class is individual after forking from zygote. So, static members are not shared. Cause each hook class has only one instance in an app, static members act the same as non-static members. Am I right?
Thanks for reading my long & poor English...
No, static members are not shared across processes. They act as static members within the app, not across apps.
Each application runs on its own VM so nothing is shared across processes.
Same applies for Xposed hooks, you can have a static method hooked for one application and not for others.
Even if you set your module to apply hooks on all applications, these hooks will be different instances in separate VMs.
I'm trying to connect my Widget to the app's database, but I don't understand a thing.
Why this works:
import android.app.Activity;
public class Widgets1 extends Activity{
mMioDbHelper = new SqlHelper(getApplicationContext());
and this not?
import android.appwidget.AppWidgetProvider;
public class Widgets1 extends AppWidgetProvider{
mMioDbHelper = new SqlHelper(getApplicationContext());
How can I connect the widget to the database? I mean how can I do a query from a widget class?
Thanks.
AppWidgetProvider extends BroadcastReceiver, which does not, in turn, inherit from Context. getApplicationContext() is a method on Context. As you determined, the reason why you are passed a Context into onReceive() of a BroadcastReceiver (and onUpdate() and other callbacks on AppWidgetProvider) is so you can do things that need a Context.
All that being said, the code you have here has issues:
Do not use methods inherited from Context from an initializer, as you have with your Activity snippet. There is no guarantee that such methods are ready for use at that point in time. Delay using Context methods until the initial entry point of the component, such as onCreate() of an Activity.
Never do database I/O on the main application thread, as it will freeze your application's UI if one of your activities happens to be in the foreground at the time. All callbacks to your AppWidgetProvider, like onUpdate(), are called on the main application thread. Please use an IntentService or something else that can safely run a background thread. Note that the IntentService is perfectly capable of updating the app widget UI via AppWidgetManager. onUpdate() is a trigger for you to do certain work, but that work can -- and often times should -- be done elsewhere.
Be very careful in creating all sorts of SQLiteOpenHelper instances, and I am assuming that SqlHelper is a subclass of SQLiteOpenHelper. Please have exactly one instance of your SQLiteOpenHelper for your entire application, so that you can take advantage of the thread safety built into SQLiteOpenHelper. That usually winds up being a singleton SQLiteOpenHelper. Having multiple instances is likely to get you in thread-related trouble.
Say I have a very simple Android app that has just one activity - the activity displays a plain screen. Lets say I have overridden the onCreate() method of the activity and it simply sets the screen as described in activity_main.xml and then returns as shown below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//boolean BT_success = turnBluetoothOn();
}
In a desktop Java (or C or Python) program, execution starts at the "main" method/function and the program finishes executing when main has finished executing (and once all the functions called by main have returned). In this simple app described above, when the common set of callback functions like onCreate(), onStart() and onResume() are finished executing, is there any part of my code that is executing?
In this sense, there is no "main" method, like in the case of desktop Java, C or Python, right? Even if we had a couple of buttons in this main screen, we would have callback functions for those buttons.
So is it fair to say that the Android API callback based in the sense that an app developer has to implement certain callback functions (and those can in turn call other functions)?
Not in the way Win32 is. For one thing, the Android flavor of Java doesn't readily accommodate the notion of a canned function; it has neither delegates (C#) nor functors (C++, Python) nor function pointers (C, C++).
The Android API is still event driven, like most GUI systems are; but the primary ways for you to provide hooks into your code to the framework are:
inheriting from library classes and then overriding functions that were meant to be overridden;
implementing abstract interfaces in your classes (possibly anonymous) and providing those objects to the framework.
This is, generally, the Java way.
EDIT: depends on your definition of callback :) Normally, when people say that, they mean a function. In this sense, it's not callback-based. But if you mean "the framework calls you whenever something interesting takes place", then yes, it is. Event-driven, like I said.
EDIT2: Preamble: C has function pointers. It's a datatype that you can initialize with a function name, pass around like a primitive value, and then call with arguments at some point down the road. The call will be received by the function that the pointer was initialized with originally.
Windows, like Android, is an event-driven GUI system. The event-driven nature of Windows is implemented mainly via said function pointers - you pass a pointer to your function to the framework, the framework calls it back when something interesting occurs. This was designed in mid-1980's, before the advent of object oriented languages.
Now, those functions that are meant to be called by the framework are referred to as "callback functions" or simply "callbacks". I come from the Windows background, so for me, "callback" primarily means "callback function". As opposed to Android-style callback objects (is that even a term?).
This is not dissimilar to the way any GUI application/framework is designed. Even Java Swing works in a similar fashion. You implement the "callbacks" that are hooked to UI control events, and your "main" function usually only serves to kick off the main event loop and exit. Note that here, when main() exits, the program itself does not exit.
To simply answer your question, yes it is based on callbacks. You specify which activity should be the starting point for your application in your androidmanifest.xml. This activity's onCreate() is called to initialize the layout. Every interaction that you perform on the screen triggers a callback (which you will override to implement what you need). But just because the main activity exits does not mean that the application will exit.
This is where you go into the activity lifecycle. All activities sit on the main thread in a stack like manner. When one activity is killed, you go to the next activity in the thread and so on. The application itself exits when all it's activities in this stack have been killed or Android decides to terminate it. Keep in mind that you might normally expect onDestroy() to be called when Android terminates the application but this is not the case - Android may or may not call onDestroy(). In this case, there was no callback for the exit.
I would say the Android API is heavily based on Extension. You almost always have to extend their Classes and override their methods.
super.onCreate(savedInstanceState);
Is a call to the Super Class method that would normally be hidden by you override. You are, however, free to call back to classes that provide the logic you need but you are not forced to. I recommend that you do, and that you put those Classes under UnitTest.
Recalling this post enumerating several problems of using singletons
and having seen several examples of Android applications using singleton pattern, I wonder if it's a good idea to use Singletons instead of single instances shared through global application state (subclassing android.os.Application and obtaining it through context.getApplication()).
What advantages/drawbacks would both mechanisms have?
To be honest, I expect the same answer in this post Singleton pattern with Web application, Not a good idea! but applied to Android. Am I correct? What's different in DalvikVM otherwise?
EDIT: I would like to have opinions on several aspects involved:
Synchronization
Reusability
Testing
I very much disagree with Dianne Hackborn's response. We are bit by bit removing all singletons from our project in favor of lightweight, task scoped objects which can easiliy be re-created when you actually need them.
Singletons are a nightmare for testing and, if lazily initialized, will introduce "state indeterminism" with subtle side effects (which may suddenly surface when moving calls to getInstance() from one scope to another). Visibility has been mentioned as another problem, and since singletons imply "global" (= random) access to shared state, subtle bugs may arise when not properly synchronized in concurrent applications.
I consider it an anti-pattern, it's a bad object-oriented style that essentially amounts to maintaining global state.
To come back to your question:
Although the app context can be considered a singleton itself, it is framework-managed and has a well defined life-cycle, scope, and access path. Hence I believe that if you do need to manage app-global state, it should go here, nowhere else. For anything else, rethink if you really need a singleton object, or if it would also be possible to rewrite your singleton class to instead instantiate small, short-lived objects that perform the task at hand.
I very much recommend singletons. If you have a singleton that needs a context, have:
MySingleton.getInstance(Context c) {
//
// ... needing to create ...
sInstance = new MySingleton(c.getApplicationContext());
}
I prefer singletons over Application because it helps keep an app much more organized and modular -- instead of having one place where all of your global state across the app needs to be maintained, each separate piece can take care of itself. Also the fact that singletons lazily initialize (at request) instead of leading you down the path of doing all initialization up-front in Application.onCreate() is good.
There is nothing intrinsically wrong with using singletons. Just use them correctly, when it makes sense. The Android framework actually has a lot of them, for it to maintain per-process caches of loaded resources and other such things.
Also for simple applications multithreading doesn't become an issue with singletons, because by design all standard callbacks to the app are dispatched on the main thread of the process so you won't have multi-threading happening unless you introduce it explicitly through threads or implicitly by publishing a content provider or service IBinder to other processes.
Just be thoughtful about what you are doing. :)
From: Developer > reference - Application
There is normally no need to subclass Application. In most situation,
static singletons can provide the same functionality in a more modular
way. If your singleton needs a global context (for example to register
broadcast receivers), the function to retrieve it can be given a
Context which internally uses Context.getApplicationContext() when
first constructing the singleton.
Application is not the same as the Singleton.The reasons are:
Application's method(such as onCreate) is called in the ui thread;
singleton's method can be called in any thread;
In the method "onCreate" of Application,you can instantiate Handler;
If the singleton is executed in none-ui thread,you could not
instantiate Handler;
Application has the ability to manage the life cycle of the
activities in the app.It has the method
"registerActivityLifecycleCallbacks".But the singletons has not the
ability.
I had the same problem: Singleton or make a subclass android.os.Application?
First I tried with the Singleton but my app at some point makes a call to the browser
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
and the problem is that, if the handset doesn't have enough memory, most of your classes (even Singletons) are cleaned to get some memory so, when returning from the browser to my app, it crashed everytime.
Solution: put needed data inside a subclass of Application class.
Consider both at the same time:
having singleton objects as static instances inside the classes.
having a common class (Context) that returns the singleton instances for all the singelton objects in your application, which has the advantage that the method names in Context will be meaningful for example: context.getLoggedinUser() instead of User.getInstance().
Furthermore, I suggest that you expand your Context to include not only access to singleton objects but some functionalities that need to be accessed globally, like for example: context.logOffUser(), context.readSavedData(), etc. Probably renaming the Context to Facade would make sense then.
They're actually the same.
There's one difference I can see. With Application class you can initialize your variables in Application.onCreate() and destroy them in Application.onTerminate(). With singleton you have to rely VM initializing and destroying statics.
From the proverbial horse's mouth...
When developing your app, you may find it necessary to share data, context or services globally across your app. For example, if your app has session data, such as the currently logged-in user, you will likely want to expose this information. In Android, the pattern for solving this problem is to have your android.app.Application instance own all global data, and then treat your Application instance as a singleton with static accessors to the various data and services.
When writing an Android app, you're guaranteed to only have one instance of the android.app.Application class, and so it's safe (and recommended by Google Android team) to treat it as a singleton. That is, you can safely add a static getInstance() method to your Application implementation. Like so:
public class AndroidApplication extends Application {
private static AndroidApplication sInstance;
public static AndroidApplication getInstance(){
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
sInstance = this;
}
}
My 2 cents:
I did notice that some singleton / static fields were reseted when my activity was destroyed. I noticed this on some low end 2.3 devices.
My case was very simple : I just have a private filed "init_done" and a static method "init" that I called from activity.onCreate(). I notice that the method init was re-executing itself on some re-creation of the activity.
While I cannot prove my affirmation, It may be related to WHEN the singleton/class was created/used first. When the activity get destroyed/recycled, it seem that all class that only this activity refer are recycled too.
I moved my instance of singleton to a sub class of Application. I acces them from the application instance. and, since then, did not notice the problem again.
I hope this can help someone.
My activity calls finish() (which doesn't make it finish immediately, but will do eventually) and calls Google Street Viewer. When I debug it on Eclipse, my connection to the app breaks when Street Viewer is called, which I understand as the (whole) application being closed, supposedly to free up memory (as a single activity being finished shouldn't cause this behavior). Nevertheless, I'm able to save state in a Bundle via onSaveInstanceState() and restore it in the onCreate() method of the next activity in the stack. Either by using a static singleton or subclassing Application I face the application closing and losing state (unless I save it in a Bundle). So from my experience they are the same with regards to state preservation. I noticed that the connection is lost in Android 4.1.2 and 4.2.2 but not on 4.0.7 or 3.2.4, which in my understanding suggests that the memory recovery mechanism has changed at some point.