How to share resources between activities/services - android

I wanted to know what is the best approach for sharing singleton in my android app.
I have a few activities that does not rely on each other, but I want them to have a singleton that they can all read/write.
Where should I place it?
Thanks

Your application should be a singleton. It avoids many other problem related to sharing datas or models.
In your manifest.xml :
<application android:icon="#drawable/icon"
android:label="#string/app_name" android:debuggable="false"
android:name="<class of your application see below>"
android:launchMode="singleTop">
..... all activities/services/receivers/etc... as usual
</application>
And your android:name refers to this class :
public class MyApp extends Application {
//singleton, but use onCreate more than constructor to build shared resources.
....
}//class
And then, from within any activity, you can retrieve your singleton to get shared resources by doing this :
((MyApp)getApplicationContext()).getSharedResources()....
or
MyApp.getInstance().getSharedResources()....
Having a singleton as a app is a usual design pattern in android, it is especially useful to handle device rotation (as it tends to destroy activities and recreate them) as it provides a stable entity to persist during app lifecycle.

Related

Is there a way to declare several native activities in android manifest?

I need to create 2 native activities in my android app where one activity will be communicating with another. I would like to avoid java coding involved, there is a way to do that if activity name is set as
android:name="android.app.NativeActivity"
The problem is that I cannot declare 2 activities with the same name and in order to avoid this problem I have to do something silly like defining another class as a dummy extension of NativeActivity
public class MyAnotherActivity extends NativeActivity {}
and then I can have both the activities declared in my manifest:
<activity android:name="android.app.NativeActivity"
...
</activity>
<activity
android:name="MyAnotherActivity"
...
</activity>
This looks odd to me, maybe there is a better way to do that without creating dummy java files ?
I would expect ability to declare several native activities without involving java.
I don't think you can.
But creating 2 Java Activity classes that do no more than extend from NativeActivity is trivial as you have shown in your question.

Android Application without Classes?

