Hey I'm using Android Studio with Kotlin and I have an activity and a service that both needs to call same methods, so I created an object with theses methods in it, which would be like a utils class.
The problem is that the methods depend on a field that needs the application context to be created, and the only way I found to retrieve the context was to pass it through the constructor, but as it's an object I can't do that.
How could I keep that object behaviour and retrieve the application context ?
In Kotlin, an object behaves like a static util class(not exactly at bytecode level) so there are only a few options that you could do
Pass the the context in every util method in the object which needs the context
Make an Application class and keep a global reference of the application context and use it everywhere by making it lateinit var and initialising it in Application`s onCreate method
Or use DI for injection of Application context and instead of using Object use Singleton scoped utility that is injected everywhere
Related
Our teams are debating whether we should pass parameter WeakReference<View> to method of ViewModel or not. I see in the google's document said
Note: Since the ViewModel outlives specific activity and fragment instantiations, it should never reference a View, or any class that may hold a reference to the activity context. If the ViewModel needs the Application context (for example, to find a system service), it can extend the AndroidViewModel class and have a constructor that receives the Application in the constructor (since Application class extends Context).
How about if we use WeakReference<View> to pass view to viewmodel ? WeakRef can prevent the leak memory can occur, however some members said it will make reading/maintain code difficultly. Some guys suggest use interface ViewInf and View will implement to ViewInf and method use in viewmodel will be like that.
fun methodA(viewInf: WeakReference<ViewInf>)() {
doSomeBackgroundThread(viewInf)
}
We want to use this view to draw on bitmap and use bitmap to save into memcache.
The cautionary note from Google makes sense, as the ViewModel is not supposed to do anything other than transport data.
Sometimes we get so caught up in the "object-oriented" part of the design that we forget that domain objects, and application infrastructure objects, should only interact to extract data from, or inject data into the application for processing.
I'd like to put my database connection object to Application class. I read some tutorials and everywhere I see explicit implementation of a singleton pattern. Something like this
public class MyApplication extends Application {
private static MyApplication singleton;
public static MyApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
My question is why do I need to do this explicit implementation? Nobody explains.
I'd like to add there some property, initialized in onCreate() and get it's value in activity.
myProp = (MyApplication)getApplicationContext().getMyProperty()
Is it really necessary to implement singleton pattern?
An Application class is an access point to application context and generally it is used as a initializator for all application-scoped dependencies like your database object. This class is initialized only once per application and persists in memory until application is no longer in memory. So it is a natively created singleton.
By having such static access point to application you may have access to the application context in any class and in general case this context is much better for retrieving resources, system services etc. when you need such dependencies in your custom classes, because it doesn't hold a link to the activity and view so is a leak-safe. Of course in your example the Activity has an access to application, but you have to cast context anyway and better use same approach for a whole app.
Despite you may use it like a global access point to all application scoped and initialized dependencies, do not overload it with huge initialization logic, better create some other singletons for this purpose and just initialize it from Application class. In a big project consider using DI framework, Dagger the best one, for providing dependencies.
By default the application class is singleton..You are not have allowed to create application yourself.Android System will create this when the first time app is loaded into the memory.You are using singleton pattern here just to get Application object from anywhere within the application
I was reading about context in Android and were using in my android application.But then a thought came into my mind. That , Why do we pass context in the constructor only and not some method,something like that component.setContext(context),where component is a hypothetical component and setContext is a hypothetical method and context could be getConetxt/this/getApplicationContext(upon the requirements).
if anyone thinks that title or anything is not appropriate,they are free to change/edit.
Please help me to understand it.Thanks
Basically both are same, if you pass a Context via constructor or via any setter method.
You will still have to have a reference to the Context in your class which will either be initialized during the creation of the object, that is via the constructor or will be initialized later via any setter method.
In both the cases, the Context reference is still there. It is just a question about eager initialization or lazy initialization.
But in case of eager initialization, while accessing the Context in the class you are sure that the context has been initialized for sure and you can safely use it.
But there is no guarantee for that in case of lazy initialization. And as a size note do check out the difference about the two types of Context - Application context and Activity context.
How I can get application context outside activity and without extending application class.
class A{
public static B b = new B(App context here);
}
Objetc b must be as a field
No you can't get context without extending Application or Activity by the given example. All that you can do is to have a static method in a class (extends Application) that would return context and then pass that method as a parameter to your B().
BTW, I did not get your intention of doing this. Can you detail out what exactly you wants to do.
Thank you
It is not possible.
If it were, it would mean that any Java class would be able to access an android.content.Context instance, even when is not related to anything in Android, for example, a Java EE application.
What you can do, is, have a static reference to a Context (an Application or an Activity) in a centralized place inside your app, but I wouldn't recommend it because it would cause multiple memory leaks.
I have an application, which is including a library which exposes set of methods via a public class. Internally, this library uses the context passed on to it by the application.
Question: Since the public class in the library does not extend Activity, the methods use the Context object passed on to it by the application. In this case how to communicate the result/data back to the application? The context object does not have startActivityWithResult() method.
Any idea?
There is no any method like startActivityWithResult() for Activity, the method is startActivityForResult().
If your context is Activity reference then you can use startActivityForResult() method in that class. just use like,
((Activity)context).startActivityForResult();