May be I am missing out on something but I am struggling with very basic problem. what I am trying to do is access some data from my database through a method retrievedata called on onCreate method and the returned list data is assigned to a listarray in it and based on the size of that list data I do some operation.
The problem is that regardless of the data returned from my database ,the arraylist return its size as zero . Here is what I tried to do in onCreate() method
retrievedata();
if (list_entry_model_list.size()==0) //problem here returns true always
notesDatabase.listDaoClass().insert_lists(new List_Entry_Model(""));
the retrievedata() method is given below
public void retrievedata() {
listLiveData = notesDatabase.listDaoClass().load_all_lists();
listLiveData.observe(this, new Observer<List<List_Entry_Model>>() {
#Override
public void onChanged(List<List_Entry_Model> list_entry_models) {
list_entry_model_list = list_entry_models; //here I assigned data to the Listarray that I declared as class variable.
listadapter.submitList(list_entry_model_list);
listadapter.setData(list_entry_model_list);
}
});
Log.d("yummyinside", String.valueOf(list_entry_model_list.size()));
}
If i retrieve size of listarray inside the retrievedata() method,it shows correct size .Listarray is declared as a class variable. So why is it loosing its value.
Thank you. Correct me :)
listLiveData.observe is an asynchronous function, so if (list_entry_model_list.size()==0) will get executed without waiting for result of listLiveData.observe i.e it will executed before anything get assigned to list_entry_model_list.
Related
I want to get frame counts which can be obtain on listener's overridden methods.
But if I use try to assign value to outer variable I get error.
error: local variables referenced from an inner class must be final or effectively final
public void Test5 (String path, Callback cb){
// 1. initialised count variable
int count = 0;
decoder.addRenderListener(
new WebPDecoder.RenderListener(){
#Override
public void onStart(){
// 2. assigning value to count variable
count = decoder.getFrameCount();
Log.d(TAG, count); count is non zero
}
#Override
public void onRender(ByteBuffer byebuffer){}
#Override
public void onEnd(){
decoder.stop();
}
}
);
decoder.start();
// 3. accessing the count variable
Log.d(TAG,"count : "+count); // still count is 0
// this won't run as count is 0
for(int i=0; i < count i++)
bitmaps.add(decoder.getFrameBitmap(i));
// and getFrameBitmap(i) is not useful inside above listener overriden methods. This returns bitmap only outside of listener.
}
I tried SharedPreference and it works but I can't use for reliablity and also app crashes.
I also Tried to use custom class. It does not give error But the value is still zero.
frameData.setFrameCount(frameCount); // setting in onStart()
frameData.getFrameCount(); // getting out of listener
but still zero because it executes before assignment
I wonder how sharedPreference gives non zero value but not this custom class
To get around the must be final you may use a
final AtomicInteger count = new AtomicInteger(0);
and then
count.addAndGet(1);
Anyway, line
Log.d(TAG,"count : "+count.get());
will always return 0, as long it is before decoder.start(). Probably you want to put into a Handler and run periodically ?.
Well a more effective way to achieve to control this would be using a LiveData object to keep track of the active counts.
Define the count variable as a MutableLiveData<Integer> and update this livedata whenever the onStart method called. This may be much faster than writing to and reading from the shared preferences. See the example snippet for an example implementation.
// Define the live data object within a correct scope in your class
MutableLiveData<Integer> mldCount = new MutableLiveData<>(0);
// In the part where you want to control and avoid the index out of bounds observe the count live data
mldCount.observe(<Pass the lifecycle owner here>, count -> {
// Check the new count here
});
public void Test5 (String path){
decoder.addRenderListener(
new WebPDecoder.RenderListener(){
#Override
public void onStart(){
// 2. assigning value to count variable
int count = decoder.getFrameCount();
// If this callback is called from a background thread use:
mldCount.postValue(count);
// If it is called in main thread then use:
mldCount.setValue(count);
Log.d(TAG, count); count is non zero
}
#Override
public void onRender(ByteBuffer byebuffer){}
#Override
public void onEnd(){
decoder.stop();
}
}
);
// This will not show the valid actual values
Log.d(TAG,"count : "+mldCount.getValue()); // still count is 0
decoder.start();
}
I got solution but won't accept is as answer beacuse it is not a solution for specified problem in question.
I invoked decoder.stop() in override OnStart() and then I could access the Bitmaps after stopping. So now no need to get frameCount outside of decoder.
I'm facing a weird behavior in my Java code using List.
The code is very simple, I have a List of Object called AccessRequest which comes from a database and I'm using this first List to create a new one but with a filter to select only a few objects.
Here is the code :
private void updateCommentIfNeeded() {
List<AccessRequest> accessRequestList = getAllRequest();
List<AccessRequest> commentsList = getCommentsListProcessedManually(accessRequestList);
}
public List<AccessRequest> getCommentsListProcessedManually(List<AccessRequest> accessRequests) {
accessRequests.removeIf(ar -> !ar.getComment().equals("To be processed manually"));
if (accessRequests.size() != 0) {
SQLServerConnection sqlServerConnection = new SQLServerConnection(sqlServerUrl);
accessRequests.removeIf(ar -> !sqlServerConnection.emailExists(ar.getEmail()));
}
return accessRequests;
}
I'm supposed to get a second List only containing the objects that has their comments to To be processed manually, which I do. But the weird part is that the first List also takes the value of the second as if I wrote accessRequestList = commentsList but there is no such thing and I'm using local variable.
Ex :
I have 3 objects in my first List, but only one containing the required comment
Both list ends with containing the only objects containing the comment
I'm kind of lost here if anyone has an idea !
Your method getCommentsListProcessedManually modifies the list you're passing. I believe you're operating under the assumption that passing the list as a parameter somehow creates a copy of the list, whereas what is actually happening is that a reference to the list is passed by value.
There are several ways to solve this, but the easiest is to simply create a copy of your input list at the start of your method:
public List<AccessRequest> getCommentsListProcessedManually(List<AccessRequest> input) {
List<AccessRequest> accessRequests = new ArrayList<>(input);
accessRequests.removeIf(ar -> !ar.getComment().equals("To be processed manually"));
if (accessRequests.size() != 0) {
SQLServerConnection sqlServerConnection = new SQLServerConnection(sqlServerUrl);
accessRequests.removeIf(ar -> !sqlServerConnection.emailExists(ar.getEmail()));
}
return accessRequests;
}
You could also use the Stream API for this (using the filter operation), but that's quite a bit trickier in this situation.
You are passing a reference of the list to the method getCommentsListProcessedManually.
So accessRequestList and the one passed as a parameter are the same, hence any operation done to the list is done to the same list.
You can create a copy of the list before passing it as a parameter:
List<AccessRequest> newList = new ArrayList<AccessRequest>(accessRequestList);
I learn Java and wonder if the item in this code line:
useResult(result, item);
Will be overrwritten by the next call coming from the
doItem(item);
Here´s the eaxmple:
public void doSomeStuff() {
// List with 100 items
for (Item item : list) {
doItem(item);
}
}
private void doItem(final Item item) {
someAsyncCall(item, new SomeCallback() {
#Override
public void onSuccess(final Result result) {
useResult(result, item);
}
});
}
the SomeCallback() happens some time in the future and it´s another thread
I mean will the useResult(result, item); item be the same when callback return?
Please advice what happens here?
I mean will the useResult(result, item); item be the same when callback return?
Of course it will, what would the utility of that be otherwise?
What you are doing is creating 100 different SomeCallback classes, that will process a different Item object.
A skeleton for your someAsyncCall may look like this:
public static void someAsyncCall(Item i, Callback callback) {
CompletableFuture.runAsync( () -> { // new thread
Result result = computeResult(i);
callback.onSuccess(result, i);
});
}
The point is: Callback, at the moment of instantiation, doesn't know anything about the Item he will get as parameter. He will only know it, when Callback::onSuccess is executed in the future.
So, will Item i change (be assigned a new object) ?
No, because it is effectively final within someAsyncCall (the object value is not explicitly changed).
You can't even assign i = new Item(), as the compiler will complain about the anonymous function accessing a non-final variable.
You could of course create a new Item and pass it to the callback
Item i2 = new Item();
callback.onSuccess(result, i2);
but then it would become one hell of a nasty library...
Nobody forbids you to do i.setText("bla") though, unless your Result class is immutable (the member fields are final themselves).
EDIT
If your questions is how java handles object in method parameters, then the answer is: yes, they are a just copy of the original instances.
You could try with a simple swap method void swap(Item i1, Item 12); and you'll notice the references are effectively swapped only within function, but as soon as you return the objects will point respectively to their original instances.
But it's a copy that reflects the original instance.
Coming back to your example. Imagine your someAsyncCall waits 10000 ms before executing the callback.
in your for loop, after you call doItem, you also do: item.setText("bla");.
When you print item.getName() within useResult you will get bla. Even though the text was changed after the async function was called.
I really didn't want to resort to asking, however I'm at a dead end. I'm trying to build an array of objects stored within a hashmap into a single array. I'm building a minecraft plugin, and I need to be able to do this in order to reset all players to their natural state. However, for whatever reason, I can't seem to actually parse the Spectator[] array into individual pieces.
The goal is simply to allow more than 1 person to spectate. Here's my code:
public class EagleEye extends JavaPlugin implements Listener{
public HashMap<Spectatee, Spectator[]> spec = new HashMap(Spectatee, Spectator[]);
public HashMap<Spectatee, Spectator[]> orinven = new HashMap<Spectatee, Spectator[]>;
public HashMap<Spectatee, Spectator[]> eeinven = new HashMap<Spectatee, Spectator[]>;
#Override
public void onEnable()
{
//TODO:Who knows.
}
#Override
public void onDisable()
{
//TODO:Spec off any players being spectated and spectating.
Spectator[] frickinhell = spec.get(key));
//Creates a master list of all spectators by uuid
for(Spectator spec : spec.get(Spectator.class))
{
master.add(spec);
}
for(Object spec : master.toArray())
{
//Verify the player is online
if(Bukkit.getPlayer(master)
{
//Verify the player is still spectating
if(tators.get(uuid) == true)
{
//Stop spectating
tators.put(uuid, false);
}
}
}
}
I understand that much of this code is broken. However, my main concern is taking Spectator[] stored within all instances of Spectators[] stored within the hashmap and resetting their values to their defaults. Once I can access each individual instance of each object itself, I can reset their respective values using setters.
Cheers.
In spec.get(Spectator.class), Spectator.class doesn't match the type of your key, which is Spectatee. Therefore, it returns null.
You should pass an instance of Spectatee to spec.get() if you want to have a chance of getting a non-null value.
If you want to collect all the Spectators regardless of their key, you can iterate over the values of the Map :
for (Spectator[] value : spec.values())
for(Spectator spec : value)
{
master.add(spec);
}
I have a firebase repository, and the data is structured like the following:
I am writing java code and i just want to get the value of "listname". HEre is what i do:
Firebase f = new Firebase("https://marketlist.firebaseio.com/sharedlists/list1/listname");
and then, when i look at member functions of my firebase object f, isee that there is a getName() function that returns listname, which is "list1", but there is no getValue() function here. Also, i tried
Query q = f.startAt("list1").endAt("list1");
but again, i cannot get the value. Can anybody help me with this?
Thanks
Firebase's logic is that data may change over time. So instead of exposing a value on the Firebase reference, you need to listen for changes like this:
f.on('value', function(snapshot) {
var val = snapshot.val();
});
Inside this callback function, val will now have list1 as its value.
If/when the value of listname changes, the callback will be called again and val will have the new value.
Update
I had missed that you use Java, so the above example is for JavaScript.
In Java the mechanism is very similar, but syntactically different:
f.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
String val = (String) snapshot.getValue());
}
#Override public void onCancelled() { }
});
So you attach a listener through addValueEventListener. Then the onDataChange method is invoked immediately for the initial value and whenever the referenced value changes.