Java extension methods for LiveData - java

In Kotlin there's an extension method observeOnce (https://code.luasoftware.com/tutorials/android/android-livedata-observe-once-only-kotlin/) which is the behaviour I'm looking to replicate in Java. It's to my understanding from googling that you can't use Kotlin extension methods in java (may be wrong), so I've got two options of using SingleEventLiveData which I've implemented and am not keen on, and removing my observer once used;
final LiveData<List<String>> stringsLiveData = mViewModel.getStrings();
stringsliveData.observe(getViewLifecycleOwner(), strings -> {
// Do stuff with data here
stringsLiveData.removeObservers(getViewLifecycleOwner());
});
Is there an equivilant method that can be used as the link above so;
mViewModel.getStrings().observeOnce(getViewLifecycleOwner(), strings -> {
//Do stuff here
});
Edit: As per the accepted answer below (modified to compile) I've got;
class LiveDataUtils {
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(o -> {
liveData.removeObserver(observer);
observer.onChanged(o);
});
}
}
and a simple usage of this;
LiveDataUtils.observeOnce(
mViewModel.getStrings(),
strings -> {
// Do some work here
}
);

Every Kotlin extension function is resolved statically, which means that you can do the same in Java by using static functions. It is not as readable or as intuitive as the extension functions, but it does the same job.
Create a util class with a static method:
public class LiveDataUtils {
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(new Observer<T>() {
#Override
public void onChanged(T t) {
liveData.removeObserver(this);
observer.onChanged(t);
}
});
}
}
I haven't tested the code, so it might have some errors. The point was to show you how you can replace extension functions in Java.
EDIT: Updated according to follow up by #Marek Potkan, since this is the accepted answer. As I mentioned, I haven't tested the code and I provided a wrong reference by mistake.

#deluxe1 answer wouldn't work. It is removing observer called observer, but that's not the one which is used in the observeForever method. Expanded version should be used instead of the lambda function here:
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(new Observer<T>() {
#Override
public void onChanged(T t) {
liveData.removeObserver(this);
observer.onChanged(t);
}
});
}
I have tested both approaches.

Related

How to use functional interface returning void?

I have this construction:
if (Objects.isNull(user.getMartialStatus())) {
user.setMartialStatus(MartialStatus.MARRIED);
}
I have many of them, & I want to optimize code using functional interface.
Okay. I write something like this:
public static <T> void processIfNull(T o, Supplier<Void> s) {
if (Objects.isNull(o)) {
s.get();
}
}
Then, I wait that this code shall work:
processIfNull(user.getMartialStatus(), () -> user.setMartialStatus(MartialStatus.MARRIED));
But IDEA write:
void is not compatible with Void
Please, tell me, what to do.
As the error explains Void is a class which is not equivalent to void. Supplier<Void> expects to return Void like Supplier<String> will expect String object to return.
So your functional interface should be like below.
It has a void apply() which matches the signature of () -> ...
#FunctionalInterface
public interface ActionIfNotNull {
void apply();
}
However when you search for an inbuild functional interface, you can come up with Runnable as Jon Skeet suggested.
Solution
public static <T> void processIfNull(T o, Runnable s) { // instead of you Runnable can use your own functional interface like ActionIfNotNull
if (Objects.isNull(o)) {
s.run();
}
}
As of Java 9 Optional has the ifPresentOrElse method, which could be used for this.
Optional
.ofNullable(user.getMartialStatus())
.ifPresentOrElse(o -> {}, () -> user.setMartialStatus(MartialStatus.MARRIED););
You could also replace the o -> {} by some NOOP Consumer if you like, like this:
private static final Consumer<Object> NOOP = o -> {};
...
Optional
.ofNullable(user.getMartialStatus())
.ifPresentOrElse(NOOP, () -> user.setMartialStatus(MartialStatus.MARRIED););
Anyway, I think the solution Trine came up with, is preferable, because it makes it much clearer, what's going on.

How to surround a callback invocation with another piece of code in a best way?

