I'm using a complex closed api. I want to create a super simple way to use it.
Basicaly, it has the following behaviour:
boolean everythingReady = false;
API.start(new Callback() {
public void onReady()
{
API.invite(new Callback2() {
public void onReady()
{
everythingReady = true;
}
});
}
});
while (!everythingReady); // Wait
API.send("hello);
API.send("What's up");
This is a chat API and the above code is "pseudo" java.
What I want to do now is:
API.start();
API.invite();
API.send("Hello);
API.send("What's up");
these methods would wait until each above has been correctly loaded (onReady called) to run. (eg: if (!apiStarted) addToQueue else do invite)
Is there a way to do that in java (as I can't edit at all the API sources).
Thanks
How about:
API.start(new Callback() {
public void onReady()
{
API.invite(new Callback() {
public void onReady()
{
API.send("hello");
API.send("What's up");
}
});
}
});
This way the send methods will be called only after invite is ready.
Related
I'm fairly new to RxJava and I have a basic understanding as to how to wrap a callback into an Observable but what I'm having difficulty with is doing so when the callback/listener is pre-instanced. Every example that I have found only shows instancing the callback directly into the Observable being created.
Some example code of what I'm talking about. I'm working with an Api that's works like this:
public class Api {
private ApiCallback callback;
void initialize(ApiCallback callback){
this.callback = callback;
}
void doAction1(){
this.callback.onAction1Complete();
}
}
interface ApiCallback {
void onInitialized();
void onAction1Complete();
}
With the real api I am working with I have no control over how it works so I must work with it in this state. In terms of trying to work with this Api using observables here is the struggle I am having. I have a member variable that holds the Api object:
private Api mApi = new Api();
Now in order to initialize this I have one of two options it seems.
Option 1:
Completable startApi() {
return Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(final CompletableEmitter emitter) throws Exception {
mApi.initialize(new ApiCallback() {
#Override
public void onInitialized() {
emitter.onComplete();
}
#Override
public void onAction1Complete() {
}
});
}
});
}
Option 2:
private ApiCallback premadeCallback = new ApiCallback() {
#Override
public void onInitialized() {
}
#Override
public void onAction1Complete() {
}
};
Completable startApi() {
return Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(final CompletableEmitter emitter) throws Exception {
mApi.initialize(premadeCallback);
}
});
}
Now the issue I have is that Option 2 makes more sense to me when I need to know when the other methods in the callback are called from Api calls. With my understanding of RxJava however I don't understand how I can reach these method calls with an Api that works like this.
For example:
Completable doAction1() {
return Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(final CompletableEmitter emitter) throws Exception {
// Api is already initialized with callback
// How do I reach the callback from here?
}
});
}
The only what that I can currently think of as to how to achieve this would be to create a member variable as an emitter (or a dictionary of emitters) and then call its appropriate method in the api callback when needed. My concerns with this are A. I'm unsure if RxJava can work this way B. This sounds like a terrible idea.
I want to implement something like gate mechanism.
I need one PublishSubject and a couple of subscribers. When PublishSubject send data via onNext only one subscriber will receive it.
For example:
I have 3 equals fragments inside tabs. They have subscription to global published called onLoginPublisher.
When onResume or onPause called gate becomes open or closed.
When onLogin called and no gates are opened because of no one of these fragments on screen, onNext will wait for fragment's onResume
Look at the pic:
You can use filter with the gate's state. For example, you can wrap all the logic into a class:
public final class GatedSubject<T> {
final PublishSubject<T> subject = PublishSubject.create();
final AtomicReferenceArray<Boolean> gates;
public GatedSubject(int numGates) {
gates = new AtomicReferenceArray<>(numGates);
}
public boolean getGateStatus(int gateIndex) {
return gates.get(gateIndex) != null;
}
public void setGateStatus(int gateIndex, boolean status) {
gates.set(gateIndex, status ? Boolean.TRUE : null);
}
public void Observable<T> getGate(int gateIndex) {
return subject.filter(v -> getGateStatus(gateIndex));
}
public void onNext(T item) {
subject.onNext(item);
}
public void onError(Throwable error) {
subject.onError(error);
}
public void onComplete() {
subject.onComplete();
}
}
I need a shorter & cleaner solution for Example 1. So multiple async calls need to be finished before a certain Activity/Fragment can start. Example 1 is very messy and ugly with member bools, but works.
I was considering using the Google Tasks API. But for that I need to add a google-services.json and connect to either "Google Sign-in", "Analytics" or "Cloud messaging", which I don't need I think. There must be a better way or is this the correct way to go?
Example 1:
boolean mIsFirstDone = false;
boolean mIsSecondDone = false;
boolean mAlreadyDone = false;
private void prepareSomeData() {
dataManager.requestSomeContent(new ApiCallback() {
#Override
public void onSuccess(final Object object) {
mIsFirstDone = true;
if(mIsFirstDone && mIsSecondDone && !mAlreadyDone) {
mAlreadyDone = true;
doSomething();
}
}
});
}
private void prepareSomeSettings() {
dataManager.requestSomeSettings(new ApiCallback() {
#Override
public void onSuccess(final Object object) {
mIsSecondDone = true;
if(mIsFirstDone && mIsSecondDone && !mAlreadyDone) {
mAlreadyDone = true;
doSomething();
}
}
});
}
With Tasks API:
Tasks.whenAll(SomeDataTask, SomeSettingsTask).addOnSuccessListener(executor, new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void v) {
doSomething();
}
}).addOnFailureListener(executor, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
RxJava, as pointed out, is probably a better solution to this. The reason why is because you can chain multiple api requests, database requests into a concrete block of code that looks elegant and clean. As an example, see below of what I'm trying to say:
Subscription subscription = apiService.getUser(someId)
.flatMap(user -> apiService.getFavourites(user.getFavouritesTag())
.subscribe(favourites -> view.updateFavouritesList(favourites),
throwable -> Log.e(TAG, throwable.printStackTrace());
Have you considered learning about RxJava and reformatting all your projects to RxJava along with retrofit for API?
start with something like this:
https://medium.com/yammer-engineering/chaining-multiple-sources-with-rxjava-20eb6850e5d9
https://adityaladwa.wordpress.com/2016/05/11/dagger-2-and-mvp-architecture/
I want to support both Synchronous and Asynchronous call using RESTEasy-JAXRS. And my asynchronous call should be based on callback, where Async request will have callbackURI, request gets processed asynchronously and upon completion makes a call to callbackURI with operation status/result. Can someone point me out to correct place? I see lot about polling model, but not callback with RESTEasy.
I am new to Asynchronous stuff...
Thanks in advance!
Thanks for your response rmlan.Yes but we have support in JAX-RS to handle asynchronous using #Suspended & AsyncResponse. I did that with following code, but i am unable to find the way to make callback to Client who called the API upon completion of task with this request.
#GET
#Path("/async")
public String checkAsync(#Suspended final AsyncResponse response) {
response.setTimeoutHandler(new TimeoutHandler() {
#Override
public void handleTimeout(AsyncResponse asyncResponse) {
response.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)
.entity("Operation time out.").build());
}
});
response.setTimeout(2, TimeUnit.SECONDS);
new Thread(new Runnable() {
#Override
public void run() {
String result = veryExpensiveOperation();
response.resume(result);
}
private String veryExpensiveOperation() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.debug("Task is processed fully");
return "Successful";
}
}).start();
return "nothing";
}
Every method in class has one return ( or maybe void ) . but sometimes you need some callbacks from your method . this is the solution .
public abstract class MyClass {
public abstract void myCallbackMethod();
public void myMethod(){
for (int i = 0; i < 5; i++) {
// do somthing
myCallbackMethod();// it will implements in future.
}
}
}
when you make an object from MyClass , you must implement myCallbackMethod abstract method . like this
public class NewMain {
public static void main(String[] args) {
MyClass myClass=new MyClass() {
#Override
public void myCallbackMethod() {
System.err.println("this is call back");
}
};
myClass.myMethod();
}
}
and the result is
this is call back
this is call back
this is call back
this is call back
this is call back
it means you can get five call backs from void method in your class.
it is a good way when you do not have any idea for the body content of myCallBackMethod
the real example is download a file from server in your app .
you can call myCallBackMethod when bytes received and progress your progressbar
I have in my project Retrofit library and RxAndroid.
For example I've called some method from my api
public void loadSomething() {
getApi().getSomething()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Something>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(Something s) {
}
});
}
How should I track progress of this observable for example to prevent user to start it second time?
Should add my custom flags something like before start set inProgress = true; and in all callback methods set inProgress = false;?
Can I do it with RxAndroid functionality? Or is it guarantee that one call to api will not be started few times in parallel?
You can use the Do operator.
You can set the inPogress = true in doOnSubscribe() and inProgress = false in doOnComplete().
Also calling subscribe returns a Subscription. You can use it to check if the call has finished using isUnsubscribed().