![]() |
|
SageTV Studio Discussion related to the SageTV Studio application produced by SageTV. Questions, issues, problems, suggestions, etc. relating to the Studio software application should be posted here. |
![]() |
|
Thread Tools | Search this Thread | Display Modes |
#1
|
|||
|
|||
Extenders and how they access static variables
I am having some confusion on extenders and how exactly they access public static's from java. Do they each keep their own jvm copy or do all extenders share?
Let's say for instance I am building a hash Code:
private static HashMap<String,String> valuehash = new HashMap<String,String>(); public static void SetHashValues(){ valuehash.put("1","1"); valuehash.put("2","2"); valuehash.put("2","2"); } public static String getvalue(String key){ return valuehash.get(key);} ( cheers and thanks again, pluckyhd |
#2
|
||||
|
||||
All extenders run in the same jvm and therefore a singleton (public static) variable will be shared by all extender connections.
To get around this, you can use the UIContext as a main key, and then keep each extenders data separated by their ui context. This has its own set of problems since in SageTV 6, calling GetUIContext from within java code returns null. the sagex.apis get around this by testing the thread name (recommendation by jeff). As a rule of thumb in a multi-user environment... you don't want to make anything public static unless you intend for it to be shared by ALL users.
__________________
Batch Metadata Tools (User Guides) - SageTV App (Android) - SageTV Plex Channel - My Other Android Apps - sagex-api wrappers - Google+ - Phoenix Renamer Downloads SageTV V9 | Android MiniClient |
#3
|
|||
|
|||
Quote:
|
#4
|
||||
|
||||
You can have a public static to keep track of extenders....
Code:
public static final Map<String, ExtenderData> extenders = new HashMap<String,ExtenderData>(); Code:
ExtenderData data = extenders.get(uicontext); if (data!=null) return data.getSomeStoredValue();
__________________
Batch Metadata Tools (User Guides) - SageTV App (Android) - SageTV Plex Channel - My Other Android Apps - sagex-api wrappers - Google+ - Phoenix Renamer Downloads SageTV V9 | Android MiniClient |
#5
|
|||
|
|||
Quote:
guessing I have to redo all my property file storing and everything....ahh never ending when you are still learning. |
#6
|
||||
|
||||
Yeah.. I ran into this quite early on with the Phoenix stuff. I basically did something similar there as well.
__________________
Batch Metadata Tools (User Guides) - SageTV App (Android) - SageTV Plex Channel - My Other Android Apps - sagex-api wrappers - Google+ - Phoenix Renamer Downloads SageTV V9 | Android MiniClient |
#7
|
|||
|
|||
I had originally used a syncronizedMap to store local data for each context, which was nice because I could examine the map and see all the clients that were connected. I switched over to InheritableThreadLocal() variables, which seems to be working well, but I loose the ability to examine the other extenders data...
Thanks, Jeff |
#8
|
||||
|
||||
If this is code that's going to be called from an STV, then another fairly straightforward option is to not use statics at all, but instead create a class instance in the ApplicatedStarted hook (which now fires when your STV is loaded) and pass that in to your method calls. That's how object-oriented code is supposed to work: you make an instance of the class and use it for all your method calls.
__________________
-- Greg |
#9
|
|||
|
|||
Quote:
![]() Code:
private static InheritableThreadLocal testmap = new InhertibableThreadLocal(); private static HashMap<String,String> valuehash = new HashMap<String,String>(); public static void SetHashValues(){ valuehash.put("1","1"); valuehash.put("2","2"); valuehash.put("3","3"); testmap.set(valuehash); logger(testmap.get()); } public static String getvalue(String key){ logger(testmap.get()); return ((HashMap<String,String>)valuehash.get()).get(key);} but when I call Getvalue that logger returns null for the testmap.... Any ideas? |
#10
|
|||
|
|||
Quote:
|
#11
|
|||
|
|||
Greg's suggestion is to instantiate an instance of a class in the STV and you pass the variable as the first parm to the method and it will call the method within that instance of the class, such as:
varx = new_ortus_class(); ortus_class_method(varx,otherparms); I tested a sample of what you posted, and it worked as it should... Thanks, Jeff |
#12
|
||||
|
||||
Quote:
ThreadLocals work like like... Create one, initialize it, and then for the lifetime of that thread, you can access that variable and it will contain a value that is specific to that varialbe (unless you share it, as you've done). For each new thread created, the threadlocal has to initialized, if it's not, then the value in the threadlocal will be null, even if it has been initialized by another thread. ie, the purpose of the threadlocal is to allow different threads to access the same "variable" but have different states. In java it's typically used in web applications.
__________________
Batch Metadata Tools (User Guides) - SageTV App (Android) - SageTV Plex Channel - My Other Android Apps - sagex-api wrappers - Google+ - Phoenix Renamer Downloads SageTV V9 | Android MiniClient |
#13
|
|||
|
|||
Quote:
I created the shared hash so I could build the has I wanted to pass to the threadlocal hash. I should move that into the actually servalue call vs defining above the class I can see how that would clash. But in And no that wasn't a copy and paste and a poor code example on my part ![]() I will give it a go plan on reading up on the differences between public static and just public as I don't think I understand those as I thought I did. I did find out if it is just public and not static i can't call it within studio now just want to learn the reason why. Cheers and appreciate once again helping me better myself in this experience. |
#14
|
||||
|
||||
Quote:
I think that threadlocal is probably overcomplicating things for you... this is the general flow... Code:
public static final InheritableThreadLocal data = new IneritableThreadLocal(); public class DataManager() { public static Object getData() { Map extenderData = data.get(); if (extenderData==null) { // no data for this thread, so initialize it. extenderData = createInitialData(); data.put(extenderData); } return extenderData; } } Personally I think it's clearer to either use a public static data store that is keyed of the UIContext, since it clearly indicates that you want some for that extender's ui context. Or, since you are working in the STV, using Greg's approach, where you create the object on application started hook, is probably the best, especially if there is an application terminated event that can be used to clean up the data, if needed.
__________________
Batch Metadata Tools (User Guides) - SageTV App (Android) - SageTV Plex Channel - My Other Android Apps - sagex-api wrappers - Google+ - Phoenix Renamer Downloads SageTV V9 | Android MiniClient |
#15
|
|||
|
|||
Quote:
Quote:
Thanks again |
#16
|
||||
|
||||
Quote:
Quote:
__________________
Batch Metadata Tools (User Guides) - SageTV App (Android) - SageTV Plex Channel - My Other Android Apps - sagex-api wrappers - Google+ - Phoenix Renamer Downloads SageTV V9 | Android MiniClient |
#17
|
|||
|
|||
Quote:
![]() |
#18
|
|||
|
|||
Just wanted to say I have all my statics that I had shared (that I didn't want extenders to share) in their own hash's now using the uicontext as the key and all seems to still be working. Wanted to thanks for the advice.
![]() |
#19
|
||||
|
||||
Quote:
So: Code:
Hook ApplicationStarted If myData == null AddGlobalContext("myData", new_myPackage_myClass()) elsewhere myPackage_myClass_method(myData, args) Hook ApplicationExiting myPackage_myClass_CleanUp(myData) myData = null Of course it's your code and you can do it however you like. But to be honest it boggles me a bit when people find all that complicated stuff with hash tables and such easier to deal with than just using Java objects the way they're meant to be used.
__________________
-- Greg |
#20
|
|||
|
|||
Quote:
![]() I am guessing I would need to create a instance for every class that this is needed is that correct? cheers and thanks for the helpful example |
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
scriptable internet access while maintaining LAN access | korben_dallas | The SageTV Community | 5 | 12-21-2009 06:11 AM |
Limiting Tuner Access for Specific HD-200 Extenders | Greg | SageTV Media Extender | 16 | 12-05-2009 09:04 AM |
Passing variables to a method | fafurd | SageTV Studio | 2 | 12-04-2006 12:23 PM |
Passing Variables between Menus | DwarF | SageTV Studio | 1 | 01-21-2006 05:42 PM |