In a persistent Android Service, what's the best place to declare static strings to reference SharedPreferences, for eventual use in BroadcastReceivers?
public final static String KEY_ENABLE_LOCKSCREEN = "key_enable_lockscreen";
Declare them in the:
Service?
Activity?
A singleton?
A singleton!
It is way more clean that way.
Usually I declare mine in package names utils.
mycustom.package.com.utils
Here a example.
public class MyUtility{
public final static String KEY_ENABLE_LOCKSCREEN = "key_enable_lockscreen";
}
And when you use it , just refer to it everywhere as follows:
SharedPreferences prefs = getSharedPreferences( MyUtility.KEY_ENABLE_LOCKSCREEN, Context.MODE_PRIVATE);
Its better approach & practice to create a separate classes like
/**
*
*/
package com.comapnyname.projectname.utility;
/**
* #author Rakesh.Jha
* All static member variable will be listed here
*/
public class MyPreferences {
/*
* #Declare all static variables here
*/
public final static String KEY_ENABLE_CODE = "0001";
}
When ever you want to use preferences you can use like -
MyPreferences.KEY_ENABLE_CODE
So, it will give you managed code to make speedness in your code.
You can extend Application class to create your own and declare it there.
You can create a helper class and just declare it in there. Your constant doesn't require a Context so it can safely live in there. This class doesn't have to be a singleton to hold your static final variable as it doesn't have to have an instance.
From Android Developer Reference on Application class:
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 (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.
Please note that this question is a bit opinion based and there's no one good answer.
I see no reason to declare them in anything other than a static class. They're constants, really. You're not going to change them (as demonstrated in the example). Why bother instantiating them in a singleton? A static class just acts like a header file in C. An even better trick is to put them in an interface definition. That way, you can mix and match constants by implementing multiple interfaces in a class. When you implement an interface that doesn't have any methods, you inherit the constants.
I think it's best to put such constants in the service as final static strings, with the minimum required scope (e.g. package private, or public, as required).
The singleton is completely unnecessary (there is no need for an instance).
A separate utils class is unnecessary. This may be a matter of preference, but there is very little to gain from having your constant definitions separated from the class they're related to. They can be accessed just as easily from the service as they can from some other arbitrary class, and in the long run I feel it will be easier to remember where the constants for MyService are, if they are in MyService, than if they are in some other utils class which you must now also remember the name of.
A separate utils class complicates naming. Putting all of your constants in a single separate class will also require you to decorate the names, assuming you have multiple services/broadcasts. In other words, you won't be able to unambiguously use the same name for your constants in multiple services.
For example, I feel this:
public class PlaylistManager extends IntentService {
public static final String BROADCAST_ERROR = "#package.name#.PlaylistManager.broadcast.ERROR";
// can be referenced within this class as BROADCAST_ERROR
private void broadcastError() {
Intent broadcastIntent = new Intent();
if(broadcastIntent != null) {
broadcastIntent.setAction(BROADCAST_ERROR);
// etc.
sendBroadcast(broadcastIntent);
}
}
}
public class AudioCacheLoader extends IntentService {
public static final String BROADCAST_ERROR = "#package.name#.AudioCacheLoader.broadcast.ERROR";
// can also be referenced within this class as BROADCAST_ERROR
private void broadcastError() {
Intent broadcastIntent = new Intent();
if(broadcastIntent != null) {
broadcastIntent.setAction(BROADCAST_ERROR);
// etc.
sendBroadcast(broadcastIntent);
}
}
}
// naming pattern:
// PlaylistManager.BROADCAST_ERROR
// AudioCacheLoader.BROADCAST_ERROR
// etc.
...is more desirable than this:
public class MyUtils {
public static final String PLAYLIST_MANAGER_BROADCAST_ERROR = "#package.name#.PlaylistManager.broadcast.ERROR";
public static final String AUDIO_CACHE_LOADER_BROADCAST_ERROR = "#package.name#.AudioCacheLoader.broadcast.ERROR";
}
public class PlaylistManager extends IntentService {
private void broadcastError() {
Intent broadcastIntent = new Intent();
if(broadcastIntent != null) {
broadcastIntent.setAction(MyUtils.PLAYLIST_MANAGER_BROADCAST_ERROR);
// etc.
sendBroadcast(broadcastIntent);
}
}
}
public class AudioCacheLoader extends IntentService {
private void broadcastError() {
Intent broadcastIntent = new Intent();
if(broadcastIntent != null) {
broadcastIntent.setAction(MyUtils.AUDIO_CACHE_LOADER_BROADCAST_ERROR);
// etc.
sendBroadcast(broadcastIntent);
}
}
}
// naming pattern:
// MyUtils.PLAYLIST_MANAGER_BROADCAST_ERROR
// MyUtils.AUDIO_CACHE_LOADER_BROADCAST_ERROR
// etc.
Note that the first example makes it easier to copy and paste code between service classes.
Also, keep in mind that you should use unique strings for BroadcastReceivers, unless you're using LocalBroadcastManager.
The Intent namespace is global. Make sure that Intent action names and other strings are written in a namespace you own, or else you may inadvertently conflict with other applications.
(See: http://developer.android.com/reference/android/content/BroadcastReceiver.html)
Related
I have a class called myConstants and in it i list all my constants so when i need them I just reference MyConstants.MYCONSTANT. However, i would like to implement something like this for methods. i am repeating a lot of code, for instance, i have a formatCalendarString(Calendar c) method in 3 activities. seems redundant and unecessary. but i cant make them static because i get static calling non-static errors and the only other way i can think is to make a MyConstant object then call public functions off that object, like this...
MyConstants myConstants = new MyConstants();
myConstants.formatCalendarString(Calendar.getInstance());
is there some way i can just call the formatCalendarString() inside MyConstants class without generating an object?
You can use singleton pattern to cache instances. Keeping methods in something like parent activity does not make any sense (as primary role of activity is user interaction).
Example:
public class MyConstants {
private static MyConstants ourInstance;
private MyConstants() {
//private constructor to limit direct instantiation
}
public synchronized static MyConstants getInstance() {
//if null then only create instance
if (ourInstance ==null) {
ourInstance = new MyConstants();
}
//otherwise return cached instance
return ourInstance;
}
}
You just need a private constructor and public static method that would only generate instance if it is null.
Then, call MyConstants.getInstance().whateverMethod(). It will create only single instance.
However when using singleton, please keep memory leaks in mind. Do not pass activity context directly inside singletons.
If you want to have all methods in activities, you can put then in abstract class BaseActivity, which extends Activity, and then make your activities extends BaseActivity. However, if these methods doesn't correspond to something about activity, I suggest some Singleton or Util class
I agree with Pier Giorgio Misley. It's also good to add a private constructor, because you don't obviously want to instantiate an object.
Can't you just use a parent class? That way you can just inherit the methods and manage in one source. Then you don't have to use static functions then.
Edit: Like Tomasz Czura said, just extend the Class.
public class ParentClass {
public void commonMethod(){
}
}
public class OtherClass extends ParentClass{
}
You can use the Static keyword.
Static methods can be referenced from outside without istantiating the new object.
Just create a class:
public class MyClassContainingMethods{
public static String MyStaticMethod(){
return "I am static!";
}
}
Now call it like
String res = MyClassContainingStaticMethods.MyStaticMethod();
Hope this helps
NOTE
You CAN call non-static from static by doing something like this:
public static void First_function(Context context)
{
SMS sms = new SMS();
sms.Second_function(context);
}
public void Second_function(Context context)
{
Toast.makeText(context,"Hello",1).show(); // This i anable to display and cause crash
}
Example taken from here, you will obiouvsly have to fit it into your needs
Here is my scenario.
I have an android activity in which I want to abstract my I/O dependencies. The dependencies are represented by this interface (edited for brevity and simplicity):
public interface ITimeDataServer {
TimeRecord[] get(int userID);
void save(TimeRecord record);
}
What I want is for my activity to be able to call these interface methods, and leave the implementation to be supplied by the calling code. (Pretty standard, I think).
ITimeDataServer myServer;
int myUserID;
void loadRecords() {
TimeRecord[] records = myServer.get(myUserID);
// etc...
}
My difficulty is, how can I ensure that myServer gets set?
This seems like a common problem, but I can't find a clean solution.
My first thought would be that myServer would be passed in through the constructor, but Android activities aren't really instantiated with constructors.
I've come up with several solutions, but they're all icky in some way:
Icky Solution 1
Create a static method to launch the activity class which takes an ITimeDataServer parameter and stores it in a static variable from which the activity can access it:
private static ITimeDataSource theDataSource;
public static void launch(Activity currentActivity, ITimeDataSource dataSource) {
theDataSource = dataSource;
Intent intent = new Intent(currentActivity, MainActivity.class);
currentActivity.startActivity(intent);
}
This is icky because (a) the data source is static and not actually associated with the instance, and (b) a consumer could initiate the activity by the standard activity API rather than this static method, which will cause NullPointerException.
Icky Solution 2
I can create a Provider class which provides a singleton instance of ITimeDataSource, which needs to be initialized by the calling library before use:
public class TimeDataSourceProvider {
private static ITimeDataSource myDataSource = null;
public void initialize(ITimeDataSource dataSource) {
myDataSource = dataSource;
}
public ITimeDataSource get() {
if (myDataSource == null)
throw new NullPointerException("TimeDataSourceProvider.initialize() must be called before .get() can be used.");
else
return myDataSource;
}
}
This seems a little less icky, but it's still a little icky because the activity's dependency is not obvious, and since there may be many paths to launch it, it's highly possible that some of them would forget to call TimeDataSourceProvider.initialize().
Icky solution 3
As a variation on #2, create a static IODependencyProvider class which must be initialized with ALL dependencies on app startup.
public class IODependencyProvider {
static ITimeDataSource myTimeData;
static IScheduleDataSource myScheduleData; // etc
public static void initialize(ITimeDataSource timeData, IScheduleDataSource scheduleData /* etc */) {
myTimeData = timeData;
myScheduleData = scheduleData;
//etc
}
public static ITimeDataSource getTimeData() {
if (myTimeData == null)
throw new NullPointerException("IODependencyProvider.initialize() must be called before the getX() methods can be used.");
else
return myTimeData;
}
// getScheduleData(), etc
}
This seems superior to #1 and #2 since a failure to initialize would be much harder to sneak by, but it also creates interdependencies among the data types that otherwise need not exist.
...and other icky variations on that theme.
The common themes that make these solutions crappy:
the need to use static fields to pass non-serializable information to an activity
the lack of ability to enforce initialization of those static fields (and subsequent haphazardness)
inability to clearly identify an activity's dependencies (due to reliance on statics)
What's a nooby Android developer to do?
As long as these dependencies implement Parcelable correctly, you should be able to add them to your intent, then unparcel them as ITimeDataServer and get the correct class.
I found a nice solution here, in the least-loved answer.
I define the library activity as abstract and with no default constructor, but a constructor that takes an interface, like so:
public abstract class TimeActivity extends AppCompatActivity {
private ITimeDataSource myTimeDataSource;
public TimeActivity(#NonNull ITimeDataSource dataSource) {
myTimeDataSource = dataSource;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time);
// do stuff with myTimeDataSource!
}
}
Then, the calling code can create a concrete subclass with its chosen implementation that does have a parameterless constructor. No static members, easy-peasy!
This allows you to abstract and inject all sorts of crazy behaviours! Woooo!
(Note that the concrete subclass activity needs to be manually added to AndroidManifest.xml, like all activities, or the app will crash when it tries to launch.)
In my android project, I have many activities and some of them already extend other stuff like map activity or BroadcastReceiver.
How do I create a function that I can call from any activity, because I don't want to have to repeat any code in multiple activities.
thanks.
If I have useful functions that perform little helpful tasks that I want to invoke from several Activities, I create a class called Util and park them in there. I make them static so that I don't need to allocate any objects.
Here is an example of part of one such class I wrote:
public final class Util {
public final static int KIBI = 1024;
public final static int BYTE = 1;
public final static int KIBIBYTE = KIBI * BYTE;
/**
* Private constructor to prevent instantiation
*/
private Util() {}
public static String getTimeStampNow() {
Time time = new Time();
time.setToNow();
return time.format3339(false);
}
}
To use these constants and methods, I can access them from the class name, rather than any object:
int fileSize = 10 * Util.KIBIBYTE;
String timestamp = Util.getTimeStampNow();
There's more to the class than this, but you get the idea.
You can extend the Application class, then in your activities call the getApplication method and cast it to your application class in order to call the method.
You do this by creating a class that extends android.app.Application:
package your.package.name.here;
import android.app.Application;
public class MyApplication extends Application {
public void doSomething(){
//Do something here
}
}
In your manifest you must then find the tag and add the android:name="MyApplication" attribute.
In your activity class you can then call the function by doing:
((MyApplication)getApplication()).doSomething();
There are other ways of doing something similar, but this is one of the ways. The documentation even states that a static singleton is a better choice in most cases. The Application documentation is available at: http://developer.android.com/reference/android/app/Application.html
You could create a static method or an object that contains this method.
You can create a class extending Activity, and then make sure your real activities are subclasses of that activity, instead of the usual built-in one. Simply define your common code in this parent activity.
Shachar
Create a new Java class BaseActivity with abstract Modifiers and extends it with AppCompatActivity.
Move all your methods under Java class BaseActivity.
package com.example.madbox;
public abstract class BaseActivity extends AppCompatActivity {
protected void YourClass() {
}
}
Extends your Activities with BaseActivity but not AppCompatActivity.
I am creating a library project for a number of android apps.
The apps all have some common functionality that I wish to include in the library project but the library project functions require use of application specific constants
So I am looking for a way to provide the library functions with the names of the constants and allow each app to define them
An example of a specific app constant and how it is used within the library project
public class AppConstants {
public static final long APP_ID = 6;//Needs to be set for each app
}
public static long getCurrentAppId(Context context) {
return getLongPreference(context, CURRENT_APP_ID_KEY, AppConstants.APP_ID);
}
This is just one example of approximately 60 constants that need to be defined for each app for a large number of library functions
Obviously I would normally just import/include the project specific app_constants.java file but this is not possible in the library project files as it hasn't got a clue about the specific applications (rightly so)
So what is the best way to have each specific app override the constants?
Update
I took a long time deciding on which of the superb answers I have been provided with best suited my needs (Thanks everyone) In the end I chose the xml solution. I don't particularly like it because it clutters up my apps resources and I did seriously consider using the interface solution but the xml solution does work nicely
Option #1
Extend your AppConstants class in each project
Better Option#2
Use XML resources to define the constants
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="integer" name="app_id" format="integer">6</item>
</resources>
then you can retrieve them by
Context.getResources().getInteger(R.integer.app_id);
add the xml file to your resources in each project with only the values you need different
I don't know of a great schema to do that but it would certainly work this way:
define some base class in your library
// class, enum or whatever you want it to be.
class BaseConstants {
// use some real singleton instead
public static final BaseConstants instance = new BaseConstants();
// define those values - sadly static inheritance does not work
private static final int APP_ID = 0;
private static final int CURRENT_APP_ID_KEY = 24;
// so we have to do that via methods
protected int getAppId() {
return APP_ID;
}
protected int getAppIdKey() {
return CURRENT_APP_ID_KEY;
}
}
let each Activity that wants something custom implement that
class App1Constants extends BaseConstants {
public static final App1Constants instance = new App1Constants();
private final static int APP_ID = 1;
// want a different APP_ID here.
protected int getAppId() {
return APP_ID;
}
// getAppIdKey not implemented here, uses default
}
Use that class as context to the constants for your library
class Library {
public static long getCurrentAppId(Context context, BaseConstants settings) {
return getLongPreference(context, settings.getAppIdKey(), settings.getAppId());
}
}
Activities would be like so
class myActivity extends Activity {
// each Activity can implement it's own constants class and overwrite only some values
private static final BaseConstants CONSTANTS = App1Constants.instance;
private void whatever() {
long appId = Library.getCurrentAppId(this, CONSTANTS);
}
}
class myActivity2 extends Activity {
// or could just use the default ones
private static final BaseConstants CONSTANTS = BaseConstants.instance;
private void whatever() {
long appId = Library.getCurrentAppId(this, CONSTANTS);
}
}
That schema is kind of ugly but it would work at least
Define them as enum's in your library project, like
public enum Planet { MERCURY, VENUS, MARS }
Android proper takes another approach, the dreaded constant interface, like,
interface Planets {
static final int MERCURY = 1;
static final int VENUS = 2;
...
}
However, this is a well-known Java anti-pattern (constant interface, and is covered in detail in Effective Java, I quote,
The constant interface pattern is a poor use of interfaces. That a
class uses some constants internally is an implementation detail.
Implementing a constant interface causes this implementation detail to
leak into the class’s exported API. It is of no consequence to the
users of a class that the class implements a constant interface. In
fact, it may even confuse them. Worse, it represents a commitment: if
in a future release the class is modified so that it no longer needs
to use the constants, it still must implement the interface to ensure
binary compatibility. If a nonfinal class implements a constant
interface, all of its subclasses will have their namespaces polluted
by the constants in the interface.
If you need the constants to have int values for some reason, and calling toString() on the enum isn't sufficient, you can give the enum's a extra information like,
public enum ZipCode {
LYNNWOOD(98036), SAN_JOSE(95112), ...;
private int zipCode;
private ZipCode(int zipCode) { this.zipCode = zipCode; }
public int getZipCode() { return zipCode; }
}
Note that enum's are slightly less performing than integer constants, but from a code organization and clarity perspective they are far superior.
For every Activity I add to my app I'm noticing a lot of similar code being used in the initialization of the Activity. A helper class with a static method to wrap this similar code seems the way to go.
I first thought of a singleton class. I could add static methods/variables and use them across the application. I haven't really tried to see how would this work in an Android application. Searching a little bit more I saw something about creating a class extending Application. For this I did a simple test:
public class MyApp extends Application {
public static String DEMOTEXT = "WORKING!";
public static void ShowToast(Context context, String text) {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
}
MyApp.ShowToast(this, MyApp.DEMOTEXT); // Placed on onCreate of some Activity
This works exactly as I expected. Is this the way to go on Android or is there a better convention? Anything else I should consider when doing this?
By the way, should I use the final keyword on the string? What about the method?
EDIT: I just read 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.
http://developer.android.com/reference/android/app/Application.html
Should I use a singleton then?
Application is primarily used for a global application initialization. You would create your own class, override Application.onCreate() and initialize your static application data there.
Dont forget to declare it in the AndroidMainfest.xml:
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
android:name="your.package.path.to.MyApp">
A static helper class is made the way you did.
The convention is to use lower case letter at first position, so MyApp.showToast(...).
You would use final for the String if you would want to avoid madifications on other places (since it should be a contant).
// this would allow ...
public static String DEMOTEXT = "WORKING!";
// ... to do this somewhere else
MyApp.DEMOTEXT = "NOT WORKING!"
I haven't tried this but I think you should be able to do something like this as well.
public class MyActivity extends Activity {
private static final String DEMOTEXT = "WORKING!";
#Override
public void onCreate(Bundle bundle)
{
super.onCreate(bundle);
Toast.makeText(this, DEMOTEXT, Toast.LENGTH_SHORT).show();
}
}
Now for all activities that need to use that initialization could just extend your base activity class.
public class SomeActivity extends MyActivity {
...
// Should display the toast on create
...
}
Yes just use a singleton. Well in this case if your methods are static, you don't even need a singleton. Just a class with static methods.