I have a simple, functional interface:
public interface Callback<T> {
void invoke(T param);
}
I make many asynchronous operations like:
public void getSubfolders(Folder folder, Callback<FolderList> result){
asyncExecutor.submit(() -> {
FolderList list = folder.get_SubFolders();
result.invoke(list);
});
}
The results must be processed on a main thread. For that, I have a JavaFX method:
Platform.runLater(Runnable task);
Which makes my code a mess like this one (and this pattern is repeated in 50 other methods):
public void getSubfolders(Folder folder, Callback<FolderList> result){
asyncExecutor.submit(() -> {
FolderList list = folder.get_SubFolders();
Platform.runLater(() -> result.invoke(list));
});
}
I'd like to wrap each callback invocation with Platform.runLater(...).
The only thing I came up with is a default method:
public interface Callback<T> {
void invoke(T param);
default void invokeOnMain(T param){
Platform.runLater(() -> invoke(param));
}
}
And then, I just call result.invokeOnMain(list).
Is there a better approach for patterns like this one?
You can go one step further than the suggestions in the other answers, and abstract Platform.runLater() as an java.util.concurrent.Executor (it is, after all, something that executes Runnables).
So you can do this:
import java.util.concurrent.Executor ;
import java.util.function.Consumer ;
import java.util.function.Supplier ;
public class Invoker {
private final Executor backgroundExecutor ;
private final Executor foregroundExecutor ;
public Invoker(Executor backgroundExecutor, Executor foregroundExecutor) {
this.backgroundExecutor = backgroundExecutor ;
this.foregroundExecutor = foregroundExecutor ;
}
public <T> void invoke(Supplier<? extends T> task, Consumer<? super T> callback) {
backgroundExecutor.execute(() -> {
T result = task.get();
foregroundExecutor.execute(() -> callback.accept(result));
});
}
}
And now your example code becomes:
Invoker invoker = new Invoker(asyncExecutor, Platform::runLater);
// ...
invoker.invoke(folder::getSubFolders, result::invoke);
The nice thing here is you can use the same Invoker class with Swing: just create a
new Invoker(asyncExecutor, SwingUtilities::invokeLater)
[Note: I did not come up with this myself; I saw it in a post on here a few years back. I cannot find that post now to give proper credit, but will edit this if I manage to dig it out. If the person who originally posted this idea sees this, please comment and I will credit you]
It defeats in a some way the default method intention :
Default methods enable you to add new functionality to the interfaces
of your libraries and ensure binary compatibility with code written
for older versions of those interfaces.
Why not put this code in a specific class :
public class PlatformUtil {
public static <T> void invoke(Callback<T> result, T param){
Platform.runLater(() -> result.invoke(param));
}
}
And from the client side, you could also use a static import for PlatformUtil.invoke to reduce further the boiler plate code.
It could give :
import static PlatformUtil.invoke;
...
public void getSubfolders(Folder folder, Callback<FolderList> result){
asyncExecutor.submit(() -> {
FolderList list = folder.get_SubFolders();
invoke(result, list);
});
}
Of course you could do the same thing with an instance method.
After you use the Decorator Pattern, you found that you never need to change the getSubfolders method at all. and then you can write a well defined layer system, when you put the components into its own package, for example:
// v--- move the UiCallback into ui package
package com.projectx.ui;
public class UiCallback<T> implements Callback<T> {
private final Callback<T> target;
private UiCallback(Callback<T> target){
this.target = Objects.requireNonNull(target);
}
public void invoke(T param){
Platform.runLater(() -> target.invoke(param));
}
public static <T> Callback<T> runOnMainThread(Callback<T> source){
return source instanceof UiCallback? source : new UiCallback<>(source);
}
}
Everything is fine, there is only one place you need to change is where you call the getSubfolders, for example:
Callback<T> origin = ...
getSubfolders(folder, runOnMainThread(origin));
If you found that you need to call runOnMainThread many times in your UI module, maybe you lose some domain concepts in your UI layer. you should to extract new domain concept by new classes or interfaces for that things, e.g: FolderExplorer.

Java: Using a class as an parameter to describe a setups

I couldn't think of a good way to name this. Basically I'm have a program where I want to have a default "pattern" almost I guess of how something should function. But I wanted to allow the use to create their own implementation (This is like an API) of the class and use that as a parameter instead, with the functionality inside. Is this the most efficient way to do it? If you don't understand that bad description here is an example.
public class SimpleStyle extends AbstractStyle {
public void personalizedImplementation() {
// manipulate the program this way
}
}
Then in the method
public static void do(Class<? extends AbstractSyle> style) {
// Use reflection in herre to get the implementation and do it
}
Is there a better and more efficient way to do something like this
You should not use reflection for this task if you can avoid it. It is less readable and more error-prone than well designed interfaces.
The basic solution (I’m not sure whether you already considered it) is to simply pass instances of AbstractStyle to your method:
public static void doSomething(AbstractStyle style) {
style.personalizedImplementation();
}
public static void main(String[] args) {
do(new SimpleStyle());
}
If you cannot use this approach – this depends on the specific use case – you could define an additional interface that handles the creation of the AbstractStyle instance:
public interface StyleFactory {
AbstractStyle createStyle();
}
public class SimpleStyleFactory implements StyleFactory {
#Override
public SimpleStyle createStyle() {
return new SimpleStyle(/* ... */);
}
}
public static void doSomething(StyleFactory styleFactory) {
AbstractStyle style = styleFactory.createStyle();
style.personalizedImplementation();
}
public static void main(String[] args) {
do(new SimpleStyleFactory());
}
Note: do is a Java keyword, so it can’t be used as an identifier. I used doSomething instead.

Java Passing in Type as Function Parameter

