Frozen calendar - why? - java

As an experiment I ran the following code snippet (simplified):
public class SGamePlay extends Activity implements View.OnClickListener
{
Calendar GlobalCal = null;
public void onCreate(Bundle savedInstanceState)
{
GlobalCal = Calendar.getInstance();
}
long time_in_ms()
{
long ans = -1;
long ans2 = -1;
Calendar LocalCal = Calendar.getInstance();
ans = LocalCal.getTimeInMillis();
ans2 = GlobalCal.getTimeInMillis();
Log.e("game","ans="+ans+" ans2="+ans2);
return ans;
}
// much more code here...
}
The time_in_ms() function is called from a sub thread. The problem is that while ans appears to be a correct, constantly updating value, ans2 appears frozen at its initial value. How could this be?
EDIT: I need to resolve this issue because I want to reduce the need for garbage collection in my program.

Calendar is to be thought of as a "mark" in a calendar. It's more like a point in time, than an interface to the current time. (Why else would it have set-functions?)
So, the reason why ans2 is "frozen" is because GlobalCal.getTimeInMillis(); will always refer to the time when you called Calendar.getInstance() in the constructor (which you did once).
I need to resolve this issue because I want to reduce the need for garbage collection in my program.
Is the garbage collection the bottle neck of your program? Is the number of Calendars the bottle neck of the GC? Have you profiled your program?
Never mind... call System.currentTimeMillis instead.

GlobalCal is initialized in the oncreate method. It is not modified after that. How would you want it to change then ?
By the way, a variable name in java begins with a lowercase letter and follows camel case.

Related

Data stored in Class extending application returning null

I have a data class that extends Application and one of the data sets its supposed to be storing is a HashMap of POI locations and Time visited
public class CharacterSheet extends Application {
private HashMap<PointOfInterest, Date> coolDowns = new HashMap<>();
public HashMap GetAllCoolDowns() { return coolDowns; } //dev only?
public Date GetCoolDown(PointOfInterest poi) {return coolDowns.get(poi);}
public Date PutCoolDown(PointOfInterest poi, Date date) {return coolDowns.put(poi, date);}}
Then on a google maps activity I grab the OnPOIclick
#Override
public void onPoiClick(final PointOfInterest poi) {
//POI Cool Down
Date currentTime = Calendar.getInstance().getTime();
Date lastTime = ((CharacterSheet) this.getApplication()).GetCoolDown(poi);//this ONLY returns null??
if (lastTime != null){
int timeDiff = currentTime.compareTo(lastTime);
makeToast("Time Since last visit: " + timeDiff );
} else { makeToast("First");
}
((CharacterSheet) this.getApplication()).PutCoolDown(poi, currentTime);
makeToast("This?" + ((CharacterSheet) this.getApplication()).GetCoolDown(poi));}
The order should be Click poi, Get current time.. get last time visited, if last time is null.. never been before, store time and date in a hashmap with poi as key
Next time turn up and this time last time should not be null as we stored this poi and time already.. but no matter what it returns null..
Last line of code is a makeToast helper telling me what is in the Data Class.. this gives me a date value of when I clicked not a null value
There is a fragment generated later on in the OnPOIClick, but still before the user can do anything, which you end up looking at and have to "back" out of, I don't know how this could effect it as all the code is finished before even calling for data for the fragment but feel It should be mentioned
PlacesClient placesClient = Places.createClient(this);
String placeId = poi.placeId;
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.TYPES);
FetchPlaceRequest request = FetchPlaceRequest.newInstance(placeId, placeFields);
placesClient.fetchPlace(request).addOnSuccessListener(new OnSuccessListener<FetchPlaceResponse>() {
#Override
public void onSuccess(FetchPlaceResponse fetchPlaceResponse) {
Place place = fetchPlaceResponse.getPlace();
PlaceDataHolder holder = new PlaceDataHolder(place);
String placeName = poi.name;
makeLootFragment(holder,placeName);
The Fragment launched is the entire point of clicking the POI so if this is the case I'll need to think of another way of handling the cooldowns.. but I really don't see why it would interfere.
I was not being thoughtful enough about the PointOfInterest that was returned. It comes with a UUID for every time the request is made, rendering it useless as a key as every time I clicked it changed.. this was discovered by changing my post operation check from making sure it had gone into the hashMap, to seeing the contents of the entire hashMap, soon saw that the entries where building up despite only clicking one poi
To solve this was simple enough. I created a new String variable from poi.name and used that in place of the poi, had to change the HashMap to accept a String rather than a PointOfInterest

Java static variable update with quartz scheduler

I have a JobClass wherein I am calling another class named as MainClass. The quartz trigger schedule to run the Main class via JobClass every 5 minutes. Now in the main class I have to collect the current date time something like below:-
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd/hh/mm/ss");
Calendar calendar = Calendar.getInstance();
String CurrentDateTime = dateFormat.format(calendar.getTime());
public String[] splitMe = CurrentDateTime.split("/");
public String year = splitMe[0];
public String month = splitMe[1];
public String day = splitMe[2];
public String hour = splitMe[3];
public String minute = splitMe[4];
public String second = splitMe[5];
String FilePrefix = year.concat(month).concat(day).concat("_").concat(hour).concat(minute).concat(second);
String FilePrefix4ControlFile = year.concat(month).concat(day).concat(" ").concat(hour).concat(minute).concat(second);
String EarliestTime = year.concat("-").concat(month).concat("-").concat(String.valueOf(Integer.parseInt(day) - 1));
String LatestTime = year.concat("-").concat(month).concat("-").concat(day);
This way I can get all my date time individual variable to create some strings with different combinations. Every single job runs I need to have a unique set of values however whatever number of times these variables are called within one job run then the values should be same.
Now I tried doing it using Static variables which kind of solved one problem of having same values during 1 run. However as the static variables are created on class initialisation ( main class) then they will always have same value unless the class is reloaded which I don't want to do , indeed not that easily possible in java.
I am sure I am doing some silly mistake, any pointers on this will be helpful.
PS: I just started Java by my own recently.
Thanks guys!
RJay

How to destruct Object Data On certain time

I have one singleton object which actually store user activity. I wanted to remove this data on certain time ( at every night 12 ). I wanted to know How we can achieve this with out having different thread running.
Add a method to the singleton that returns the last date it ran:
static Date lastRun = new Date(); //when the class initializes
Date lastDateRan() {
return lastRun;
}
Then add another method that checks if today > lastRun (pay attention to check only the date - not time/hour - in case you decide to use TimeStamp or any other library).
Whenever the object is called, check:
if (today > lastRun) {
lastRun = today;
// and clean the object.
}
It won't run every-day exactly at midnight, but it'll have the exact same effect! (the first call after midnight will get "fresh" data)
You can use following code :
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
Object_name.close //your code to cleanup object
}
},
12*60*60*1000 /*time after which it will run again*/
);

