I would need an Observable, for example to provide a system clock, which does not need to pass anything in onNext(). I couldn't find a signature that would allow me to do that.
Sure, I could use any object and then pass null, but that doesn't make much sense. So my question is if there is a better way to do that.
Observable.create(new Observable.OnSubscribe<Anyobject>() { // use any object in the signature
#Override public void call(Subscriber<? super Anyobject> subscriber) {
subscriber.onNext(null); // then pass null
subscriber.onCompleted();
}
})
You don't need to call onNext if your Observable doesn't emit anything.
You could use Void in your signature and do something like
Observable<Void> o = Observable.create(new Observable.OnSubscribe<Void>() {
#Override
public void call(Subscriber<? super Void> subscriber) {
// Do the work and call onCompleted when you done,
// no need to call onNext if you have nothing to emit
subscriber.onCompleted();
}
});
o.subscribe(new OnCompletedObserver<Void>() {
#Override
public void onCompleted() {
System.out.println("onCompleted");
}
#Override
public void onError(Throwable e) {
System.out.println("onError " + e.getMessage());
}
});
You can define an OnCompletedObserver to simplify your Observer callback so that you don't have to override the onNext since you don't need it.
public abstract class OnCompletedObserver<T> implements Observer<T> {
#Override
public void onNext(T o) {
}
}
If I've understood what you're asking then this should do the trick.
If you need something to be passed to onNext() before onCompleted() is called:
Observable.<Void>just(null)
If you only need onCompleted() to be called:
Observable.empty()
RxJava 2 Wiki:
RxJava 2.x no longer accepts null values and the following will yield
NullPointerException immediately or as a signal to downstream.
...
This means that Observable<Void> can no longer emit any values but
only terminate normally or with an exception. API designers may
instead choose to define Observable<Object> with no guarantee on what
Object will be (which should be irrelevant anyway)
It means that you can't use Void and do Observable.just(null).
Use Object or some other simple type instead:
Observable.just(new Object());
Starting with RxJava 2, the propper way to do this is to use a Completable
From the docs:
Represents a deferred computation without any value but only
indication for completion or exception. The class follows a similar
event pattern as Reactive-Streams: onSubscribe (onError|onComplete)?
One of the light solutions is to use Observable<Boolean>
And then onNext(Boolean.TRUE) which you then just ignore.
But probably you shouldn't use Observable in that case.
Consider using Completable instead
I don't know this will helps you or not.
The code written in RxSwift.
// Create an observable and emit somethings
let myObservable = Observable<Void>.create{ observer in
observer.on(.next(Void()))
return Disposables.create()
}
// Observer subscribe changes
myObservable.subscribe(onNext: {
_ in
print("Hello")
}).disposed(by: disposeBag)
Or use the Variable object
// Create a Variable object that contanins nothing
var myValueWatcher:Variable<Void> = Variable<Void>(Void())
// Observer subscribe changes
myValueWatcher.asObservable().skip(1).subscribe(onNext: {
_ in
print("Changes!")
}).disposed(by: disposeBag)
// The emit code
myValueWatcher.value = Void()
Related
I'm using RxJava for my project and I am puzzled a bit with this piece of code:
#Override
public Observable<Hexagon<T>> getHexagons() {
return Observable.create(new OnSubscribe<Hexagon<T>>() {
#Override
public void call(final Subscriber<? super Hexagon<T>> subscriber) {
hexagonDataStorage.getCoordinates().subscribe(new Subscriber<CubeCoordinate>() {
#Override
public void onCompleted() {
subscriber.onCompleted();
}
#Override
public void onError(final Throwable throwable) {
System.err.println(String.format("Cannot get Hexagons: <%s>", throwable.getMessage()));
}
#Override
public void onNext(final CubeCoordinate cubeCoordinate) {
subscriber.onNext(new HexagonImpl<>(gridData, cubeCoordinate, hexagonDataStorage));
}
});
}
});
}
What I'm basically trying to do here is to
get all the CubeCoordinate objects by calling the getCoordinates method which in fact returns an Observable
transform the CubeCoordinate objects into Hexagon objects and return the result as a new Observable.
This example is working but it is really tiring on my eyes and also smells. Is there a better way to achieve the same result?
Also is there an implementation of Subscriber which only makes me override onCompleted and onNext? onError is not needed in my case. I checked the source code but there is a gazillion of implementations and I can't differentiate based on my criteria.
To answer your first question - the operator you are looking for is map:
public Observable<Hexagon<T>> getHexagons() {
return hexagonDataStorage.getCoordinates()
.map(cubeCoordinate -> new HexagonImpl<>(gridData, cubeCoordinate, hexagonDataStorage))
}
It does exactly what you want - it transforms each item by applying a function.
To answer your second question - I highly suggest you always override onError, otherwise, if the RxJava stream encounters an exception, it will throw OnErrorNotImplementedException. You can make an abstract class that extends Subscriber and implement onError there and leave the other two methods abstract.
Guava's ListenableFuture library provides a mechanism for adding callbacks to future tasks. This is done as follows:
ListenableFuture<MyClass> future = myExecutor.submit(myCallable);
Futures.addCallback(future, new FutureCallback<MyClass>() {
#Override
public void onSuccess(#Nullable MyClass myClass) {
doSomething(myClass);
}
#Override
public void onFailure(Throwable t) {
printWarning(t);
}}, myCallbackExecutor);
}
You can wait for a ListenableFuture to complete by calling its get function. For instance:
MyClass myClass = future.get();
My question is, are all callbacks for a certain future guaranteed to run before the get terminates. I.e. if there is a future with many callbacks on many callback executors registered, will all the callbacks complete before get returns?
Edit
My use case is, I pass a builder around to many classes. Each class populates one field of the builder. I want all fields to be populated asynchronously because each field requires an external query to generate the data for the field. I want the user who calls my asyncPopulateBuilder to receive a Future on which she can call get and be assured that all the fields have been populated. The way I thought to do it is as follows:
final Builder b;
ListenableFuture<MyClass> future = myExecutor.submit(myCallable);
Futures.addCallback(future, new FutureCallback<MyClass>() {
#Override
public void onSuccess(#Nullable MyClass myClass) {
b.setMyClass(myClass);
}
#Override
public void onFailure(Throwable t) {
printWarning(t);
}}, myCallbackExecutor);
}
// Do the same thing for all other fields.
What is the recommended way to block until all fields are populated in such a case?
Callbacks are not guaranteed to run before get returns. More on that below.
As for how to address this use case, I would suggest turning the query for each field's data into a separate Future, combining them with allAsList+transform, and taking action on that. (We may someday provide a shortcut for the "combine" step.)
ListenableFuture<MyClass> future = myExecutor.submit(myCallable);
final ListenableFuture<Foo> foo =
Futures.transform(
future,
new Function<MyClass, Foo>() { ... },
myCallbackExecutor);
final ListenableFuture<Bar> bar = ...;
final ListenableFuture<Baz> baz = ...;
ListenableFuture<?> allAvailable = Futures.allAsList(foo, bar, baz);
ListenableFuture<?> allSet = Futures.transform(
allAvailable,
new Function<Object, Object>() {
#Override
public Object apply(Object ignored) {
// Use getUnchecked, since we know they already succeeded:
builder.setFoo(Futures.getUnchecked(foo));
builder.setFoo(Futures.getUnchecked(bar));
builder.setFoo(Futures.getUnchecked(baz));
return null;
}
}
};
Now the user can call allSet.get() to await population.
(Or maybe you want for allSet to be a Future<Builder> so that the user is handed a reference to the builder. Or maybe you don't need a full-on Future at all, only a CountDownLatch, in which you could use addCallback instead of transform and count down the latch at the end of the callback.)
This approach may also simplify error handling.
RE: "Do callbacks run before get?"
First, I am pretty sure that we don't guarantee this anywhere in the spec, so thanks for asking rather than just going for it :) If you do end up wanting to rely on some behavior of the current implementation, please file an issue so that we can add documentation and tests.
Second, if I take your question very literally, what you're asking for isn't possible: If get() waits for all listeners to complete, then any listener that calls get() will hang!
A slightly more lenient version of your question is "Will all the listeners at least start before get() returns?" This turns out to be impossible, too: Suppose that I attach two listeners to the same Future to be run with directExecutor(). Both listeners simply call get() and return. One of the listeners has to run first. When it calls get(), it will hang, since the second listener hasn't started yet -- nor can it until the first listener is done. (More generally, it can be dangerous to rely on any given Executor to execute a task promptly.)
A still more lenient version is "Will the Future at least call submit() for each of the listeners before get() returns?" But this ends up with a problem in the same scenario as I just described: Calling submit(firstListener) on a directExecutor() runs the task and calls get(), which can't complete until the second listener is started, which can't happen until the first listener completes.
If anything, it's starting to sound much more likely that get() will return before any listeners execute. But thanks to the unpredictability of thread scheduling, we can't rely on that, either. (And again: It's not documented, so please don't rely on it unless you ask for it to be documented!)
final Builder b;
CountDownLatch latch = new CountDownLatch(1);
ListenableFuture<MyClass> future = myExecutor.submit(myCallable);
Futures.addCallback(future, new FutureCallback<MyClass>() {
#Override
public void onSuccess(#Nullable MyClass myClass) {
b.setMyClass(myClass);
latch.countDown();
}
#Override
public void onFailure(Throwable t) {
printWarning(t);
latch.countDown();
}, myCallbackExecutor);
try {
latch.await();
} catch (InterruptedException e) {
LOG.error("something InterruptedException", e);
} finally {
myCallbackExecutor.shutdown();
}
Edit
code is inspired by #Chris Povirk
(Or maybe you want for allSet to be a Future so that the user is handed a reference to the builder. Or maybe you don't need a full-on Future at all, only a CountDownLatch, in which you could use addCallback instead of transform and count down the latch at the end of the callback.)
This approach may also simplify error handling.
I'm new to android and very used to web developing. in javascript when you want to perform an asynchronous task you pass a function as an argument (a callback):
http.get('www.example.com' , function(response){
//some code to handle response
});
I was wondering if we can do the same with android's AsyncTask , pass a function reference to the onPostExecute() method , and it will run it.
any suggestions ?
Yes the concept of callbacks also very much exists in Java. In Java you define a callback like this:
public interface TaskListener {
public void onFinished(String result);
}
One would often nest these kind of listener definitions inside the AsyncTask like this:
public class ExampleTask extends AsyncTask<Void, Void, String> {
public interface TaskListener {
public void onFinished(String result);
}
...
}
And a complete implementation of the callback in the AsyncTask would look like this:
public class ExampleTask extends AsyncTask<Void, Void, String> {
public interface TaskListener {
public void onFinished(String result);
}
// This is the reference to the associated listener
private final TaskListener taskListener;
public ExampleTask(TaskListener listener) {
// The listener reference is passed in through the constructor
this.taskListener = listener;
}
#Override
protected String doInBackground(Void... params) {
return doSomething();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// In onPostExecute we check if the listener is valid
if(this.taskListener != null) {
// And if it is we call the callback function on it.
this.taskListener.onFinished(result);
}
}
}
onPostExecute() is called as soon as the background task finishes. You can use the whole thing like this:
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
#Override
public void onFinished(String result) {
// Do Something after the task has finished
}
});
task.execute();
Or you can define the TaskListener completely separately like this:
ExampleTask.TaskListener listener = new ExampleTask.TaskListener() {
#Override
public void onFinished(String result) {
// Do Something after the task has finished
}
};
ExampleTask task = new ExampleTask(listener);
task.execute();
Or you can subclass TaskListener like this:
public class ExampleTaskListener implements TaskListener {
#Override
public void onFinished(String result) {
}
}
And then use it like this:
ExampleTask task = new ExampleTask(new ExampleTaskListener());
task.execute();
You can of course just override the onPostExecute() method of the AsyncTask, but that is not recommended and in most cases actually pretty bad practice. For example you could do this:
ExampleTask task = new ExampleTask() {
#Override
public void onPostExecute(String result) {
super.onPostExecute(result);
// Your code goes here
}
};
This will work just as well as the implementation above with a separate listener interface, but there are a few problems with this:
First and foremost you can actually break the ExampleTask all together. It all comes down to the super.onPostExecute() call above. If you as a developer override onPostExecute() like above and forget to include the super call or simply delete it for whatever reason that the original onPostExecute() method in the ExampleTask will not be called anymore. For example the whole listener implementation with the TaskListener would suddenly not work anymore since the call to the callback is implemented in onPostExecute(). You can also break the TaskListener in many other ways by unknowingly or unwittingly influencing the state of the ExampleTask so it won't work anymore.
If you look at what's actually happening when you override a method like this than it becomes much more clear what's going on. By overriding onPostExecute() you are creating a new subclass of ExampleTask. It would be the exact same thing as doing this:
public class AnotherExampleTask extends ExampleTask {
#Override
public void onPostExecute(String result) {
super.onPostExecute(result);
// Your code goes here
}
}
All this is just hidden behind a language feature called anonymous classes. Suddenly overriding a method like this doesn't seem so clean and quick anymore does it?
To summarise:
Overriding a method like this actually creates a new subclass. You are not just adding a callback, you are modifying how this class works and can unknowingly break oh so many things.
Debugging errors like this can be much more than just a pain in the a**. Because suddenly ExampleTask could throw Exceptions or simply not work anymore for no apparent reason, because you never actually modified its code.
Each class has to provide listener implementations at places where it is appropriate and intended. Sure you can just add them later on by overriding onPostExecute() but that is always very dangerous. Even #flup with his 13k reputation has forgotten to include the super.onPostExecute() call in his answer, imagine what some other not as experienced developer might do!
A little abstraction never hurt anybody. Writing specific listeners might be slightly more code, but it is a much better solution. The code will be cleaner, more readable and a lot more maintainable. Using shortcuts like overriding onPostExecute() essentially sacrifices code quality for a little bit convenience. That is never a good idea an will just cause problems in the long run.
In Java, functions are less of a first class citizen than in JavaScript. The AsyncTask provides the callback as a method in the class, which you should override.
See Make an HTTP request with android for a subclass of AsyncTask with an implementation of the doInBackground which makes a web request.
If you want to do multiple HTTP requests with different callbacks, you can override RequestTask and implement onPostExecute with the different callback implementations.
You can use an anonymous class to simulate the closure a JavaScript callback commonly uses:
new RequestTask(){
#Override
public void onPostExecute(String result) {
// Implementation has read only access to
// final variables in calling scope.
}
}.execute("http://stackoverflow.com");
As Xaver shows, you can also create a full-blown interface for the listener. This seems only useful to me if you wish to implement a couple default onPostExecute functions and pick one of these default implementations for a particular call.
in Kotlin
Firstly, create class AsyncTaskHelper as below.
class AsyncTaskHelper() : AsyncTask<Callable<Void>, Void, Boolean>() {
var taskListener: AsyncListener? = null
override fun doInBackground(vararg params: Callable<Void>?): Boolean {
params.forEach {
it?.call()
}
return true
}
override fun onPreExecute() {
super.onPreExecute()
}
override fun onPostExecute(result: Boolean?) {
super.onPostExecute(result)
taskListener?.onFinished(result as Any)
}
}
interface AsyncListener {
fun onFinished(obj: Any)
}
the code below you can use when you want to use async task.
AsyncTaskHelper().let {
it.execute(Callable<Void> {
//this area is the process do you want to do it in background
// dosomething()
}
}
null
})
it.taskListener = object : AsyncListener{
override fun onFinished(obj: Any) {
// this area is for the process will want do after finish dosomething() from Callable<Void> callback
}
}
From the code above. if you want to separate your process to several task. you can do as this code below.
AsyncTaskHelper().let {
it.execute(Callable<Void> {
// task 1 do in background
null
},Callable<Void>{
// task 2 do in background
null
},Callable<Void>{
// task 3 do in background
null
})
it.taskListener = object : AsyncListener {
override fun onFinished(obj: Any) {
// when task1,task2,task3 has been finished . it will do in this area
}
}
}
I also want to contribute to Sup.la's Kotlin solution by making it a little more generic in case you're only interested in .execute()ing a function asnychronously and .get()ting a result from an AsyncTask.
I split up the explanation in order to make it better understandable.
If you only want to copy paste, just skip to Step2 :)
Note: Keep in mind that AsyncTask is deprecated now. However, I think it'll stay around for while due to compatibility and stuff.
Step 1
This is how the generic class can look like:
import android.os.AsyncTask
#Suppress("DEPRECATION") // As mentioned, AsyncTask is deprecated now
class GenericAsyncTask() : AsyncTask<Callable<Any>, Void, Any?>() {
override fun doInBackground(vararg params: Callable<Any>): Any? {
// params receives vararg, meaning its an Array.
// In this example we only want pass one function to easen up the example (-> [0]).
return params[0]?.call()
}
}
As can be seen, the AsyncTask now takes any function passed to it (Callable<Any>), whereby Any and null can be the result of the function. Thus, here nobody cares about the types the AsyncTask has to handle or return or how the passed function looks like.
You can now use it like this:
// In this example lets assume we have a method which returns a list of Strings
var res: List<String>? = GenericAsyncTask().let {
it.execute(
Callable<Any> { your_random_function() }
).get() as? List<String>?
}
As you can see, we handle the Any dilemma just by casting it. This works since all Types are deriving from Any except null. To handle the latter, we're doing a safe cast using as?. Thus, also null as return-type is handled.
Step2
However, ultimatively we can even make this more generic:
// The same example result as shown above
// The casting will be inferred directly from your_random_function() return-type
val res: List<String>? = GenericAsyncTask().async(::your_random_function)
// For the sake of completeness, this is valid as well
val res: List<String>? = GenericAsyncTask().async<List<String>?> { your_random_function() }
class GenericAsyncTask() : AsyncTask<Callable<Any>, Void, Any?>() {
// This function takes any method you provide and even infers the result-type, thus, spares you the casting
public fun<T> async(method: () -> T): T? {
return this.let {
it.execute(Callable<Any> { method() }).get() as? T?
}
}
override fun doInBackground(vararg params: Callable<Any>): Any? { ... }
}
I have some code
service.doAction(request, Callback<Response> callback);
How can I using Mockito grab the callback object, and call callback.reply(x)
You want to set up an Answer object that does that. Have a look at the Mockito documentation, at
https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#answer_stubs
You might write something like
when(mockService.doAction(any(Request.class), any(Callback.class))).thenAnswer(
new Answer<Object>() {
Object answer(InvocationOnMock invocation) {
((Callback<Response>) invocation.getArguments()[1]).reply(x);
return null;
}
});
(replacing x with whatever it ought to be, of course)
Consider using an ArgumentCaptor, which in any case is a closer match to "grab[bing] the callback object".
/**
* Captor for Response callbacks. Populated by MockitoAnnotations.initMocks().
* You can also use ArgumentCaptor.forClass(Callback.class) but you'd have to
* cast it due to the type parameter.
*/
#Captor ArgumentCaptor<Callback<Response>> callbackCaptor;
#Test public void testDoAction() {
// Cause service.doAction to be called
// Now call callback. ArgumentCaptor.capture() works like a matcher.
verify(service).doAction(eq(request), callbackCaptor.capture());
assertTrue(/* some assertion about the state before the callback is called */);
// Once you're satisfied, trigger the reply on callbackCaptor.getValue().
callbackCaptor.getValue().reply(x);
assertTrue(/* some assertion about the state after the callback is called */);
}
While an Answer is a good idea when the callback needs to return immediately (read: synchronously), it also introduces the overhead of creating an anonymous inner class, and unsafely casting the elements from invocation.getArguments()[n] to the data type you want. It also requires you to make any assertions about the pre-callback state of the system from WITHIN the Answer, which means that your Answer may grow in size and scope.
Instead, treat your callback asynchronously: Capture the Callback object passed to your service using an ArgumentCaptor. Now you can make all of your assertions at the test method level and call reply when you choose. This is of particular use if your service is responsible for multiple simultaneous callbacks, because you have more control over the order in which the callbacks return.
If you have a method like:
public void registerListener(final IListener listener) {
container.registerListener(new IListener() {
#Override
public void beforeCompletion() {
}
#Override
public void afterCompletion(boolean succeeded) {
listener.afterCompletion(succeeded);
}
});
}
Then following way you can mock the above method easily:
#Mock private IListener listener;
#Test
public void test_registerListener() {
target.registerListener(listener);
ArgumentCaptor<IListener> listenerCaptor =
ArgumentCaptor.forClass(IListener.class);
verify(container).registerListener(listenerCaptor.capture());
listenerCaptor.getValue().afterCompletion(true);
verify(listener).afterCompletion(true);
}
I hope this might help someone, as I had spend lot of time in figuring out this solution.
when(service.doAction(any(Request.class), any(Callback.class))).thenAnswer(
new Answer() {
Object answer(InvocationOnMock invocation) {
Callback<Response> callback =
(Callback<Response>) invocation.getArguments()[1];
callback.reply(/*response*/);
}
});
I just can't figure out how to remove listener when I have some event executed. I have some leaking issue using websockets, and this can probaly fix it.
final WebSocket w = asyncHttpClient.prepareGet(url)
.execute(new WebSocketUpgradeHandler.Builder().build())
.get();
w.addWebSocketListener(new WebSocketTextListener() {
public void onMessage(String message) {
listener.onMessage(responseMessage);
// Here is the place I want to do my w.removeWebSocketListener(l);
}
#Override
public void onFragment(String s, boolean b) {
}
public void onOpen(WebSocket websocket) {
}
#Override
public void onClose(WebSocket webSocket) {
}
#Override
public void onError(Throwable throwable) {
}
});
The problem is when I create WebSocketTextListener lis = new .... and passing in there is something like one object need other object and other object is dependent on this, and I'm still now allowed to do what I want.
Looks like it is something simple, but can't figure out.
Normally event listeners can be removed with a removeXXXListener method. But it requires that you provide the exact same event listener instance as parameter. You can store the event listener and later remove it using the same reference. But since you, in the onMessage message already are inside the scope of the event listener, using this should work.
Try something like
listener.onMessage(responseMessage);
// Here is the place I want to do my w.removeWebSocketListener(l);
w.removeWebSocketListener(this);
Using "this" in anonumous inner class is the way to solve problem. But, it is muck better to refactor code, to avoid using anonumous classes, for testability and better understanding.