I come from a Python background and in Python you can pass in the type of an object as a parameter. But in Java you cannot do this, any tips on how to get something like this working?
private void function(Type TypeGoesHere)
Stock s = new TypeGoesHere();
s.analyze();
}
Java does not support Python’s way of referencing functions and classes. To achieve this behaviour, you have to use two advanced techniques: generics and reflection. Explaining these concepts is beyond the scope of a SO answer. You should read a Java guide to learn about them.
Yet here is an example how this would look like, assuming that the given class has a no-argument constructor:
public <T extends Stock> void analyzeNewStock(Class<T> clazz) throws Exception {
Stock s = clazz.newInstance();
s.analyze();
}
Then call this function with analyzeNewStock(MyStock.class).
As this is a rather complicated and error-prone approach, you’d rather define an interface that creates Stock instances:
public interface StockProvider {
Stock createStock(String value);
}
public class MyStockProvider implements StockProvider {
private final String valueTwo;
public MyStockProvider(String valueTwo) {
this.valueTwo = valueTwo;
}
#Override
public Stock createStock(String valueOne) {
return new MyStock(valueOne, valueTwo);
}
}
public class MyOtherClass {
public void analyzeNewStock(StockProvider provider) {
provider.createStock("Hi!").analyze();
}
public static void main(String[] args) {
analyzeNewStock(new MyStockProvider("Hey!"));
}
}
In Java you can pass a Class. You can do it like this:
private void function(Class c)
This is not very common procatice though. You can probably get wha you need by looking into Strategy pattern, or proper use of Object Oriented Programming (polymorphism).
If you are looking for a way to build some objects, look into Factory pattern.
If you want to create a generic class- look into this detailed answer: https://stackoverflow.com/a/1090488/1611957
You could use generics. For example:
private <T> void function(Class<T> clazz) {
try{
T t = clazz.newInstance();
//more code here
}catch(InstantiationException | IllegalAccessException ex){
ex.printStackTrace();
}
}
The Class<T> clazz shows what type to instantiate. The try/catch is just to prevent errors from stopping your code. The same idea is expanded in this SO post. More info here.
However, I'm not really sure why you would want to do this. There should easily be a workaround using a simple interface. Since you already know that you want an object with type Stock, you could pass an implementation of the interface. For example:
//interface to implement
public interface Stock {
public void analyze();
}
//rewrite of function
private void function(Stock s){
s.analyze();
}
And using two ways to call function:
//first way
public class XYZ implements Stock{
public void analyze(){
//some code here
}
}
//calling the function
function(new XYZ());
//second way
function(new Stock(){
public void analyze(){
//your code here
}
});

Preprocessor variables in Java

I am developing with GWT and share a codebase with an Android developer. Some functions we want to share take speciffic arguments like "Drawable" under Android and "Image" under GWT.
Is it possible to use a preprocessor variable as in C++:
#ifdef ANDROID
public void DrawImg(Drawable img);
#elif GWT
public void DrawImg(Image img);
#endif
The solution we are testing is a Generic like this:
interface DrawImgInterf<T extends Object> {
public void DrawImg(T img);
}
However using a preproccesor variable seems better. Is there such a thing in Java?
No, there's nothing like that in normal Java. You could run a preprocessor of course, but that will make it painful to develop the code. (Anything like an IDE which expects the code to be "normal" Java is going to get confused.)
Have you considered using an interface instead, which abstracts out the common operations, and binds to the appropriate real type at execution time? That won't always work (as adding a proxy breaks situations where object identity is important) but in some cases it can be helpful.
No, there are no preprocessor variables in Java.
for such cases it is the best way to use a preprocessor
I used it for my J2ME developments http://code.google.com/p/java-comment-preprocessor/wiki/ExampleOfUsageForJ2ME
Java+ is a preprocessor which can perform substitution using resource bundles:
public static void
main(String[] args)
{
System.out.println({{
The answer,
my dearest,
is {{computeAnswer()}}.
}});
}
static String computeAnswer()
{
return {{my computed answer}};
}
References
java+.tgz
java+.dmg
Employing Visitor Pattern here, is making sense to me. For example,
interface ImageVisitor {
void visit(GWTImage image);
void visit(AndroidImage image);
}
interface IImage {
void accept(ImageVisitor visitor);
}
class GWTImage implements IImage {
..
public void accept(ImageVisitor visitor) {
visitor.visit(this);
}
..
}
class AndroidImage implements IImage {
..
public void accept(ImageVisitor visitor) {
visitor.visit(this);
}
..
}
class GWTImageVisitor implements ImageVisitor {
public void visit(GWTImage image) {
Image img = image.getImage();
..
}
}
class AndroidImageVisitor implements ImageVisitor {
public void visit(AndroidImage image) {
Drawable drawable = image.getDrawable();
..
}
}

Categories

Resources