Access a static variable from a service - java

My application has a service and my MainActivity has a static variable :
public static boolean appIsPlaying = false;
And my service code is something like this :
MainActivity.appIsPlaying = false;
This code works well but I'm not sure that it's a true way. So, would you help me if there is a problem with this solution?
Thanks

I don't really agree with the people who say let's just use getters and setters for everything, and that's the solution. Your solution is simple, but effective. There are no problems with this way of communication between a service and an activity per se. This isn't some public API, so using public fields isn't a definite no-no.
Problems can only arise if you have certain requirements which you have to fulfill. This from of interaction is the simplest, therefore it can't do much. For example, if you want to listen to the event of changing the value, then you will have a problem because you just set the value and don't notify the activity.
If that's the case, then you can bind to the service, and implement more complex interaction. Listening to the value changes could be done by storing listeners in the service and notifying them when changes happen.
There is not really the way to do it, there are more appropriate ones and less so. You have to choose one of them depending on your needs.

Put your static variable in a utility class and create static getters and setters with required validations. Making the class Single Instance is also preferred but what you are doing right is not without problems.

Related

Struts2 application scope instances

I've inherited a Struts2 project which needs some functionality addition. When I ran into de code to guess how the previous guy did things, I found out that if he wants a class to instantiate only once when the Tomcat server starts (because it has to read heavy loads of data from disk, but only once to get its config, for instance), he did this in the following way:
public class ExampleClass {
public ExampleClass(){//Read files and stuff to initialize}
public Object method(Object[] args){//The job to do}
}
And then, in the struts action which uses it he instantiates it this way:
public class SomeAction extends ActionSupport {
ExampleClass example = new ExampleClass()
public String execute() {
//Do stuff every time the action is called
Object result = example.method(args);
// Do stuff with results
}
}
I know from servlet times that this does the trick, however, I feel like the guy who handled this before was as inexperienced in Struts2 as I am, so here comes my question:
Is this the proper way to do so according to style recommendations and best practices? Does struts2 provide a more controlled way to do so?
I found some answers related to simple parameters here, but I'm not sure if this is the proper way for objects like those? What would happen if ExampleClass instance is really heavy? I don't want them to be copied around:
How to set a value in application scope in struts2?
Some background about ExampleClass: When the constructor is called, it reads large sets of files and extracts it's configurations from them, creating complex internal representations.
When method() is called, it analyzes it's parameters using the rules, and outputs results to the user. This process usually takes seconds, and doesn't modify the previously initialized rule values.
This is running in Tomcat 7, however, I'm planning to upgrade to Tomcat 8.5 when everything is in place. I'd like to know if there are known issues about this regarding to this setup aswell (there are no other incompatibilities in the code).
BTW: He's not checking if ExampleClass is broken or anything like that, this definetly looks like a recipe to disaster xD. In fact, If I remove the source files, it is still trying to execute the method()... Poor soul...
Ideally, I need a way to instantiate all my application-level objects on start-up (they're the application itself, the rest is just a mere interface) in a way that if they fail Struts2 will tell Tomcat not to start that war, with the corresponding error logging and so on.
If Struts2 doesn't support this, which is the commonly accepted work-around? Maybe some Interceptor to check the object status and return to a error page if it hasn't been correctly instantiated? Execute a partial stop of tomcat from within?
All the objects of this project are thread safe (the only write operation inside them is performed on initialization), but I'd like to know best practices for Struts2 when objects are not so simple. What happens if a user can actually break one? (I know I should by any means avoid that, and I do, but mistakes happen, so I need a secure way to get through them, and get properly alerted, and of course I need a way to reinstantiate it safelly or to stop the whole service).
Right now, I can manually execute something like:
public class SomeAction extends ActionSupport {
ExampleClass example = new ExampleClass();
private boolean otherIsBuildingExample = false;
public String execute() {
if(otherIsBuildingExample) return '500 error';
if(example==null || example.isBroken()){
otherIsBuildingExample = true;
example = new ExampleClass();
otherIsBuildingExample = false;
}
Object result = example.method(args);
// Do stuff with results
}
}
Indeed, this would be cleaner with Interceptors, or so, however, this sounds like a pain in the *** for concurrency, specially taking into consideration thay example takes several seconds to start, and that more requests can come, so more concerns to take into consideration, like: what if two people call if(otherIsBuildingExample) and the second one gets the value before the first one performs otherIsBuildingExample=true? Nothing good... If the class is simple enough, both will instantiate and the slower one will prevail, but if one instantiation blocks the other's resources... well, more problems.
The only clean solution I can think of is to make ExampleClass robust enough so you can repare it using its own methods (not reinstantiating) and make those thread safe in the common way (if 10 people try to repair it, only one will proceed, while the others are just waiting for the first to end to continue, for instance).
Or maybe everytime you call execute() you get a copy of example, so no worries at all about this?
I'm digging into struts documentation
Thanks in advance.

How to call methods from other classes not having an instance?

How can I call a method from a class that is not an object within another class, and has nothing in common with this other class?
In my case:
class GridUI {
com.google.gwt.user.cellview.client.DataGrid grid;
public void refresh() {
dataGrid.redraw();
}
}
class SomeBackendService() {
public foo() {
//have to trigger refresh of a specific grid
}
}
One possibility might be to make the refresh() and grid static. But that's bad design, and I cannot use this approach as I want to use several implementations of GridUI.
So, how can I refresh a certain gridclass in my app from any service that does not contain this grid as an object??
Just create and fire an Event for it in your service and make your grid register for that Event. It's probably best to use an EventBus.
Using a static Map<String, Grid> as was suggested in the accepted answer will work but it's not proper. You risk making mistakes and it's not as easy to manage when the number of grids increases.
The EventBus approach is more work upfront but in the end it's a better approach. You'll be able to reuse the EventBus throughout your application. It really helps keep your coupling down. You'll also easily be able to get different objects act on the same Event with little effort.
Alternatively create a components registry (basically a Map<String,Grid>), then fetch the grid from SomeBackendService using its id as key in the registry. (I guess you know which grid you want to refresh, right?)
Be careful with registries though:
make sure they are thread safe if need be (probably true in an UI app)
they tend to fill up and leak memory if not properly handled
Sorry for not answering that long time, i was in vacation.
Interfaces are some kind of classes.
But they do not implement any method, they have empty method bodies.
Each class, which implements an interface usually MUST implement its methods.
In C# You would Do :
enter code here
interface IMyInterface
{
void PleaseImplementMe();
}
class clMyInterface :IMyInterface
{
void IMyInterface.PleaseImplementMe()
{
MessageBox.Show("One implementation");
}
}
end
Please let me know, whether this is what can help You or not.

Best practice for keeping track of Callback result codes in Android/Java?

I'm creating a Facebook application that uses many calls to Facebook's asynchrunner class. As such, I am constantly using many callback listeners.. I have many classes that have to respond. I am finding that I cannot remember which classes are defining which callback listener result codes. I am worried that I am going to end up using the same callback result code in two different classes and this could cause serious problems. What is the best practice for organizing this? Thanks!
I think you probably meant "request codes", but it doesn't matter for the purpose of this answer. I would suggest creating a separate interface to contain all these codes:
public interface FBCallbackCodes {
public final static int AUTH_CODE = 1;
public final static int POST_PHOTO_CODE = 2;
...
}
Then, whenever you need to introduce a new code, just add another public final static to this interface and use it like FBCallbackCodes.AUTH_CODE rather than hard-coding the values where you're using them.
This way you're achieving two things:
All codes are kept in one place and you'll easily see what else to add without introducing duplication.
If you have two places in your app that use the same functionality with the same code, you can easily see that the required code already exists and just re-use it.

Background methods always as private class?

I'm starting with Android and wonder if background Task like DB reading and saving are always encapsulated in private classes?
I mean, at the moment I have:
private class SaveToDB extends AsyncTask..
private class ReadFromDB extends AsyncTask..
public void onButtonClick(View v) {
new SaveToDB().execute();
}
And so on. This way, I always have to create a new object if I want to execute background tasks. Is that the correct way?
What I wonder is that all my private classes are "actions" itself, not really objects. As they are named eg save or read which naming normally applies to methods by convention, not to classes.
Moreover, in case I'm doing it right: is it good practice to neast the private classes inside MyApplication Activity? Or should I refacter them out into own separate classes?
You could write a service to handle all the background content management. So, when you want to save, you just message the service and tell it to write data. This is much more complicated. For simple things, you can do it exactly as you are currently.
EDIT:
Also, as Ian pointed out, take a look at the new database interfacing classes post 3.0.
If you are firing of async tasks to interact with a sqlite database, then its not the best way to do things these days, you should check out cursor loaders instead.
http://developer.android.com/guide/topics/fundamentals/loaders.html
http://developer.android.com/reference/android/content/CursorLoader.html
Once you got your head around them they are much easier than firing off async tasks, infact they build on top of async tasks to address some of the issues you describe and are tolerant to configuration changes.
I highly recommend to move away from AsyncTask (for db access) and use the Loader API instead.
Its backported in the compatibility package so you can use them in older versions prior to Honeycomb.
Not always.
For example, if you've got a task that is to be used by different activities (I'm not talking about sharing the same instance), you will want a public class so you don't write it several times.
If you only use that (class of) task in one place, private class might help keeping your code cleaner.
It is a correct way for using AsyncTask, which isntance you can execute once.
Class Name can be DbSaver isntead of SaveToDb for instance which is more readable.
If that class is used only one Activity you can nest them, why not. But if you have task which is executed within different Activities, it is a good idea to create his own file.
It is good design to loosely couple your database access from your UI code. One way to avoid having to create a new object every time would be to make the database access classes a singleton and just return the instance of the class whenever you need to make a transaction.
To your last question it is a better idea to move the database management to its own class so that it can be accessed across several activities. If you do it all in a private class then what happens when you have a new activity that need s database access?

java - how to persist variable in JVM

I have an odd situation where i want to be able to be able to persist a variable in memory.. like a global variable I can pin in the JVM.
Is this possible? I remember doing something similar in college, but can't find it by googling. I have a logic problem that has some artificial constraints that make this the best possible solution.
EDIT 1:
I will need to update the value of the variable.
EDIT 2 :
I appreciate the responses guys. I'm a .net programmer and hadn't used java since college. Thanks again.
Yes, using a static field:
public class GlobalVariableHolder {
public static int globalVariable;
}
Note, however, that this is considered a bad practice and can lead to unexpected results that are hard to debug. The way to not use a global variable is to pass it around as an argument or methods where you need it.
If you are still sure you need this, in order to guard yourself as much as possible, use synchronization. Even better, if the variable is going to be primitive (int, long, etc), you can use AtomicInteger's getAndAdd() or addAndGet() method.
Usually you will end up storing these things in some kind of a global class--a class that is accessible from anywhere and has a controlled number of instances.
Singletons are commonly used for this. If you look up the pattern for a singleton and store your variable in that singleton (add a setter and a getter) you are on your way.
Doing this (as opposed to a public static variable) will give you some level of access control and traceability--for instance you can put debug statements in the getter if you find you are getting unpredictable results.
In the long run setters and getters and singletons are all bad code smells but no where near as bad as a settable public variable.
Later you may want to move the code that manipulates that variable into the singleton object and possibly convert the singleton to something you can fetch via IOC, but having a singleton is a much better place to start than with a public static.
Do you mean something that will exist across multiple invocations of java.exe, or do you mean a single variable that will be the same location in memory regardless of which thread within java.exe access it? Or do you mean a variable that can only be accessed if you're using JRockit? Or maybe just the JVM on your dev machine, but not on another system?
In the first case, you'd need another way to store it, like a config file.
In the second case, like Bozho says, use the static keyword.
In the third case, you'd probably need to use the System class and determine the JVM manufacturer (Assuming that's available from System - I'm not sure off the top of my head, and you'll learn more by looking up the API yourself).
In the fourth case, you're pretty much back to a config file.
Its not going to win any awards but this should work:
package mypackage;
public class MyGlobal {
public static String MY_GLOBAL_VAR = "my variable";
}
Any class within that JVM instance would be able to access MyGlobal.MY_GLOBAL_VAR.
Updated to allow update.

Categories

Resources