i cant seem to access values inside an overriden method(a custom listener) - android-fragmentactivity

so i have a listener that listens for typed text from the main activity in a search-view and gets that data to a fragment of the same main activity. the above process is working well problem is i cant seem to access the data from the overridden listener to the rest of the fragment class so i can actually use it .
here is the listner instance
private void getSearch(){
searchView.setOnSearchViewListener(new MaterialSearchView.SearchViewListener() {
#Override
public void onSearchViewShown() {
Log.d(TAG, "onSearchViewShown: searchview running");
}
#Override
public void onSearchViewClosed() {
logoRL.setVisibility(View.VISIBLE);
Log.d(TAG, "onSearchViewClosed: 0000");
}
});
searchView.setOnQueryTextListener(new MaterialSearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
Log.d(TAG, "VALUE"+ newText);
listner.onDataLoaded(newText);
return true;
}
});
here is the fragment class in which i need the text values to be seen. the data value is what i need to use. also declaring a global variable and then assigning it to this value doesn't work as it returns null, i'm thinking its because the overridden method somehow gets called before the oncreatview of the fragment does but i'm not sure. any help would be largely appreciated, i have been on this for the past 4 days, i'm really getting desperate
#Override
public void onSearchViewSelected(String newText) {
}
#Override
public void onDataLoaded(String data) {
Log.d(TAG, "query" + data);
}

i solved the problem by doing it the other way around, getting what i needed to the method instead of the opposite and it worked

Related

Akka: Can an actor of some class become an actor of a diferent class?

