I need to run a task inside a RMI service and it needs an event listener implemented for it. Right now when I pass the EventListener over RMI it does execute the call however the callback method of the Listener is not being invoked and it remains in the wait state. How should I get this to work?
public class MyEventListener implements Serializable, ABCEventListener {
private static final long serialVersionUID = -4686421592620210489L;
private boolean registrationCompleted = false;
public boolean getRegistrationCompleted(){
return registrationCompleted;
}
#Override
public void onSomethingDiscovered(Agent agent) {
System.out.println("Added agent "+agent.toString()+" to the set \n");
}
#Override
public void onDiscoveryComplete() {
this.registrationCompleted = true;
System.out.println("Discovery process completed. \n");
}
}
Here is where I pass the eventlistener to the RMI service 'ds'
MyEventListener myEL = new MyEventListener();
ds.discoverAsync(val, myEL);
waitForRegistration();
.
.
private void waitForRegistration() {
try{
while(!dcev.getRegistrationCompleted()){
System.out.println("Please wait...");
Thread.sleep(15000);
}
}catch(InterruptedException e){
logger.error("InterruptedException raised while waiting for registration",e);
e.printStackTrace();
}
}
The problem is that because your event listener is serializable the data fields of your event listener get sent across the wire and a new object created on the server side. The method is called on this copy of your event listener. This makes perfect sense for data objects, but for the likes of event listeners doesn't work as you want your client code to get the call.
I believe you can make this work if your event listener extends RemoteObject. If you do this, instead of your object being copied, it will be exposed as an RMI service when you call the server. The server instead of getting a copy of your object, will get a proxy to your event listener. The call to the event listener will result in an RMI call in the reverse direction to call your event listener.
See Passing Remote Objects in the RMI guide for more details.
Related
Whenever we want to create a listener, we implement a listener interface. For example, lets implement SensorEventListener.
Now we have to override the methods of this listener interface.
public void onSensorChanged(SensorEvent event);
and
public void onAccuracyChanged(Sensor sensor, int accuracy);
What I don't understand is:
Why and how these methods work when I automatically use them?
Why does onAccuracyChanged method gets called when the accuracy changes?
After all, onAccuracyChanged is just an empty method that we override because our formula (or the interface we implement) requires us to do so. If it is something magical caused by the lower levels
When and why would someone actually use an interface in his/her
self-project regardless of android?
Here is a suitable answer. Allow me to give you an example about listeners.
Listeners:
Suppose there is a class that fetches data in the background, the Worker, and another class that is interested in that data, the InterestedClass.
public class Worker extends Thread{
interface DataFetchedListener{
void onDataFetched(String data);
}
private DataFetchedListener listener;
#Override
public void run(){
String data = fetchData();
// Data fetched inform your listener so he can take action
listener.onDataFetched(data);
}
public void setDataFetchedListener(DataFetchedListener listener){
this.listener = listener;
}
private String fetchData(){
// returns the fetched data after some operations
return "Data";
}
}
public class InterestedClass implements Worker.DatafetchedListener{
#Override
public void onDataFetched(String data){
doSomethingWith(data);
}
private doSomethingWith(String data){
// just print it in the console
System.out.println("Data fetched is -> " + data);
}
}
The Worker does not care which class will manipulate its data, as long as that class follows the contract of DataFetchedListener.
Equally this means that any class is able to do something with the data (InterestedClass just prints it in the console) but Worker does not need to know which class is that, just that it implements its interface.
The main could go like this...
public class Application{
public static void main(String[] args){
InterestedClass interested = new InterestedClass();
Worker worker = new Worker();
worker.setDataFetchedListener(intereseted);
worker.start(); // Starts Worker's thread
}
}
When the Worker will fetch the data then it will notify its listener (currently the interested object) and the listener will act accordingly (interested will print the data to the console).
In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information.(Wikipedia)
You may wish to respond to some events either system events or user events. But for that you need to know when the event you wish to capture occurs and also what must be done at that time.
And for that you open a confidential EAR to listen to events. But that will not be sufficient since you need to be notified too so that you can reply according to the event. You set callbacks that will notify when an event occur. Those empty body methods we create inside an interface.
A Listener is that interface that hears and notify back through callbacks.
So how can all that be used? And how all these do interact?
First create an interface with empty bodies methods that you intend to call when an event occurs:
public interface MyListener{
void actionOneHappens(Object o);
void actionTwo();
void actionThree();
}
Create a class that handles something, for example counts:
public class MyCounter{
//create a member of type MyListener if you intend to exchange infos
private MyListener myListener;
//let's create a setter for our listener
public void setMyListener(MyListener listener)
{
this.myListener=listener;
}
MyCounter(){
}
//this method will help us count
public void startCounting()
{
new CountDownTimer(10000,1000)
{
#Override
public void onTick(long millisUntilFinished) {
//I want to notify at third second after counter launched
if(millisUntilFinished/1000==3)
{
// I notify if true :
//as someone can forget to set the listener let's test if it's not //null
if(myListener!=null){
myListener.actionThree();
}
}
}
#Override
public void onFinish() {
}
}.start();
}
}
You can then create an object of type MyCounter and know when it's at three:
MyCounter myCounter=new MyCounter();
myCounter.setMyListener(new MyListener()
{
//then override methods here
#override
void actionOneHappens(Object o){
}
#override
void actionTwo()
{}
#override
void actionThree()
{
//Add you code here
Toast.makeText(getApplicationContext(),"I'm at 3",Toast.LENGTH_LONG).show()
}
});
//start your counter
myCounter.startCounting();
And it's done!! That's how we proceed.
Interfaces have no implementation and for using them we have two options:
A class that implement them
An anonymous class
And consider this code:
interface TestInterface {
void doSomething();
}
class TestClass{
private TestInterface ti;
public TestClass(TestInterface ti){
this.ti = ti;
}
public void testActionMethod(){
ti.doSomething();
//some other codes
}
}
class OurOwnLauncherApp{
public static void main(String[] args) {
TestClass tc = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Hi!");
}
});
tc.testActionMethod();
TestClass tc2 = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Bye!");
}
});
tc2.testActionMethod();
}
}
In here we have:
An Interface (Just like what you asked)
A function class the uses that interface
An application somewhere that we don't know (Maybe your phone app, maybe your friends phone app, etc)
What this code does, it gives an anonymous class (which implements TestInterface) to the testActionMethod and with calling doSomething method inside testActionMethod, we invert the calling back to our own method. that's why you will see this result:
Hi!
Bye!
This is exactly a simplified version of listener interfaces and how they work
There is no magic thing. Generally, the event-listener mechanism is as follow:
For some entities, there is the possibility to listen to some events on that entity (let name this entity as event generator). So some way should exist for other entities to listen to these changes (let name these entities as listeners). Now a listener registers itself as a listener of event generator. When an event occurs on the event generator, it calls the related method of registered listeners.
As a simple example assume a button. The button may generate an event for some actions such as click. Now if a listener wants to aware when the button is clicked, it should register itself as a listener of that button. On the other hand, the button should provide a unified way of registering the listeners. This unified way is the interface. Each entity which implements the interface could register itself as a listener for click on that button:
1- Listener implements the interface
2- Listener registers itself as a listener of button (Event Generator)
3- Event Generator calls the appropriate method of all registered listeners (this method is a method of the interface).
For your case, android provides a manager which you could register a listener on some sensors by it: android.hardware.SensorManager.registerListener(). All things occurs here (which is not magic!). When you register an entity (which implemented the related interface, SensorEventListener) as a sensor listener, changes in that sensor will cause to call methods of the listener).
I have a set of subscribers that need to start when server starts up.
Right now I'm instantiating them and calling run method on them in Application.java.
Was thinking it would be wonderful if these get instantiated on their own, may be using custom annotation or by belonging to an interface (get all classes of interface and instantiate). This way anyone writing a new subscriber in future doesn't need to create the object and call run() on it.
Wondering if anyone has solved it earlier and whether it makes sense to do it.
Example:
I have an interface for event handlers:
interface EventHandler {
void process(String data);
}
And then implementation classes:
public class CoolEventHandler implements EventHandler {
public void process(String data) {
//handle cool event
}
}
public class HotEventHandler implements EventHandler {
public void process(String data) {
//handle hot event
}
}
And I have a subscriber service which listens to remote APIs and if there's data, it passes that to handler:
public class PollService {
public static void register(String API, EventHandler eventHandler) {
//create a thread to poll API
//and if data is received, call eventHandler.process()
}
}
At the start of my application I'm registering handlers in Application.java
PollService.register("/cool", new CoolEventHandler());
PollService.register("/hot", new HotEventHandler());
Tomorrow if there's a new handler, say WarmEventHandler, I'll have to call register again. I'm trying to avoid this last step. What would be the best way to register all classes of EventHandler?
I am sending an object called event inside my application but to another process.
I am using IPC EventBus. When I register I cannot receive events back.
This is what I am doing:
public class UserActivity extends Activity
implements IIpcEventBusConnectionListener, IIpcEventBusObserver {
#Override
public void onConnected(IIpcEventBusConnector connector) {
connector.registerObserver(this);
}
...
}
How can I receive the events?
Are you calling conn.startConnection();? If you don't then it will not work.
IIpcEventBusConnector conn =
ConnectorFactory.getInstance().buildConnector(context, this, "com.myapp");
conn.startConnection();
My server aperiodically receives join requests from new clients. Upon receiving a new join request, the server runs a service that can be finished real quick. I implement the service as a Java class (called JC) implementing the Runnable interface. I have parameters within the JC class.
At the caller side, I like to have only one instance (or static) of the JC. My question is how to trigger the run() method in the JC every time. Please show me some code. Thanks.
Hope following edits make sense, which is my current implementation.
In the Server that wants to trigger thread executing:
public class Server {
private static RealService mm = new RealService();
private static void update(){
new Thread(mm).start();
}
}
In the Service class:
public class RealService implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
// Do something
}
}
You're question is not really clear here, but I would suggest reading about TimerTask in Java
You could use a socket to listen for incoming requests, the server can spawn a new thread each time there is a request. Once the thread completes, you should intimate the client.
You could read about how a concurrent server works.
say I want to perform an Http request from the server, this process takes time.
now because of this, the http request needs to be run on a different thread (AsyncTask, Runnable, etc.)
but sometimes I just need the response when I ask for it, in order to update the UI
using Thread.sleep in a loop to wait for the response is not good performance wise
example: I want the user's name, I ask the server for it, and I have to wait for it
now the activity calls the UserManager that calls the serverHandler that performs the operation and returns the result back
maybe an event system is in order, but I'm not sure how to do this in my scenerio
and quite frankly I am really confused on this issue
please help someone?
This can most definitely be done w/ AsyncTask... Handle the network request in doInBackground() and once doInBackground() is finished, onPostExecute() is triggered on the UI thread and that's where you can execute any code that will update UI elements.
If you need something a bit more generic and re-usable, you would probably want to implement a callback... I'll refer to the UI thread as the client and the AsyncTask as the server.
Create a new interface and create some method stubs.
public interface MyEventListener {
public void onEventCompleted();
public void onEventFailed();
}
Have your client pass instance of MyEventListener to the server. A typical way of doing this is to have your client implement the interface (MyEventListener) and pass itself to the server.
public class MyActivity implement MyEventListener {
public void startEvent() {
new MyAsyncTask(this).execute();
}
#Override
public void onEventCompleted() {
// TODO
}
#Override
public void onEventFailed() {
// TODO
}
}
On the onPostExecute of the server, check if the callback is null and call the appropriate method.
public class MyAsyncTask extends AsyncTask<Void, Void, Void> {
private MyEventListener callback;
public MyAsyncTask(MyEventListener cb) {
callback = cb;
}
[...]
#Override
protected void onPostExecute(Void aVoid) {
if(callback != null) {
callback.onEventCompleted();
}
}
}
You can read more about callbacks here: http://www.javaworld.com/javaworld/javatips/jw-javatip10.html