In manifest file, I set:
<application android:name=".MyApplication" />
But in activity when I call:
getApplication()
it returns android.app.Application instance not MyApplication instance.
I think it causes by I am using Dagger2. I am new to dagger2
The better way to access to application instance — property in your Application class.
Java example:
class App extends Application {
private static App instance;
#Override
public void onAttachBaseContext(Context newBase) {
super.onAttachBaseContext(newBase);
this.instance = this;
}
public static App getInstance() {
return this.instance;
}
}
Your MyApplication is a child class of android.app.Application, getApplication() returns it as an Application instance, but it is actually your class. That's use of inheritance. You need to process it further, by
MyApplication myApp = null;
Application app = getApplication();
if (app instanceOf MyApplication) {
myApp = (MyApplication) app;
}
or you can simply do
MyApplication myApp = (MyApplication) getApplication();
Related
I have a CustomApplication extends Application class, which is registered in AndroidManifest
<application
....
// Please, pay attention that I got this in my Manifest
android:name=".CustomApplication">
And at different part of my application, both some activities and services I do
getApplication()/getApplicationContext() then cast it to CustomApplication and it crashes in production on a variety of devices/sdk versions(beginning at android 6) due to a class cast exception. Caused by: java.lang.ClassCastException
Example:
class CustomApplication extends Application{
...
public static CustomApplication with(Context context) {
return (CustomApplication) context.getApplicationContext(); //crashes here
}
}
and service example:
class CustomService extends IntentService{
...
#Override
rotected void onHandleIntent(#Nullable Intent intent) {
CustomApplication app = CustomApplication.from(getApplication());
// tried getApplicationContext() also
}
}
and activity example:
class CustomActivity extends AppCompatActivity{
...
#Override
protected void onCreate(...){
CustomApplication app = CustomApplication.with(this);
}
What I've tried:
Tried services with different process=":process"
Tried deep linking with different launchModes
Tried activities with taskAffinity
launching from push notifications
process cleaning with system tray(on device), ps kill int adb shell
nothing helps me to reproduce an issue on emulator
I don't use Instant Run also (never used it)
Please don't provide me with suggests of using static application context instance
You can keep a static reference of your CustomApplication like below. You don't need to cast in the following way.
public class CustomApplication extends Application {
private static CustomApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static CustomApplication getContext() {
return instance;
}
}
Then call CustomApplication.getContext();
You need to define your custom application in the manifest as follow:
<application
....
android:name="my.package.path.CustomApplication">
... activities ....
</application>
Also, you are getting an instance of a class that extends Application, not Context, that being said you should call this the following way:
CustomApplication customApplication;
customApplication = (CustomApplication)getApplication();
What you might have to apply in case you have BroadcastReceiver(No context available) is:
customApplication = (CustomApplication)getApplicationContext().getApplication();
I have access to application context but not to application. I want to get the application (so I can get all running activities), but couldn't find a way to do so. Is there an existing API to get application from application context or I will have to override getApplicationContext for that?
No, there's no such API out of the box. However, you can either get application context and cast it to Application object, or Extend Application class, and make it a singleton so you can grab an instance of it from everywhere.
public class MyApplication extends Application {
private static MyApplication singleton;
// Returns the application instance
public static MyApplication getInstance() {
return singleton;
}
public final void onCreate() {
super.onCreate();
singleton = this;
}
}
Is it possible to make an activity singleton?
I have found many resources that just tell to use android:launchMode="singleInstance" or singleTask, but I would constructor to be called only once.
Ideally, I would like to be able to specify custom constructor/builder method e.g. getInstance()
You could store your references in Application instead of an Activity. The application class is de facto a singleton. You only need to define your access methods.
public class BaseApplication extends Application {
private static BaseApplication sInstance = null;
public synchronized static BaseApplication getInstance() {
return sInstance;
}
public synchronized static void setInstance(BaseApplication app) {
sInstance = app;
}
public BaseApplication() {
}
#Override
public void onCreate() {
super.onCreate();
setInstance(this);
}
Now you can access it by calling BaseApplication.getInstance(). As a bonus the Application extends Context so now you have an application context reference anywhere you want (safe to use pretty much everywhere except inflating layouts).
Don't forget to define this class as the base application class in your manifest:
<application
android:name="com.yourapp.BaseApplication">
Usually they do as follows:
1) define what comprise the Activity state
2) Save the state in onSaveInstanceState
3) Restore the state in onCreate or in onRestoreInstanceState
I am looking for information regarding writing my own application class. In many tutorials on the net I have seen the following code:
class myapp extends Application
{
private static myapp mm;
private Context context;
public Context getContext()
{
return getApplicationContext();
}
public myapp getmyapp()
{
if(mm == null)
mm = new myapp();
return mm;
}
}
What is the difference in getting object of myapp and getApplicationContext and where to use object of myapp and where to use context object. I just want to clear the concept of usage of these objects.
that code is completely wrong:
public myapp getmyapp()
{
if(mm==null)
mm=new myapp();
return mm;
}
only the Android framework can instantiate the Application object. I mean, you can call new but the object won't be "connected" to the underlying framework
To have a static reference of the application object you should do as follows:
class MyApp extends Application{
// I fixed the names to follow some Java convention
private static MyApp instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static MyApp getMyApp(){
return instance;
}
Regarding the context, the code is not wrong, but simply doesn't make any sense. That's because the Application object already is the application context. So there's not need to ask for it.
Context is what gives Android apps access to resources, file system specific folders, permissions, etc (what I said about the Android framework creates it). The Application is one class that extends Context, other examples are Activity and Service classes.
I hope it's a bit clearer.
I use BroadcastReceiver for manage my app behaviour when incoming call.
I need to access to object instantiated in my MAIN activity.
In my main activity I create an object with any method that I need to execute in BroadcastReceiver.
How can I access to it ?
Any object you add in intent and send through broadcast, your object must implement Parcelable
Try to create a new class which extends Application, in this class create a global variable with getter and setter methods
public class MyApplication extends Application
{
private YourTypeObject object;
public void setObj(YourTypeObject obj )
{
object=obj;
}
public YourTypeObject getObj()
{
return object;
}
...
}
In your MAIN activity you can use
...
YourTypeObject myobj=....
MyApplication application = (MyApplication) this.getApplication();
application.setObj(myobj);
...
Now in your another Activity you can use
...
MyApplication application = (MyApplication) this.getApplication();
YourTypeObject obj=getObj();
...