As a course project, I am trying to implement a (simulation) of the Raft protocol.
In this post, I will not use Raft terminology at all; instead, I will use a simplified one.
The protocol is run by a number of servers (for example, 5) which can be in three different states (A, B, C).
The servers inherit some state variables and behavior from a "base" kind, but they all also have many unique state variables and methods, and respond to different messages.
At some point of the protocol, a server in some state (for example, A) is required to become the other state (for example, B).
In other words, the server should:
Lose the state variables and methods of state A, acquire those of state B, but maintain the variables of the "base" kind.
Stop responding to messages destined for state A, start responding to messages destined for state B.
In Akka, Point 1 can be implemented using Receives and become().
Point 2 is needed because, for example, an actor of class B should not have access to state variables and methods of an actor of class A. This aims at separating concerns, and achieving a better code organization.
The issues I am facing in implementing these Point 2 are the following:
Right now, my implementation has only one actor, which contains both A and B state variables and methods.
The protocol I am trying to implement requires each server has to keep a reference to the others (i.e., the ActorRef of the others).
I can't simply spawn an actor in state B, transfer the values of the state variables of the "base" kind to it, and stop the old actor, because the newly spawned actor has a new ActorRef, and the other servers are in the dark about it, and they will continue sending messages using the old ActorRef (therefore, the new actor would not receive anything, and both parties time out).
A way to circumvent the issue is that the newly spawned actor "advertises" itself by sending a message to the other actors, including its old ActorRef.
However, again due to the protocol, the other servers may be temporarily not available (i.e., they are crashed), thus they might not receive and process the advertisement.
In the project, I must use extensions of AbstractActor, and not FSM (final state machines), and have to use Java.
Is there any Akka pattern or functionality that solves this use case? Thank you for any insight. Below is a simplified example.
public abstract class BaseActor extends AbstractActor {
protected int x = 0;
// some state variables and methods that make sense for both A and B
#Override
public Receive createReceive() {
return new ReceiveBuilder()
.matchEquals("x", msg -> {
System.out.println(x);
x++;
})
.build();
}
}
public class A extends BaseActor {
protected int a = 10;
// many other state variables and methods that are own of A and do NOT make sense to B
#Override
public Receive createReceive() {
return new ReceiveBuilder()
.matchEquals("a", msg -> {
System.out.println(a);
})
.matchEquals("change", msg -> {
// here I want A to become B, but maintain value of x
})
.build()
.orElse(super.createReceive());
}
}
public class B extends BaseActor {
protected int b = 20;
// many other state variables and methods that are own of B and do NOT make sense to A
#Override
public AbstractActor.Receive createReceive() {
return new ReceiveBuilder()
.matchEquals("b", msg -> {
System.out.println(b);
})
.matchEquals("change", msg -> {
// here I want B to become A, but maintain value of x
})
.build()
.orElse(super.createReceive());
}
}
public class Example {
public static void main(String[] args) {
var system = ActorSystem.create("example");
// actor has class A
var actor = system.actorOf(Props.create(A.class));
actor.tell("x", ActorRef.noSender()); // prints "0"
actor.tell("a", ActorRef.noSender()); // prints "10"
// here, the actor should become of class B,
// preserving the value of x, a variable of the "base" kind
actor.tell("change", ActorRef.noSender());
// actor has class B
actor.tell("x", ActorRef.noSender()); // should print "1"
actor.tell("b", ActorRef.noSender()); // should print "20"
}
}
This is a sketch implementation of how this could look like.
You model each of the states a separate class:
public class BaseState {
//base state fields/getters/setters
}
public class StateA {
BaseState baseState;
//state A fields/getters/setters
..
//factory methods
public static StateA fromBase(BaseState baseState) {...}
//if you need to go from StateB to StateA:
public static StateA fromStateB(StateB stateB) {...}
}
public class StateB {
BaseState baseState;
//state B fields/getters/setters
//factory methods
public static StateB fromBase(BaseState baseState) {...}
//if you need to go from StateA to StateB:
public static StateB fromStateA(StateA stateA) {...}
}
Then in your Actor you can have receive functions defined for both A and B and initialize it to A or B depending which one is the initial one
private static class MyActor extends AbstractActor
{
private AbstractActor.Receive receive4StateA(StateA stateA)
{
return new ReceiveBuilder()
.matchEquals("a", msg -> stateA.setSomeProperty(msg))
.matchEquals("changeToB", msg -> getContext().become(
receive4StateB(StateB.fromStateA(stateA))))
.build();
}
private AbstractActor.Receive receive4StateB(StateB stateB)
{
return new ReceiveBuilder()
.matchEquals("b", msg -> stateB.setSomeProperty(msg))
.matchEquals("changeToA", msg -> getContext().become(
receive4StateA(StateA.fromStateB(stateB))))
.build();
}
//assuming stateA is the initial state
#Override
public AbstractActor.Receive createReceive()
{
return receive4StateA(StateA.fromBase(new BaseState()));
}
}
Admittedly, my Java is rusty, but for example, this actor (or something very much like it...) will take strings until it receives a Lock message, after which it can be queried for how many distinct strings it received before being locked. So in the first Receive it gets, it tracks a Set of the strings received in order to dedupe. On a Lock it transitions to a second Receive which does not contain the Set (just an Integer field) and ignores String and Lock messages.
import akka.japi.JavaPartialFunction;
import java.util.HashSet;
import scala.runtime.BoxedUnit;
public class StringCounter extends AbstractActor {
public StringCounter() {}
public static class Lock {
private Lock() {}
public static final Lock INSTANCE = new Lock();
}
public static class Query {
private Query() {}
public static final Query INSTANCE = new Query();
}
/** The taking in Strings state */
public class AcceptingStrings extends JavaPartialFunction<Object, BoxedUnit> {
private HashSet<String> strings;
public AcceptingStrings() {
strings = new HashSet<String>();
}
public BoxedUnit apply(Object msg, boolean isCheck) {
if (msg instanceof String) {
if (!isCheck) {
strings.add(msg);
}
} else if (msg instanceof Lock) {
if (!isCheck) {
context().become(new Queryable(strings.size()), true);
}
} else {
// not handling any other message
throw noMatch();
}
return BoxedUnit.UNIT;
}
}
/** The responding to queries state */
public class Queryable extends JavaPartialFunction<Object, BoxedUnit> {
private Integer ans;
public Queryable(int answer) {
ans = Integer.valueOf(answer);
}
public BoxedUnit apply(Object msg, boolean isCheck) {
if (msg instanceof Query) {
if (!isCheck) {
getSender().tell(ans, getSelf());
}
} else {
// not handling any other message
throw noMatch();
}
return BoxedUnit.UNIT;
}
}
#Override
public Receive createReceive() {
return new Receive(new AcceptingStrings());
}
}
Note that in Queryable the set is long gone. One thing to be careful of is that the JavaPartialFunction will typically have apply called once with isCheck set to true and if that call doesn't throw the exception returned by noMatch(), it will be called again "for real" with isCheck set to false. You therefore need to be careful to not do anything but throw noMatch() or return in the case that isCheck is true.
This pattern is exceptionally similar to what happens in Akka Typed (especially in the functional API) under the hood.
Hopefully this illuminates this approach. There's a chance, of course, that your instructors will not accept this, though in that case it might be worth pushing back with the argument that:
in the actor model state and behavior are effectively the same thing
all the functionality is contained within an AbstractActor
I'd also not necessarily recommend using this approach normally in Java Akka code (the AbstractActor with state in its fields feels a lot more Java-y).

