delight-im / Android-DDP

[UNMAINTAINED] Meteor's Distributed Data Protocol (DDP) for clients on Android
Apache License 2.0
274 stars 54 forks source link

How can change instance in MeteorSingleton? #70

Closed thuanmaster closed 8 years ago

thuanmaster commented 8 years ago

I need use MeteorCallback in many activity so i use MeteorSingleton but i can't replace instance by command MeteorSingleton.createInstance(this, "ws://example.meteor.com/websocket") to change server address. Any methods to do this?

ocram commented 8 years ago

Thanks for your question!

The command that you mentioned is only used the very first time. Afterwards, in order to get the reference every time and replace your normal instance, you have to use a different command. This is how it should work:

In the very beginning, when your application or Activity starts, create the instance:

Meteor meteor = MeteorSingleton.createInstance(this, "ws://example.meteor.com/websocket");
meteor.addCallback(this);
meteor.connect();

Afterwards, whenever you need to reference the instance or call a method on it, use this:

// example: Meteor meteor = MeteorSingleton.getInstance();

MeteorSingleton.getInstance().insert(arg1, arg2);
// instead of: myMeteorInstance.insert(arg1, arg2);

MeteorSingleton.getInstance().update(arg1, arg2);
MeteorSingleton.getInstance().remove(arg1, arg2);
MeteorSingleton.getInstance().subscribe(arg1, arg2);
MeteorSingleton.getInstance().call(arg1, arg2);
// ...

Changing the server address, while being connected to another server already, is not possible with the singleton. It's impossible, by definition.

If you really need this, you have to access the instances in the normal way, without the singleton.

Does this help?

thuanmaster commented 8 years ago

Yep. I have dropdown select server address. May I need restart app to change server address. Thank you very much!

ocram commented 8 years ago

Ah, that makes sense. Now the use case is clear.

There might be an easy solution: Just copy the class MeteorSingleton from this library to your own source package. Maybe even rename it to something else (e.g. MyMeteor) in order to avoid confusion.

Then add some new method similar to the following one:

public synchronized static void destroyInstance() {
    if (mInstance == null) {
        throw new IllegalStateException("Please call `createInstance(...)` first");
    }

    mInstance.disconnect();
    mInstance.removeCallbacks();
    mInstance = null;
}

If you did this, you would be able to replace all occurrences of MeteorSingleton in your code with MyMeteor. And whenever you want to call MyMeteor.createInstance(...) a second time, just remember to call MyMeteor.destroyInstance() before.

Does this work for you?

thuanmaster commented 8 years ago

Ta-da. It works. I think you should add this funtion on next package's update and an
instruction on Readme. Thanks very much!

ocram commented 8 years ago

@thuanmaster Glad to hear that it works for you :) We'll add this method to the MeteorSingleton class in the next release, as you suggested. We should probably leave this issue open until then as a reminder. Thank you!

ocram commented 8 years ago

The method has been implemented in https://github.com/delight-im/Android-DDP/commit/e5078272145c687286536ed2b51c017fa4ba94d5 and is included in the latest release now :)

Thanks again!

thuanmaster commented 8 years ago

@mwaclawek You should take a document about it!:)

ocram commented 8 years ago

@thuanmaster I'm not sure if it should be in the documentation. It could be rather confusing to developers. Usually, the method is not required at all, since you can just call disconnect on the instance. Only in some special use cases, such as yours where the user can select from different servers, do you need this feature. I think it's good that the feature exists now, but most developers probably shouldn't be using it :)

prashanthmotifworks commented 8 years ago

Whenever meteor android app goes to background for 3-4 hrs, and returns to foreground, it is throwing an error "First create the instance" and app is crashing. Note: During login activity, in signin we are doing CreateInstance() initially, why getInstance() is set to null whenever app is going to background for 3-4hrs. What would be the possible solution for this case.

ocram commented 8 years ago

@prashanthmotifworks It seems your application has been killed by the operating system, e.g. because it has been in the background for too long or because memory was low on the device. In that case, I don't think there's anything you can do about it. You have to prevent it from being killed. In case you have further questions, please open separate issues for those. Thank you!