I have several different Android projects that use a library where I've created most of the common classes. One of the classes is "commonSettingsAndFunctions" where I've defined several static strings and methods to be used. Example:
public class commonSettingsAndFunctions {
public static String flurryCode = "MY_FLURRY_CODE";
public static final int APP_VERSION = 2;
public static final String API_URL = "http://mydomain/api.jsp"
public static String getAPIUrl(Context context, String parameters) {
// code
}
}
However, now I've come up with a situation where I have to change some of the settings per project. For example, flurry code and app version. API_URL is always (so far) the same.
What's the best way to implement this? One option I thought of is making commonSettingsAndFunction as abstract, create a class "commonSettingsAndFunctionsReal extends commonSettingsAndFunctions", then implement the "Real" class per project? Another possibilities?
I come from PHP world, and there I'd just have settings as a class, and do this in some "global include file":
$common = new commonSettingsAndFunctions();
$common->flurryCode = "ABCD";
AppVersion is something that is in the AndroidManifest.xml and you can access that from code, so you don't really need your own version of it. As fo the Flurry API key, I always put mine in my strings.xml so I can load it in when I need it.
Related
In several tutorials, I've seen result codes set as "private static final int"s at the top of pertaining activities. To me this does not seem like the best way to do this since I find myself having to constantly refer to other classes to find the correct code rather than referring to the same code created somewhere else.
Is there a better way to do this? Is it bad practice to just make a utility class to hold the common result codes, request codes, data keys, etc? I've just never seen this done before.
Another way is to keep this variables in Gradle build and use them like this: BuildConfig.VARIABLE
Example:
In gradle file:
buildTypes {
release {
buildConfigField "java.lang.String", "DATABASE_NAME", "\"db_name\""
}
}
In Java:
BuildConfig.DATABASE_NAME
Pros:
can change constants values for different builds
there is one place with all program constants
auto generated (BuildConfig) by IDE/Gradle
References:
0.14.3 http://tools.android.com/tech-docs/new-build-system
http://toastdroid.com/2014/03/28/customizing-your-build-with-gradle/
I think it's personal preference, although it seems more meaningful to have all your statics in utility class. The tutorials probably show them in Activies for simplicity which is far easier to understand than using utility classes when they only need a couple of statics.
If you need to share constants for few classes, you can create special "constants" class and refer to it.
package ru.kopeyko.***;
/**
* class for holding various CONSTANTs for '***' app
*
* #author Andrey Kopeyko <andrey#kopeyko.ru>
*/
public final class Const {
public static final String UUID_DEFAULT = "00000000-0000-0000-0000-000000000000";
public static final String VERSION_CODE = "versionCode";
public static final long ONESECOND = 1000L;
public static final int POSITIONS_MAX_DAYS = 32;
public static final long DB_MAINTENANCE_INTERVAL = 1*86400*1000L;
}
I am working on my first Android Project. I have a Service class that waits for receive intents to retrieve some information from a remote server. This service of mine looks something like this:
public class MyService extends IntentService{
public static final String ACTION_INTENT_01 = "xyz.actionIntent01";
public static final String ACTION_INTENT_02 = "xyz.actionIntent02";
public static final String ACTION_INTENT_03 = "xyz.actionIntent03";
... A lot of constant more...
public static final String ACTION_INTENT_01_EXTRA = "xyz.actionIntent01Extra";
...more and more constants...
public MyService(){
...
}
/*The Rest of The Service*/
}
My question is, what is better, having a lot of constant strings inside this class or declare them on the String.xml file and access them by getString(R.string.ACTION_INTENT_03) ??
Thanks!
None of these. I would recommend to have a constants class and put these constants in that class. In this way your service class is smaller and easier to maintain.
You should put strings in strings XML files only if those are subject for localization changes: in English have a specific value, in French a different value and so on. Or if you want to use them in XML UI layouts. So if you have constants to use only in code, there's no reason to have them in XML strings.
You can do in both ways. Personally I declare the strings that are showed in the UI into strings.xml, and string constants in the source code.
One reason the string resources to be declared in the strings.xml is that later they are easy to localize.
Declare them in strings.xml because if you are modifying value that modified will be reflected everywhere.
I'm developing an android application which uses web service to get data from server, for that I'm having three different set of URLs to point development system, test server and live server. It's difficult to change URL whenever I want to give application for testing/live. so I planned to make it as configurable, so that application can get appropriate URL based on me build type configuration constant.
So,
which is the best way to keep this constants, java static class or
java public interface or xml resource file.? When? Why?
which gives better performance?, When? Why?
Ex: xml resource
<integer name="config_build_type">0</integer>
<string-array name="url_authentication">
<item >http://development.com/xxxx</item>
<item >http://test.com/xxx</item>
<item >http://example.com/xxx</item>
</string-array>
Java static constant
public class Config {
public static final int BUILD_TYPE = 0; // 0 - development, 1 - test, 2 - live
public static final String[] URL_AUTHENTICATION = {"http://development.com/", "http://test.com/", "http://example.com"};
}
There is a big difference between the two in that you can reference project resources in your XML layouts. They are available in the application context and are therefore accessible across the global application. The biggest advantages of using project resources is the ease of access and that they allow you to organize your project significantly.
static final constants are compiled into the java bytecode; project resources are compiled into a binary format within the apk. Accessing either is extremely efficient... if there is a difference between the two, it is trivial at most.
There isn't a set rule on how you should be using resources/constants in your project. That said, I personally use resources for values that I might need to use in my XML or java code. On the other hand, I typically use static final constants for values that will only be used by my java code and are specific to my implementation.
Also note that it is possible to load XML resources at runtime depending on the device's current configuration (i.e. screen size, locale, etc.). So you should take this into consideration when deciding whether or not you should declare the constant in XML or directly in your .java files.
For the people who want to see how we can use a Class to define our constants and call any where we need.
Constant.java
package org.nrum.nrum;
/**
* Created by rajdhami on 5/23/2017.
*/
public class Constant {
public static final String SERVER = "http://192.168.0.100/bs.dev/nrum";
// public static final String SERVER = "http://192.168.100.2/bs.dev/nrum";
public static final String API_END = SERVER + "/dataProvider";
public static final String NEWS_API = API_END + "/newsApi";
public static final String BANNER_API = API_END + "/bannerApi/lists";
public static final String NOTICE_API = API_END + "/noticeApi/lists";
public static final String UPLOAD_PATH = SERVER + "/uploads";
public static final String UPLOAD_PATH_BANNER = UPLOAD_PATH + "/company_1/banner";
public static final String UPLOAD_PATH_NEWS = UPLOAD_PATH + "/company_1/news";
public static final int BANNER_TRANSITION_DURATION = 5000;
public static final int NOTICE_BUTTON_BLINK_DURATION = 5000;
public static final int BANNER_FETCH_LIMIT = 3;
}
Now we can use above constants in following way.
Constant.NOTICE_BUTTON_BLINK_DURATION
In general case:
XML values have the advantage of accessbilty in layout file and manifest file over Constants in java file
XML values have the advantage for multi language support over Constants in java file
It’s always a good practice to extract UI strings from your app code and keep them in an external file. Android makes this easy with a resources directory in each Android project.
http://developer.android.com/training/basics/supporting-devices/languages.html
I think both way seems to be good but thing is that it depends on your requirements.
If you have your values(web service link) in your XML and suppose there is any change in your values(web service link) , you can easily change only in XML file.
But if you use inside classes as static variables you have to change in all class files.
So my suggestion is that separate constants from source file and put into resource and access it..
If the constant related or depend on locale or language or use in manifest you may consider to use xml values
If the constant dont't related to translation or locale or use in manifest I would avoid to put it in xml resource
I would add enum inside the viewmodel or whatever that need to use constant as a key.
enum class Key{
key,rule,practice
}
Or
const val MY_CONST = "my constant"
In Kotlin:
class Foo() {
// any other code for the class Foo
companion object {
const val MY_CONSTANT = "my constant"
}
}
This method is particularly recommended for data object.
Project resources need access to Context, which is not available in static methods unless you pass it in, but is always available in Activities -- there seems to be a preferential connection between resources and layouts.
For app variables and constants that may be processed in static methods I create an abstract class and do a static import (of this constants class) in all the other project class files.
I noticed myself constantly typing:
someVar = getResources().getString(R.string.someString);
I have several XML files that I am parsing and building and in order to make sure that the files stay consistent, I have placed the tag names in the res/values/strings.xml file. The same handles are used throughout several activities, and some of those activities extend ListActivity while others do not so creating a simple super class which houses these variables ( ex:
public class thisClass extends thatClass
{...}
public class thatClass
{
package String someTag = "this";
package String otherTag = "that";
}
I would assume that all of these calls to getResources() could get pretty taxing and was wondering if it is beneficial to instead create an R-type file where I can store these types of commonly used variables statically ex:
public final class globalVars
{
public static final class XML_TAGS
{
static final String someTag = "this";
static final String otherTag = "that";
}
}
and to reference these variables like such:
serializer.startTag("", globalVars.XML_TAGS.someTag);
instead of
serializer.startTag("", getResources().getString(R.string.someTag));
Thanks for the input!
OK, after looking into the source code of android.content.res.resources and some other classes, it is evident that using Resources and getting resources through getResources() is costly compared to a static class.
Indeed, the instance of Resources returned is not a static container but rather an object that gets resources by executing a couple of statements (whether a string or drawable or any other form).
However, using getResources() has its advantages:
It helps you externalize your resources.
For any type of resource, you can specify default and multiple alternative resources depending maybe on Locale, Screen Depth/Resolution...
A static container might provide a less costly alternative than using resources but remember: any later attempt at localization would be relatively extremely costly.
I'm fairly new in Android/Java programming, so some of the basic stuff is still quite confusing. So, lets say my application gets all data (articles) it requires from external XML files, it parses them to data models (Article class) and those articles will be used (displaying in lists or single article) all over the application for all it's lifecycle.
Where should I keep them? Can I create singleton class with an array containing all the articles I've parsed? Or should I save them to database and then query it on demand? (that sounds like too much work, I don't need to cache them for now) What's the best practice here?
Keep them in Application. This is a base class of any android application and it's alive during the whole lifetime of the application, whereas Activities are killed when not shown or orientation is changed.
You have to declare android:name in your AndroidManifest.xml:
<application android:name=".YourApplication"/>
Edited:
This is also relevant: How do I pass data between Activities/Services within a single application?
that depends what is your programming style lol.
you can as you said create a singleton that will read your xml and store everything.
you can create a static hash in your class. this way when you create a new object you will have access to the static information from that class.
you can pass the information from class to class as parameters.
if you want us to tell you which one would be the best it will be difficult without knowing the architecture of your program.
for example you could have a view controller that handle any changes and then it is simple to store the data at that level to pass it on when you switch views.
you could have static views in wich you could directly set all the values as you open them.
you could have losely linked views that call each other without any controller to handle the switching and in that case you would may prefer having a way to collect the info you need from a singleton or a static method...
As long as you make sure that you don't have any threads acting on the shared data you can just create a static class with static members. each activity will be able to access it. If using async download for your data then in the onPostExecute of your handler you can touch the GlobeVars because that runs on the UI thread.
public class GlobalVars {
public static String userId = "?";
//public static String serverUrl = "10.0.2.2"; //localhost when developing
public static String serverUrl = "192.168.1.4"; //on device to laptop
//public static String serverUrl = "102.192.293.10"; //production
public static Book currentBook = null;
public static Chapter currentChapter = null;
public static int lastclickedChapter = -1;
public static Voice currentVoice = null;
public static String catalogJson = "";
public static ArrayList<Book> catalogItems = null;
}
onCreate of MainActivity I can set the catalog to my downloaded list of xml coverted to objects
GlobeVars.catalogItems = downloaded xml to object list
in my SubActivity which is a list of chapters in onclicklistener I can set:
GlobeVars.currentChapter = items[clickeditem];
when you return to the main activity the values will still be set.