How would one unit test api call method (rxjava+retrofit)?

I'm trying to unit test an api call made with retrofit and rxjava.
In order to do that i'm mocking the api call object but api calls subscriber won't trigger its onNext method.
ApiCallsTest.java:
//custom object replacing api call response object
Observable<FastRechargeClass[]> apiObservable = Observable.just(fastRechargeList);
InterfaceAPI api = mock(InterfaceAPI.class);
when(retrofitApi.getApiInterface(context)).thenReturn(api); when(api.getLatestTransactions("token")).thenReturn(apiObservable);
apiCalls.getLatestTransactions("token",context);
ApiCalls.java:
public void getLatestTransactions(String token, final Context context) {
String methodName = "getLatestTransactions";
InterfaceAPI api = retrofitApi.getApiInterface(context);
Observable<FastRechargeClass[]> call = api.getLatestTransactions(token);
call.observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(new Observer<FastRechargeClass[]>() {
#Override
public void onSubscribe(Disposable d) {
WriteLog.print("onSubscribe");
}
#Override
public void onNext(FastRechargeClass[] fastRechargeClasses) {
fastRechargeManager.runUpdateFastRechargeDb(fastRechargeClasses);
}
#Override
public void onError(Throwable e) {
logOnFailureRequests(methodName, e.getMessage());
}
#Override
public void onComplete() {
}
});
}
When running test
onSubscribe is being called and it stops
You need to trigger event emission manually. To do this you need to call method
.blockingFirst()
or
.blockingGet()
depends of observable type you are using.
So you have to add
call.blockingGet()
at the end of getLatestTransactions method or this method should return created observable and call blocking get inside a test method.

How to mock a retrofit service observable calling onError?