I have seen a JS talk about Redux recently. The speaker programmed a working application without any classes, just with const variables. He even excluded classes in his lint file (https://github.com/MartinSeeler/redux-presentation/tree/master/demo).
So I tried to do the same in my Android apps, which are written in Kotlin. Unfortunately, I get the following error when I try to make my MainActivity class an object:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{blog.app.niklas.flyingbytes/blog.app.niklas.flyingbytes.MainActivity}: java.lang.IllegalAccessException: void blog.app.niklas.flyingbytes.MainActivity.<init>() is not accessible from java.lang.Class<android.app.Instrumentation>
Caused by: java.lang.IllegalAccessException: void blog.app.niklas.flyingbytes.MainActivity.<init>() is not accessible from java.lang.Class<android.app.Instrumentation>
Is there a way to work around this? I really like the idea of having as many singleton objects as possible in my app.
Thank you in advance,
Niklas
You can't replace Activity class by kotlin object on Android, for the same reason you don't instantiate Activities by calling it's constructor:
activities are managed by the platform.
When you ask (via an Intent) the platform for an Activity, the platform will try to instantiate it by calling it's constructor with zero parameter. Which doesn't exist for an object, giving the mentioned error.
That's said, some developer dodge around the frame given by Android, like mortar, by having only one activity and using custom logic for navigation between views.
As Geoffrey said, the Android platform manages your activities, but that also means that the platform is responsible for keeping track of your Activity's instances - which is the purpose of Singleton.
So, while you can't make your Activity an object, you can still make it a Singleton by using the android:launchMode attribute in your AndroidManifest:
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleInstance">
For more information on the launchMode attribute (including other possible values), check out the Official Documentation

Multiple Application name in Android Manifest

I am new to volley.I have two classes,AppController Singleton class, and ImageController Singleton class.But in Manifest,it allows only one application name.So how do I solve this?
You can try this way:
Application Class no one:
public class MyApplication extends Application {
}
Application class no two:
public class MyApplication2 extends MyApplication {
}
In your Manifest:
<application
android:name=".MyApplication2"
android:allowBackup="false"
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:supportsRtl="true"/>
Only the <manifest> and <application> elements are required, they each must be present and can occur only once
According to documentation manifest file with only one application element is valid.
Try to Marge in Single Application Class
First of all, every application should have only one application class that is the concept of MVC in android.
You should remove one application class and do whatever it is doing in another one.
As per your requirement: you have AppController and ImageController application class then remove all the code of ImageController application and merge it in AppController application class. Now use AppController class in manifest.
I'm guessing you are using a Singleton as to have a class that holds your App data for the current session and\or another one for specific stuff (e.g. networking), if so, you have a couple ways of going about that:
Use ONE Application class - you shouldn't have more than one, if so - merge them.
If you insist on having 2 Singleton classes because you want to separate some functionality, you may create 2 Singleton classes, which are NOT your application class.
If you choose option 2, you should initialize(and maybe also control) them from your application class, especially to avoid duplicating a context object (that might lead to a memory leak), but make sure it's really necessary first.
since you tagged your question with the Volley tag, I'm guessing this SO thread about isolating Volley requests might help.
Hope anything here helped!

Global application object instantiated twice android

I am instantiating an application object in the manifest file as below.
<application android:name=".MyApp"
android:icon="#drawable/add_icon_with_oval"
android:label="#string/app_name"
android:process="com.test.myprocess"
android:allowBackup="false">
I am starting a service from my application which is running in another process. This service is also declared in my manifest file as below.
<service
android:name="com.test.package.MyService"
android:permission="some.permission"
android:process="com.test.anotherprocess" >
</service>
The problem that I am seeing here is that MyApp is instantiated twice, one for my process, com.test.myprocess and another instance for com.test.anotherprocess.
Is there is a way that I can prevent creating MyApp for com.test.anotherprocess
Since the service is a component of application, it can't run without an application. The only way to have a single instance of your Application object is to remove the android:process attribute from your service.
For more details, check: http://developer.android.com/guide/topics/manifest/service-element.html#proc
Is there is a way that I can prevent creating MyApp for com.test.anotherprocess
you cannot, system will will create Application instance for each process. If you have some initialization code in your custom Application class then you can check process name and for example skip it, see code here: Is there a way to get current process name in Android.

Class extending Application in Android project library?

I have a project (in Eclipse) which I've turned into an Android Project Library so as to re-use some of the code in another similar project. I think I've shot myself in the foot however as I'm getting the error:
Unable to start activity ComponentInfo{com.test.scroller1/com.lib.scrolltest.ScrollTestActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.lib.scrolltest.resAppVars
com.lib.scrolltest is my Project Library which instantiates a class extending Application (resAppVars). In the onCreate() method I call:
mRav = (resAppVars) getApplicationContext ();
This way, I can use methods in the mRav object which would otherwise be a lot of duplicated code in other classes (such as passing a query to a generic select statement which returns an ArrayList of results).
What's the problem here? It seems I've hit a limitation in the way I've implemented the Application class.
Calling getApplicationContext() returns the Application object for the current application (i.e. the application that owns the activity that onCreate() is running inside of).
Unless you're doing something strange, you don't get to pick which Application class is used. There's even a note in the documentation for Application saying not to do this:
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.
You should just create a regular shared class inside of your library project. Or if you don't have a need for the special functionality library projects offer, you can also just use a regular .jar file.
And if you need shared state, just make it a singleton. ;)
Although this is a very old post. I encountered the same problem and solved it. So I thought I'll post the solution for everyone.
It turns out that I forgot to declare the subclassed application name in the manifest file.
The android:name should point to the extended app class, even if it is defined in the referenced library.
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:name="com.example.lib.MyApp">
After I added that I could use the extended app with (<cast>) getApplication() anywhere in my project.

Categories

Resources