There is a lot of examples and guides how to get ApplicationContext, but a cannot find some examples which provide me an ability to store some values in ApplicationContext.
I want to get, for example, string mode everywhere in my application, like this:
String mode = getApplicationContext().getMode();
How can I do that?
You have to extend Application (there is no ApplicationContext class) and add the fields you need stored to your custom class. Then you would cast the reference you get from getApplication() to your actual class:
class MyApplication extends Application {
String mode;
}
// in your activity
MyApplication app = (MyApplication)getApplication();
String mode = app.mode;
why don't you store it in shared preferences?
Related
I have a service url (http://servicetest.com/api/) getting datas through the restful service.
I want to ask a question that what is the best way holding this constant?. Is it appropriate holding it in strings.xml or applicationcontroller class, or etc. Because according to my needs, I can use service url in every activity. That's why, it should be accessible from anywhere.
Thanks
I think it would be best to create a class constants(urls or whatever you want to name it) and declare all constant variables as static there so you can access them everywhere in your app without creating an object and when you need to change is you have to change only at one place,hope that helped
Just create a class like this:
public class AppConstants {
public static final String URL = "http://servicetest.com/api/";
/* private Constructor to avoid instanciating this class */
private AppConstants() {}
}
Use it that way, e.g.:
MyAsyncTask task = new MyAsyncTask();
task.execute(AppConstants.URL);
create an Interface (i.e ProjectConstants) for declaring all your project constants like generic class manner..So you can easily access these variables everywhere in your application..
//For example
package com.example.myapp;
public interface ProjectConstants
{
String SERVICE_URL = "http://servicetest.com/api/";
}
// you can use this URL in your application where ever you want by simply calling like this
textView.setText(ProjectConstants.SERVICE_URL);
I have read some articles about how to use/extend the Android Application class but I am still kind of unsure if I can use it for my needs.
In my Application, on startup, i read a JSON configuration file. This configuration file contains some basic infos about an external device. Because I need this infos in several other fragments/activities I simply store an object representation of this json file as a member variable of my Application class.
public App extends Application {
private ConfigurationContainer configuration;
...
getters / setters
}
When I need it i call getApplication().getConfigurationContainer().
Is this OK for my needs?
Yes, It is ok.
Follow this steps.
1.Override onCreate() method and load all the json configuration in this method.
public App extends Application {
private ConfigurationContainer configuration;
public void onCreate(){
super.onCreate();
// load json configuration.
}
// getter setter
}
Declare this class in manifest file.
<application android:name="com.packageName.App">.
Use this configuration in all your activity.
App ap = (App)getApplication();
ConfigurationContainer conf = ap.getConfigurationContainer()
Yes it is reasonable to store globally scoped variables (or objects) in your Application class. You should be careful that you are not storing too much data here, as it will consume memory that is never recovered as long as your app is running.
Your concept is fine, but there are some nuances about using the Application class in this way, it is suggested that you create a Singleton class (instantiated by your Application) to store values like this.
Here is a great SO related to this: Android Application as Singleton
I'm developing an Android app that uses two singleton objects: one for business logic (similar to the model in MVC) and one for a Bluetooth connection. Some activities display data and need access to the former, while one lets the user connect/disconnect and needs access to the latter.
What is the preferred way of passing these objects around? Arguments to the activities? Global objects?
You can use Application Class. it is a base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's tag, which will cause that class to be instantiated for you when the process for your application/package is created.
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 ,the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.
ref- http://developer.android.com/reference/android/app/Application.html
Ex- Define in App class
public class AppData extends Application{
Object ob = new Object(); //Global Obj - Can be anything String etc
}
initialize in acticity like -
AppData ad= (AppData)getApplicationContext();
ad.ob = //yourValue
Access across the activities ->
Object obj = ((AppData)getApplicationContext()).ob;
and in manifest give the name of your app class-
<application
android:name=".AppData"
>
You might want to check out Dagger. This Dependency Injection framework (optimized for Android) allows to easily inject singletons into your activities/fragments.
// define this code in your common data access class which use thought your app or application master class
private static Object object=null;
public synchronized static Object getInstance(){
if(object==null){
object = new Object();
}
return object;
}
// this way define your two object.
I'm trying to persist data objects throughout my Android app. I want to be able to access an object in one activity, modify it, save it, navigate to a new activity, and access the same object with the updated value.
What I'm essentially talking about is a cache, but my data objects are complex. For example, ObjectA contains ObjectB which contains ObjectC. Does anyone know if a good method, tool, or framework for persisting complex objects in Sql?
Put a static field in a subclassed Application. Also inside your manifest, put:
android:name="MyApp" inside your application tags.
Also to access from other files, simply use:
MyApp myApp = (MyApp)getApplicationContext();
See here How to declare global variables in Android?:
class MyApp extends Application {
private String myState;
public String getState(){
return myState;
}
public void setState(String s){
myState = s;
}
}
class Blah extends Activity {
#Override
public void onCreate(Bundle b){
...
MyApp appState = ((MyApp)getApplicationContext());
String state = appState.getState();
...
}
}
You could use an ORM framework, like OrmLite for mapping objects into sql, but it may be an overkill for you situation.
You could also make these shared object Parcelable and pass them between the Activities thru the Intents.
You could also save these objects into the SharedPreferences, so each Activity can access them whenever they feel the need to it, and the objects are also persisted this way. This may mean more IO access though, so take that into consideration as well. You could use e.g. Gson to serialize the objects more painlessly for this.
These are the solutions I'd consider. But whatever you do, don't put this common object into some kind of "standard" global static variable, like using a custom Application class, static field or any implementation of the Singleton pattern, these are really fragile constructs on Android.
Why don't you use a JSON serialization mechanism ?
In association with a static access to your objects you can easily build a lite-weight database with some basic functionnalities:
loadObjectsFromCache
saveObjectsInCache
getObjects
You can also store your objects in differents files, and use a streaming json parser like this one: http://code.google.com/p/google-gson/
It's the same that this one: http://developer.android.com/reference/android/util/JsonReader.html
but can be used even if your application api level is inferior to 11.
It use less memory than the basic DOM parser:
http://developer.android.com/reference/org/json/JSONObject.html,
but with the same speed.
Can anyone enlighten me about the safety of a class holding global values in Android?
Here's a short example of what I mean:
public class Globals {
public static int someVariable = 0;
public static User currentUser = null;
public static Handler onLogin = null;
}
Then somewhere in an Activity I do the following:
Globals.someVariable = 42;
Globals.currentUser = new User("John", "Doe");
I have to rely on Globals.currentUser at multiple places in my app as soon as the user is logged in, but I'm unsure if I should do it, and also if I could use a Handler like this.
I read everywhere that an Android app could be killed anytime, does this mean it is killed completely or maybe just a part of it, thus killing my Globals class only?
Or is there any other way to store globally available data in a safe way, without writing every member change to the database (in fact, my User class is a little more complex than in this example. ;-)
Thanks for your effort!
Edit: Ok, here's what I finally did:
public class MyApp extends Application {
private static MyApp _instance;
public MyApp() {
super();
_instance = this;
}
public static MyApp getContext() {
return _instance;
}
....
private User _user = null;
public User getUser() {
if (_user == null) _user = new User();
return _user;
}
}
Then modify the AndroidManifest.xml and add android:name=".MyApp" to your application node to tell the app to use your subclass.
So far everything works fine and I can easily access the current Context (f.ex. in SQLiteOpenHelper) by calling MyApp.getContext().
It would be better to use the Android Application class. It's meant to store global application state
http://developer.android.com/reference/android/app/Application.html
Just create a subclass and make sure to update your manifest file to use your version. Then you can store whatever you need to in it. Activities have a method getApplication() which you can cast to your class to access your implementation
The pattern is discouraged--you will run into problems when unit testing.
Can you explain how you unit-test a class that must supply different custom "Users" here? You are either forcing a mock/fake class into "User" which will probably have a cross-effect on other tests or you are putting an if(test) into your code which gets ugly quick.
Over time populating this class artificially for testing gets more complex and starts to have relationships and dependencies.
More simply it makes it difficult to unit test a class in isolation.
It's one of those patterns that a given programmer either doesn't see a problem with or never uses because he's been burnt--you'll see little middle ground.