Store an Calendar in constant field to use it later avoiding create it inside the method

Is there any problem with below code?
I want to use the method parseDateToInteger in a process that execute million times. This process can be accessed in multithread way, so I synchronized the method. I avoid to create the Calendar instance inside the method, cause its take a precious time. But I don't sure about this code behaviour. There are any problem in use this code?
private static final Calendar CALENDAR_BRASIL = GregorianCalendar.getInstance(LOCALE_BRASIL);
public synchronized static int parseDateToInteger(Date data) {
CALENDAR_BRASIL.setTime(data);
int ano = CALENDAR_BRASIL.get(Calendar.YEAR);
int mes = CALENDAR_BRASIL.get(Calendar.MONTH)+1;
int dia = CALENDAR_BRASIL.get(Calendar.DATE);
return ano * 10000 + mes * 100 + dia;
}
EDIT:
I See this article that makes me afraid, but the author don't used a synchronized method.
http://blog.bielu.com/2008/08/javautilcalendar-confusion-is-it-safe_28.html
This is a bad idea. Although you've avoided creating all of those objects, you now have a method that can only be used by one object at a time. So instead of creating a million objects, partially in parallel, you're going to have processes that have to wait their turn to use the Calendar.
Just create the instance for each thread.

Android: using Calendar to compare 2 dates

I'm trying to compare two instances of calendar but something does not work as I expect it. My code goes as following:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar now = Calendar.getInstance();
Calendar past = Calendar.getInstance();
past.set(2014,2,30);
Log.d("ppp",String.valueOf(now.after(past)) +" \n Past: " + past.toString() +" \n Now: "+ now.toString());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I would expect the above code to return true, but looking at the logCat this is what I get:
false
Past: java.util.GregorianCalendar[time=1396174280322,areFieldsSet=true,lenient=true,zone=Europe/Amsterdam,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=2,WEEK_OF_YEAR=14,WEEK_OF_MONTH=6,DAY_OF_MONTH=30,DAY_OF_YEAR=89,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=5,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=11,SECOND=20,MILLISECOND=322,ZONE_OFFSET=3600000,DST_OFFSET=3600000]
Now: java.util.GregorianCalendar[time=1394622680322,areFieldsSet=true,lenient=true,zone=Europe/Amsterdam,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=2,WEEK_OF_YEAR=11,WEEK_OF_MONTH=3,DAY_OF_MONTH=12,DAY_OF_YEAR=71,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=11,SECOND=20,MILLISECOND=322,ZONE_OFFSET=3600000,DST_OFFSET=0]
In particular I don't understand why for example MONTH is the same for both objects (why isn't the current one 3?) while DAY_OF_YEAR is actually higher in the past Calendar than in the current one.
What am I missing here?
Works as intended. Read the docs.
Android java.util.Calendar looks to behave in a similar way to the standard Java version.
Java docs say:
Any field values set in a Calendar will not be interpreted until it
needs to calculate its time value (milliseconds from the Epoch) or
values of the calendar fields. Calling the get, getTimeInMillis,
getTime, add and roll involves such calculation.
Android docs say:
set(f, value) changes field f to value. In addition, it sets an
internal member variable to indicate that field f has been changed.
Although field f is changed immediately, the calendar's milliseconds
is not recomputed until the next call to get(), getTime(), or
getTimeInMillis() is made. Thus, multiple calls to set() do not
trigger multiple, unnecessary computations.

Categories