I am testing this code.
service.getProducts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Result<Catalog<SoajsProductPreview>>>() {
#Override
public void onError(Throwable e) {
view.showErrorView(e);
}
#Override
public void onNext(Result<Product> products) {
view.showProducts(products)
}
#Override
public void onCompleted() {}
});
Testing that view.showProducts() the mocked service returns results works fine.
I do
when(service.getProducts().thenReturn(someObservable);
Now I want to test that view.ShowErrorView() is called when the service throws an error but I can't find a way to do that:
Obviously the following doesn't compile
when(service.getProducts().thenReturn(someException);
And this throws an exception immediately but doesn't call the Subscriber's onError method
when(service.getProducts().thenReturn(someException);
How can I get Subscriber.onError() called?
when(service.getProducts().thenReturn(Observable.error(someException))
should work. See the documentation starting here.

Task chaining in JavaFX8: Start next Task after onSucceeded finished on previous task

I'm rather new to JavaFX8 and facing the following problem. In my current App, which is for document processing/editing, I have two rather expensive tasks. Opening a document and saving a document.
My app has the buttons "import next", "export current" and "export current and import next". For Import and Export, I have two Task of the following structure:
private class Export extends Task<Void> {
public Export() {
this.setOnRunning(event -> {
// do stuff (change cursor etc)
});
this.setOnFailed(event -> {
// do stuff, eg. show error box
});
this.setOnSucceeded(event -> {
// do stuff
});
}
#Override
protected Void call() throws Exception {
// do expensive stuff
return null;
}
}
I submit the task using the Executors.newSingleThreadExecutor();.
For the functionality "export current and import next", my goal is to submit the Export and Import tasks to the executor, but my Import tasks should only run if the export-task was sucessful and the EventHandler given in setOnSucceedded (whichs runs on the GUI thread) finished. If the export fails, it does not make any sense to load the next document because user interaction is needed. How can this be achieved?
First I tired to but the entire logic/error handling in the call method, but this does not work as I cannot change the GUI from this method (i.e. to show an error-box).
As workaround, I'm manually submitting the import-task on the last line of my setOnSucceeded in the export-task, but this is not very flexible, because I want to be sure this task exports only (without subsequent import)...
Don't call the handler property methods setOnXXX in your Task subclass constructor. These actually set a property on the task, so if you also call those methods from elsewhere you will replace the functionality you're implementing in the class itself, rather than add to it.
Instead, override the protected convenience methods:
public class Export extends Task<Void> {
#Override
protected void succeeded() {
super.succeeded();
// do stuff...
}
#Override
protected void running() {
super.running();
// do stuff...
}
#Override
protected void failed() {
super.failed();
// do stuff...
}
#Override
protected Void call() {
// do expensive stuff....
return null ;
}
}
Now you can safely use setOnXXX(...) externally to the Export class without breaking its functionality:
Export export = new Export();
export.setOnSucceeded(e -> {
Import import = new Import();
executor.submit(import);
});
executor.submit(export);
This puts the logic for chaining the tasks at the point where you actually create them, which would seem to be the correct place to do it.
Note that another way to provide multiple handlers for the change of state is to register listeners with the stateProperty():
Export export = new Export();
export.stateProperty().addListener((obs, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
// ...
}
});
From testing, it appears the order of execution of these different mechanisms is:
state listeners
the onSucceeded handler
the Task.succeeded method
All are executed on the FX Application Thread.
So if you want the code in the Task subclass to be executed before the handler added externally, do
public class Export extends Task<Void> {
public Export() {
stateProperty().addListener((obs, oldState, newState) -> {
if (newState == Worker.State.RUNNING) {
// do stuff
} else if (newState == Worker.State.SUCCEEDED) {
// do stuff
} else if (newState == Worker.State.FAILED) {
// do stuff
}
});
}
#Override
public Void call() {
// ...
}
}
Finally, you could implement the entire logic in your call method: if you need to interact with the UI you can wrap those calls in a Platform.runLater(() -> {});. However, separating the functionality into different tasks as you have done is probably cleaner anyway.

XSocket.net. how to send a message to a client from an object which is not a controller

I have a class that starts a server:
public class SocketServer
{
private static IXSocketServerContainer server = null;
public SocketServer()
{
server = XSockets.Plugin.Framework.Composable
.GetExport<IXSocketServerContainer>();
}
public bool StartServers()
{
try
{
server.StartServers();
return true;
} catch
{
return false;
}
}
this class has a method:
public void SendEventMessageToAllClients(string message)
{
XSockets.Core.XSocket.Helpers.XSocketHelper
.SendToAll<MyController>(new MyController(), message, "events");
}
where MyController is my own controller, it is implemented and the server can find it and this method work.
Now I would like to expand the functionality with a new method that allows me to send an event to an specific client:
public void SendEventMessageToClient(string clientId, string message)
{
XSockets.Core.XSocket.Helpers.XSocketHelper
.SendTo<MyController>(new MyController(),
p => p.ClientId == clientId, message, "events");
}
Is this the right approach or am I doing something wrong?
Thanks!
I would not recomend that approach, I have not even tested if that actaully works.
You create a new controller every time just to be able to access the extension method.
I am guessing that since you have this on the class starting the server you only use this as a publisher?
If so the correct way would be to install the XSockets.Client package and use the client pool to publish messages: client pool documentation
Example with client pool
The nice thing about the client pool is that you do not need to create an instance every time. The pool will reuse your connection to the controller.
Using the clientpool (or a real client connection) will ensure that the message pass through the Pipeline and all interceptors if you have any. Using a controller instance directly will never reach the pipline, interceptors etc.
//Get a pool client
ClientPool poolClient =
XSockets.Client.ClientPool.GetInstance("ws://127.0.0.1:4502/MyController", "*");
Methods for sending a message to the controller.
public void SendEventMessageToClient(Guid clientId, string message)
{
poolClient.Send(new {clientId, message}, "SendEventMessageToClient");
}
public void SendEventMessageToAllClients(string message)
{
poolClient.Send(message, "SendEventMessageToAllClients");
}
The controller
public void SendEventMessageToClient(Guid clientId, string message)
{
this.SendTo(p => p.ClientId == clientId, message, "SendEventMessageToClient");
}
public void SendEventMessageToAllClients(string message)
{
this.SendToAll(message, "SendEventMessageToAllClients");
}
Example with instance of controller
If you decide to use the way you have done you should at least create on ONE instance of the controller to use the in the server class.
Important: Using a controller instance directly will never reach the pipline, interceptors etc.
//Be aware of the fact that this controller NEVER will have a connection.
//It can only send to others, it can never receive messages!
MyController c = new MyController();
//You should probably have a Guid here instead of string
//Also note that the client have to subscribe for "events" to get the message
public void SendEventMessageToClient(Guid clientId, string message)
{
this.SendTo(p => p.ClientId == clientId, message, "SendEventMessageToClient");
}
public void SendEventMessageToAllClients(string message)
{
this.SendToAll(message, "SendEventMessageToAllClients");
}
Since I do not know what you are trying to accomplish Im not sure this is the best way, but one of the merhods above should work.
EDIT: Also, in a real application you probably dont have access to the MyController class since it probably is in a separate assembly not being referenced at compile time. So then you approach will not even be possible and the way to go then is client or clientpool
/Uffe
Uffe, you're right an the ClientPool is the right option for me, I had problems running your code because some of the mappings proposed by you are not working, here is your proposed solution slightly modified to make it run:
//Get a pool client
ClientPool poolClient = XSockets.Client.ClientPool.GetInstance("ws://127.0.0.1:4502/MyController", "*");
Methods for sending a message to the controller. ITextArgs are needed in this case
public void SendEventMessageToClient(Guid clientId, string message)
{
ITextArgs textargs = new TextArgs(mess, "SendEventMessageToClient");
poolClient.Send(new {clientId = guid, message = "Hello to one client"}, "SendEventMessageToClient");
}
Here, I TextArgs is not needed, it can be used, but string works also properly. It seems that the conversion to ITextArgs works fine here.
public void SendEventMessageToAllClients(string message)
{
poolClient.Send("hello all", "SendEventMessageToAllClients");
}
The controller: Only ITextArgs messages are mapped. Using string will not work.
public void SendEventMessageToClient(Guid clientId, ITextArgs message)
{
c.SendTo(p => p.ClientId == clientId, message.data, "events");
}
public void SendEventMessageToAllClients(ITextArgs message)
{
c.SendToAll(message.data, "events");
}
Thanks you very much Uffe for your help!