As I continue to work on and debug my hobby app to learn/practise Xamarin Android devt, I discovered I produced a version that could be installed on my phone, but it could not be run. (After successful installation, only the Done button could be pressed, the Open button was grayed out)
s'shot of Open button that is grayed out when the public static class is added in the code
There were a few changes since the last version that could be run, and having narrowed it down, the problem is the definition of a public static class in order to define some global variables.
public static class GlobalVariables1
{
public static string TdyAlertTime1 = "11";
public static string TdyAlertTime2 = "15";
public static string TdyAlertTime3 = "21";
}
This was adopted having followed How to declare global variable. I have tried making adjustments to that but still not resolving.
I also tried other methods found on the Net to no avail:
Store data and global variables using the Application object
public class HelloApplication : Application
{
public static int GlobalVariable = 1;
}
I also saw SharedPreferences and Application Properties Dictionary but the latter seemed applicable for certain functions eg. OnStart; and the former, I had poor experience before when trying to develop a Preferences screen.
But back to my original intention. I want to define simple global variables or constants (actually for debugging purposes currently, but learning it would be useful for other purposes too) to be utilised in two different classes in my project.
What could be wrong with the method I adopted (to cause the inability to run)? Or what method could I really use in a simple manner?
Thanx & Rgds
Related
How do i find where static variable are used in android studio project? Is there any way to find such variables . As my project is too big and i want to remove possible memory leaks. Help me to achieve this. Thanks
I have been using this trick for a very long time now. I am sure this will definitely help you. Follow the instructions step by step and this will help...
If you are using windows, Press Ctrl + Shift + F to open entire project search...
Next, In the text to find add this Regex (public|private|protected) static and under options select case sensitive and Regular expression. This will match public static or private static or protected static.
In the scope, select the project production files
Set the file mask as *.java
Set the context as except comments and string literals
When you hit Find, you will get 1000's of results. You will find results like this:
Completely ignore the usages in generated code.... IMPORTANT
Only search in the found occurences for your static variables.
PS :
One drawback with this is that this will match static methods too... such as public static int randomMethod() { }
If your static variables don't have access specifiers such as public private or protected, just use regex as static .
1.Open your andorid project.
2.Click ctrl+shift+f
You will get a dialog box.
Then search static
You will get all static members and functions.
You can do right-click on said variable and choose Find Usages:
Result will be revealed on Find panel on bottom-right of the window.
I am building an application and use labels in the following areas.
1. Component Names (TextView, Buttons etc)
2. Buttons in alert boxes
3. Parameters to AsyncTask
4. Key names in Intent extras
5. Log tags
I have got strings.xml files to store and use labels. I am using using it for category 1. What do you think is the best option for others?
res/strings.xml or
Constants class ?
I'll suggest to you what I normally do:
For everything that the user will read on the screen or be referenced in anyway from a XML layout, use strings.xml. I reckon that includes your 1 and 2. But remember that for AlertDialogues you can also use android.R.string.ok or android.R.string.cancel, etc; that will vary from use to use.
Also for project config values, or API keys, you could have a config.xml with String, Integers, etc. Something that makes easy to later on change those values without diving into the code.
For AsyncTask, it varies a lot of what work it is doing, but usually a network, DB or disk operation, and I try to include private static final String URL_PT1 = "http://..."; etc, in the classes themselves, as they are the only interested in knowing that address (or DB columns, or file prefix)
For key names (both in Intent and Fragment arguments) I use private static final String KEY_VALUE = "renjith.Key.MyClassName.VALUE"; and then create a public static Bundle getIntentExtras(String value) inside that class that will properly allocate the value in the extra. That's because only that one class needs to know about it's KEY values, there's no reason to make those public accessible, that will just create errors for outside classes doing it wrong.
For Logs (5), create on every class a private static final String TAG = "Renjith.ThisClassName"; (and for Fragments make the TAG public to be used in transactions). That way you can create a filter in LogCat Renjith.* and you can easily identify from where this log is coming from
edit:
For sharedpreferences it depends:
for GlobalSharedPreferences I would create one class to handle them with static set/get methods that must receive Context and all keys private static inside that class.
For local shared preferences (that only one class is interested in saving/retrieving) I would handle in a SharedPreferences file with the same name as that class and all the keys as private static inside that one class.
Again, same philosophy, only the classes that really need to know about those details will know about them, and abstracting to the rest of the classes with direct method calls.
I need a solution for the really common but important issue that i am thinking of.
I have created application in which i have hard coded my server address in /res/values/strings.xml file. Suppose if my server address changes run-time due to some reasons, then i have to make changes in the file and then i have to recompile it.
So is there any way that i put my server address out of my application.. So we do not have to recomplie the application. Instead of it, it will read new server address from out side and resume its normal work...
Any type of related suggestions,links,blogs appreciated..
While I am making apps in Android , I mostly create a Utility class e.g. Constants.java , Utils.java etc. In these classes, I put all the constant numerical and String values like this:
public static String ip="74.117.153.111";
public static final String LOGIN_TOKEN_URL = "http://"+ ip + "/api/getLoginToken";
public static final String USERNAME_PARAM = "username";
public static final String PASSWORD_FIELD_EMPTY_ERROR = "Please enter password";
public static final int GRID_ICON_COUNT = 4;
public static final String FACEBOOK_KEY = "16411636362877862";
These are some type of constants which we generally use here and there. So I put them into a different dedicated class. So now when I need their value somewhere, I get it like this:
params.put(Constants.USERNAME_PARAM, username);
fbRocket = new FBRocket(this, Constants.APP_NAME,Constants.FACEBOOK_KEY);
The benefit of this approach is that if I have to change a value later on which is being used at lot of places , then I don't have to change it everywhere. I will just change the value in Constants.java and this change will replicate in the whole app.
Utils.showErrorMessage(this, Constants.PASSWORD_FIELD_EMPTY_ERROR, Constants.TOAST_VISIBLE_SHORT);
I got the answer by reading this blog.
Which says you should use shard preferences with the activity extending PreferenceActivity.
Here you can set your server address and all the dynamic stuff that will change by the time. So that you will not have to recompile the apk. Just change the settings in shared preferences.
Read this important bog that all app developer wants to know it..
Is there a way to have an global settings variable for an android application, which is accessable as well from any help java classes without giving them context?!
I try to explain what I mean.
I have an application version as string value in strings.xml
I can get its value from every android activity, but not from help java classes withought giving context
What I do now, is saving it in a static variable of my first activity, but it seems, that sometimes it will be erased and set to null.
May be I do something wrong?!
Sorry for newbie question.
And thank you in advance,
Mur
P.s.
I wrote a small tutorial for this topic, to show the solution.
A variable declared as public, static, and final will be visible to all of your classes and never get erased.
public static final String VERSION = "1.2.3.4";
You could make a public static variable in your application class that you fill with the value from strings.xml in the onCreate method. The application class is a singleton and will be the last thing that is killed as part of your app so it will always be there and if you make it public static there will be only one instance.
I'm guessing that you have a JAVA class for some common utility functions. You get the value of your string using a context in your Activity/Service and then pass in that value to the JAVA class function as a parameter.
I'm adding Android C2DM to a Android library project. I started with the com.google.android.c2dm package that is included with JumpNote and Chrome To Phone. In order to use this package, you have to subclass the C2DMBaseReceiver service which takes the Sender Id as an argument to it's constructor. In JumpNote, this argument is initialized using a hard-coded static variable in a config class. However, in an Android library project, which may be used by multiple concurrently running apps I don't think I can use a hard-coded static variable (that is, I believe it could lead to problems when/if multiple apps are trying to access/modify the static variable).
I tried to think of a way to initialize the Sender Id without using a static variable and am stumped so far.
The obvious solution would be to use the Manifest or a Resource string or a combination of the 2. For example, in strings.xml I might have a "ac2dmSender" string, which is accessed in a meta-data child of the C2DMReceiver service declaration in the manifest. However, it seems that you cannot get a reference to the PackageManager or ResourceManager from a static context, so there is no way for me to then retrieve the meta data in such a way as to pass it in to the constructor of C2DMBaseReceiver.
Please let me know that I'm missing something! Thanks in advance.
We had same problem.
We solved it by using properties file under the assets folder.
Can load the properties staticly by using static configuration helper class.
On the first time the application is loaded can get the properties file using the Application context.
for example:
1. init the static configuration
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myConfig = new WLConfig(getApplication());
}
Then use in the configuration class:
myProperties.load(context.getAssets().open("myclient.properties"));
And get the sender email:
return myProperties.getProperty(WL_C2DM_SENDER)
However, in an Android library project, which may be used by multiple concurrently running apps I don't think I can use a hard-coded static variable (that is, I believe it could lead to problems when/if multiple apps are trying to access/modify the static variable).
"Multiple concurrently running apps" each have their own copy of the static variable, since each runs in its own process.