How to get RealmList inside Thread? - java

Hi in my app i need to get RealmList from RealmObject(PlayList.class). The problem is that i trying to do this on other thread.(some loop engine with tick() method) So my solution it was to get the RealmList from the RealmObject and convert it to ArrayList and than do with it what i want in any thread.
This is the crash i get
java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
this is my RealmObject class
public class PlaylistModel extends RealmObject implements Serializable {
public int id;
public String path;
public String fileName;
public String duration;
public RealmList<Note> notes;
this is my Note class
public class MidiModel extends RealmObject implements Serializable {
private String tag;
private long spaceTime = -1;
and this is how i get the data
public RealmResults<PlaylistModel> getPlaylist(){
realm.beginTransaction();
RealmResults<PlaylistModel> realmResults = realm.where(PlaylistModel.class).findAll();
realm.commitTransaction();
return realmResults;
}
and this is how i trying to read the RealmList in a diffrent thread
public void tick(){
Note model = noteList.get(index);
index++;
}
How can i make it works?
Do i need to convert RealmList to ArrayList Before manipulate?
Please help :)

Managed RealmObjects cannot be passed between threads, so you need to re-query it on the background thread by its primary key, from a Realm instance that was opened for that thread.
Executor executor = Executors.newSingleThreadedPool(); // like new Thread().start();
public void doSomething(final String pkValue) {
executor.execute(new Runnable() {
#Override
public void run() {
try(Realm realm = Realm.getDefaultInstance()) { // beginning of thread
doThingsWithMyObject(realm, pkValue);
} // end of thread
}
}
}
public void doThingsWithMyObject(Realm realm, String pkValue) { // <-- pass Realm instance
MyObject myObject = realm.where(MyObject.class).equalTo("id", pkValue).findFirst(); // <-- requery
RealmList<Note> notes = myObject.getNotes();
// ... do things with notes
}

Related

Return value from lambda function in background thread, throw NullPointerException

In my use case, I want to return a user object from the lambda function as in the code below. Before posting my question, I try many similar questions like this and this but no theme solves my problem, here is my code:
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class AppDatabase {
private static final int NUMBER_OF_THREADS = 4;
public static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
}
public class MyClass {
private User mUser;
public User findUser(){
AppDatabase.databaseWriteExecutor.execute(() -> {
mUser = work();
});
return mUser;
}
public User work(){
//simulate get user from database
User user = new User();
user.setName("Toto");
return user;
}
}
public class Main {
public static void main(String[] args) {
MyClass myClass = new MyClass();
User user;
user = myClass.findUser();
System.out.println(user.getName()); //this line: Exception in thread "main" java.lang.NullPointerException
}
}
When I run this code, I get "Exception in thread" main "java.lang.NullPointerException". My question is how do I get the User object built by the work () function, but this function should run in a background thread like in code.
findUser returns right away, and it returns null because mUser hasn't been set yet. You need to either wait for it to be set, or return a Future<User> that the caller can wait on.

How do I implement an Observer to get data from a listener?

I am using the MaterialDrawer library to create a simple drawer for my app, some of the instances of classes in the library need a string passed into them when called. An example is the IProfile class:
IProfile profile = new ProfileDrawerItem().withName("John Doe");
where the withName() method takes in a string.
I have created a class MyObservable.java (extends Observable) class that I intend using to get data to be used in my MainActivity which has the MaterialDrawer library implemented. In this class, I have a method implementData() which has my listener for what I need from my firebase database.
This is what it looks like:
public class MyObservable extends Observable {
// Attach our firebase reference...
Firebase userRef = new Firebase("https://myApp.firebaseio.com/users");
AuthData authData;
public String username = "";
public String email = "";
public void changeUsername(String username) {
this.username = username;
setChanged();
notifyObservers(username);
}
public void implementData(){
// Get the authentication data of our user from the reference.
authData = userRef.getAuth();
// This is the listener I have to get the data from.
userRef.child(authData.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
UserSchema user = snapshot.getValue(UserSchema.class);
// This guy needs to be used in the MainActivity appDrawer() method
String userName = user.getName();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
}
class MyObserver implements Observer {
public void update(Observable observable, Object data) {
// For now I just print it out to System.out
System.out.println("Username:" + data);
}
}
Then I notify my observers of the username change with the changeUsername() method:
public void changeUsername(String username) {
this.username = username;
setChanged();
notifyObservers(username);
}
In the MyObservable class, I have a MyObserver class that implements Observer with the update() method called whenever an observer has been updated. In the update() method for now, I just print out the username of the user to ensure something is actually happening.
This is where I need the data from the observer (In the MainActivity):
public class MainActivity extends AppCompatActivity {
...
public void appDrawer(){
IProfile profile = new ProfileDrawerItem()
// I need the user's data here
.withName("Test")
.withEmail("test#test.com")
.withIcon(R.drawable.avatar2);
}
...
}
I have spent hours trying to 'react' to the events happening in the listener by trying to retrieve data to be used in my MainActivity but I'm not sure I'm using the Observable/Observer pattern properly, also since this is an Asynchronous event by Firebase to get data, using an Observer has been the best way to do this.
The appDrawer() method is called in my Activity's onCreate() .
How do I retrieve data from the Listener with an Observer, so I can use it elsewhere?
I can't tell by your design what's really going on. Naming a class Listener then making it Observable seems counter-intuitive. A listener listens or observes. Nonetheless, it sounds like you have another class in the Listener that's an Observer so I'm a little lost but you seem unsure if you've implemented the pattern correctly. That I can clear up with an example.
public class MyObserver implements Observer {
#Override
public void update(Observable o, Object arg) {
System.out.println(arg + " " + ((MyObservable)o).name);
}
}
public class MyObservable extends Observable {
public String name = "Observable";
public void changeMe(String word) {
setChanged();
notifyObservers(word);
}
}
public class Test {
public static void main(String[] args) {
MyObservable myObservable = new MyObservable();
myObservable.addObserver(new MyObserver());
myObservable.changeMe("Hello");
}
}
The update method gives you the object you're observing as well as the arguments (the data you want shared with the observer) you passed into notifyObservers(). If you've done it like this then you should get the behavior you expect.
As you can see data can be sent to the observers that is outside or inside the observable. When you run it the output is...
Hello Observable

passing values from one jInternalFrame to another jInternalFrame

can anyone help how to pass value from one jInternalFrame1 to another jInternalFrame2?I can't make object of the jInternalFrame1 in jInternalFrame2.I have seen one solution by making constructor and oject the Jframe.But how?
"can you provide code for this data Model?"
The second internal frame accepts a DataModel object. The two will remain the same object when between the frames.
Note if you need something more complex (like back and forth interaction between the frames), you should look into some tutorial on Model View Controller architecture, where you will need to use PropertyChaneListeners and such
public class DataModel {
private String data;
public DataModel() {
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
public class MyInternalFrame1 extends JInternalFrame {
private DataModel dataModel = new DataModel();
public DataModel getDataModel() {
return dataModel;
}
}
public class MyInternalFrame2 extends JInternalFrame {
private DataModel dataModel;
public MyInternaFrame1() {}
public MyIntenalFrame2(DataModel datModel) {
this.dataModel = dataModel;
}
public void setDataModel(DataModel dataModel) {
this.dataModel = dataModel;
}
}
In the Main GUI program, you can do something like this
public class GUI extends JFrame {
MyInternalFrame1 iFrame1 = new MyInternalFrame1();
....
// somewhere else in code
DataModel dataModel = iFrame1.getDataModel();
dataModel.setData("Hello");
new MyInternalFrame2(dataModel);
}

How to collect a number of asynchronous callbacks?

Are there any techiques to collect a number of gwt-rpc service callback results?
I have a dialog window used to create new or edit existing object. These objects have a number of references to other object. So when user creating or editing an object he may pick one in the ListBox.
public class School {
private String name;
private String address;
}
public class Car {
private String model;
private String type;
}
public class Person {
private String firstName;
private String lastName;
private School school;
private Car firstCar;
}
When the dialog window appears on the screen it should request all available values for all referencing fields. These values are requested with AsyncCallback's via gwt-rpc, so I can handle it one-by-one.
service.getAllSchools(new AsyncCallback<List<School>>() {
#Override
public void onSuccess(List<School> result) {
fillSchoolListBox(result);
}
#Override
public void onFailure(Throwable caught) {
Window.alert("ups...");
}
});
...
service.getAllSchools(new AsyncCallback<List<Car>>() {
#Override
public void onSuccess(List<Car> result) {
fillCarListBox(result);
}
#Override
public void onFailure(Throwable caught) {
Window.alert("ups...");
}
});
How to get all result in one place?
Thanks.
The best solution would be Command Patter as igorbel said, but if you are beginner you can design for example Bean Container that only contains beans that must be transported at one request.
For example:
public class BeanContainer{
private ArrayList<School> schools = new ArrayList<School>();
private ArrayList<Car> cars = new ArrayList<Car>;
private ArrayList<Person> people = ArrayList<Person>();
public void addSchool(School school){
this.schools.add(school);
}
public void addSchoolCollection(ArrayList<School> schools){
this.schools.add(schools);
}
public ArrayList<School> getSchoolCollection(){
return schools;
}
...
}
Why don't you create a new service method that returns all the data as a result?
The implementation of such a method could simply call all of the other methods. You will have to encapsulate all the required data and return it as a single result. One example how you could handle this:
In the service implementation:
#Override
public Data getAllData(){
List<Cars> cars = this.getAllCars();
List<School> schools = this.getAllSchools();
return new Data(cars, schools);
}
And you can then use the method like this:
service.getAllData(new AsyncCallback<Data data>() {
#Override
public void onSuccess(Data data) {
fillCarListBox(data.getCars());
fillSchoolListBox(data.getSchools());
}
#Override
public void onFailure(Throwable caught) {
Window.alert("Pogreska...");
}
});
With this kind of approach you minimize the number of service calls on your client side. This not only creates a more readable code, but also usually speeds up the client side of your app. You should always try to minimize the number of service calls, ideally to a single one.
Concerning the more general question of collecting a number of asynchronous callbacks, a good approach is to use the Command Pattern. Gwt Remote Action is a library that provides an implementation of the mentioned pattern for doing RPC calls:
http://code.google.com/p/gwt-remote-action/

How to use constructor in Realm v0.87.1 on Android

I want use Realm version 0.87.1 for Database in android, and i create provider class to save values but when use this class constructor in main class (activity) show me this error, please see error from this image : Error image Link
Task_Provider class :
public class Task_Provider extends RealmObject {
public Task_Provider() {
}
public String getAddTask() {
return addTask;
}
public void setAddTask(String addTask) {
this.addTask = addTask;
}
public long getAdded_date() {
return added_date;
}
public void setAdded_date(long added_date) {
this.added_date = added_date;
}
public long getWhen_date() {
return when_date;
}
public void setWhen_date(long when_date) {
this.when_date = when_date;
}
public boolean isComplete() {
return complete;
}
public void setComplete(boolean complete) {
this.complete = complete;
}
public Task_Provider(String addTask, long added_date, long when_date, boolean complete) {
this.addTask = addTask;
this.added_date = added_date;
this.when_date = when_date;
this.complete = complete;
}
private String addTask;
#PrimaryKey
private long added_date;
private long when_date;
private boolean complete;
}
Main Activity (Button setOnClickListener) :
String addTask = dialog_edit_task.getText().toString();
long now = System.currentTimeMillis();
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(getActivity()).build();
Realm.setDefaultConfiguration(realmConfiguration);
Realm realm = Realm.getDefaultInstance();
Task_Provider task_provider = new Task_Provider(addTask, now, 0, false);
realm.beginTransaction();
realm.copyToRealm(task_provider);
realm.commitTransaction();
realm.close();
How can i fix this problem? tnx all <3
Did you try cleaning your project? I got with that issue, but disappeared as i cleaned it. You have an empty constructor already :)
Otherwise, you can try to create the object realm defaults.
Because copyToRealm... your Task_Provider object is already a realm object, since you are extending it on the class declaration.
Task_Provider task = realm.createObject(Task_Provider.class);
task.setAddTask("");
...
Hope it helps!

Categories