I'm trying to Subscribe and Post from the same fragment, but I'm getting this error when i try to register the fragment:
...(my method) has #Produce annotation but requires 1 arguments. Methods must require zero arguments.
on
BusProvider.getInstance().register(this);
So i guess it's not possible, but maybe there is an alternative without additional interfaces.
Thanks in advance!
Methods annotated with #Produce must not take any arguments. They should just return the event object.
"I'm trying to Subscribe and Post" suggests you probably need to change it to #Subscribe annotation instead.
For posting events, just use post(). #Produce is meant for returning the latest value of an event.
Related
Recently I've been reading aboout data binding in android. I get how this could be useful in updating the ui but what is the advantage in event handling? Assigning in XML android:onClick to a method in activity seems to me like a same thing to just with less code.
When should I use which?
Assigning in XML android:onClick to a method in activity seems to me like a same thing to just with less code
First, android:onClick only works with an activity. Using data binding for event handling allows you to route that event to some other form of controller or presenter (e.g., a fragment).
Second, android:onClick only works with that event. Using data binding for event handling allows you to handle other sorts of events, replacing OnLongClickListener, OnTouchListener, etc.
Third, android:onClick only routes to a method, with a fixed list of arguments. Using data binding for event handling allows you to use Java 8-style lambda expressions to route to methods with a different roster of parameters, including variables that you may have injected into the layout (e.g., the RecyclerView position associated with this layout).
When should I use which?
If you are bothering to use data binding, use it for event handling where practical. Data binding is useful for larger projects, and on those projects, you may find the features I listed to be useful.
If you are not using data binding in a project, use android:onClick.
I have a problem regarding viewing & following method calls in the android source code when Parcels get involved.
I wanted to find out more about the inner workings of PendingIntents by checking out the Android source code, but just when things get interesting, Parcels pop up a few ambiguous functions are called, and the important bit is over.
I belive specifically the following lines in the send() method of IIntentSender is important:
mRemote.transact(Stub.TRANSACTION_send, _data, _reply, 0);
This is where I get lost. How can I track down the method which is called next? Trying to view the source of transact method just reveals an interface with no code!
The type of mRemote is android.os.IBinder (an interface again)
Thanks for your help in advance!
(P.S: I used grepcode.com to inspect the source code)
The Binder is just the "guts" of an inter-process function call. Providers, Intents, and Messages are actually just abstractions of the Binder protocol. There is a lot of information out there about the Binder protocol, however it is designed so that most people don't have to worry about it.
When you call functions such as getActivity() you are acquiring an intent object that will be used later, but when that time comes, it uses the binder to do its job.
This is all to say, you've gone too far into the "guts," and need to take a step back. The Binder is literally used everywhere and is just a generic way to communicate. Whatever is on the other side of that .transact call is dependent upon the means in which the Binder (or in this case, the PendingIntent) was acquired.
Try to deduce what component would handle an intent of your particular variety, and look for a .transact method in its code. This will usually take the form of a huge switch statement that calls different functions based upon .transact's first argument. Whatever the case block calls will be what is "interesting" to you.
In your case TRANSACTION_send makes me think of finding some activity with the capability of "sending" something. Well, this sounds like a job for the ActivityManager. This code can be found here. Check out the onTransact method for some potential breakpoint positions.
I am developing an application in which I am using retrofit library for calling the web services . After calling web-service a callback return Response then I am passing the Response to the next activity. I want to know the best approach for this .
I am new in memory related problems please correct me if I am totally wrong.
Shall I make a new class then pass a weak reference to that class and call the function from that class on the main activity.
Or
I shall register a new event on event bus and when the callback returns the object ,fire the event and call the function.
Please consider what is good to avoid Memory Leaks.
Saving callbacks/listeners in weak references is not a good idea. See
Pros and Cons of Listeners as WeakReferences
Are anonymous listeners incompatible with weak references?
You can "broadcast" results of asynchronous operations (Network calls in your case) on completion using event bus, and have other objects (Views, Fragments, Activities) register to event bus. Points to note:
Listeners must always un-register properly, else its a memory leak.
You'll need to create a new class for each event type. Soon this number will grow.
Inheritance and Event bus do not play well. There is no proper "overriding" of listening methods possible.
Perhaps some other object also requested the same data. Since EventBus broadcasts to all, listeners might get multiple events of same type, at unsuspected timing.
Particular to Retrofit usage, if you do requests asynchronously as:
GitHubService service = retrofit.create(GitHubService.class);
Call<List<Repo>> repos = service.listRepos("octocat");
repos.enqueue(myCallback)
Then you must remember to cancel all calls that a component has made, when the life-cycle of component is complete. I.e onDestroy() of Activity, onDetach() of Fragment, onDetachFromWindow() of View:
repos.cancel();
I'm trying to pass an event from a fragment to a dialog using otto. Unfortunately by the time the dialog is created the event has already fired and the #Subscribe method in my dialog and the data that was being sent gets passed over.
The data I'm trying to pass is an Object and an index (Best case) or a String (worst case) from a listview/ArrayList.
I know they have an #Produce method; but I don't understand how a method that takes no arguments helps in anyway or how I can get it to work.
Here's an example they provide
#Produce public AnswerAvailableEvent produceAnswer() {
// Assuming 'lastAnswer' exists.
return new AnswerAvailableEvent(this.lastAnswer);
}
For my newly created dialog this.lastAnswer; won't exist, it can't - that's what I'm passing in.So how do I get around this?
Side note:
I think the event bus, in it's current form is a bit of overkill since it's only communicating with my dialog. Later on I hope to use the event bus in more dialogfrag/fragment communication.
I've also asked same question for myself, when I was investigating Otto. And decided to read their site(http://square.github.io/otto/) more thoughtfully.
Here is their description under #Produce annotation:
...
Producers, like subscribers, must also be registered...
When registering, the producer method will be
called once for each subscriber previously registered for the same
type. The producer method will also be called once for each new method
that subscribes to an event of the same type.
You may only have one producer per event type registered at a time on
a bus.
So I think in time you register your producer, "lastAnswer" should be initialized.
And no parameters needed because you don't suppose to call your producer-method by yourself.
I hope it will help.
should I call super.xxxx() before my custom code or after when I override a method?
Is there some skills to Identify?
The short answer: It Depends.
The long answer:
You need to understand what the implementation of the method in the parent class does.
There are cases when the super method does some "initialization" work required for the overridden method to function smoothly. In such cases, the super.myMethod() call should be the first line in the method.
In some other cases, the implementation of the method in the parent class could be responsible for some clean up (or some sort of finalization) operations. Thats when you would need to make the call to super the last line in your overridden implementation.
Then there are situations where the order doesn't matter, but you must call the super method because the implementation in the base class performs some operation which are necessary; although the order of these operations doesn't matter. Most of the Activity life cycle methods fall in this category. Which is why you must call though to super.onCreate() although you can do it at any point in your onCreate().
Finally, there are also cases where the call to the super method is not required. The base class has a default implementation which you may choose to use or ignore. You might also end up doing an if-else here: For instance, you might call through to the super implementation. If it returns a null, you might create a new object and return that instead.
Is there some skills to Identify?
Read the method documentation and see if there is any mention of the order in which the super method must be called.
Go through the source code of the base class and see if you can figure out whether it does anything that necessitated calling it in a particular order.
(Very OOPy) generally, the idea is to call super just when you need a parent's functionality. I know it seems pretty obvious, but it has implications when it comes to cleanup functionality:
Init:
super.init
... your initialization code
Delete:
... your deletion code here <-- important
super.delete
SomeOtherRandomMethod:
... your code may go here if it does not need any state from the parent
super.SomeOtherRandomMethod
... otherwise it can go here
I find it's just simpler / cleaner to just call super's code at the beginning of an override (unless there's some really specific reason not to), and just make sure that I call the parent's destroy/delete/free/destruction after I've done my own cleanup (we definitely don't want the parent dumping the object out from under us!)