As documentation we must cast Activity to Interface in onAttach() to communicate between Fragment-to-Fragment.
OnHeadlineSelectedListener mCallback = (OnHeadlineSelectedListener) activity;
After this we can implement that interface in Activity class and use it's methods.
But, i want to know that, as that interface is implemented by Activity class.
Then, why don't we instantiate it in Fragment onAttach() like below:
OnHeadlineSelectedListener mCallback = new ActivityClass();// After this all methods are also available in fragment class.
Using this way we can also pass the data by using Interface methods. But, why don't we use this?
Thanks.
You cannot create a new instance of an Android component (Activity, Service, BroadcastReceiver, Provider) using the new keyword. Only the Android framework can create these components, because they need to have their Context set up by the Android framework during construction. Although the compiler will let you do this, and your code will run, at some point you will get crashes because the methods in these components always assume that they have a valid Context.
Related
What is the advantage of using an interface to communicate from a fragment to an activity, as described here: http://developer.android.com/training/basics/fragments/communicating.html
This creates an unecessary dependency when we could have created an "onArticleSelected()" method in the activity WITHOUT THE INTERFACE and called it in the fragment via getActivity().onArticleSelected().
What if the activity, at another point in time contain a fragment where there are no articles, why create this illogical dependency and add more code?
Using an interface actually removes dependency on a specific Activity class. It allows the Fragment to work with any Activity that implements the interface, not just a single Activity.
I have noticed that I can create a callback by using two methods:
Receive an interface at the constructor of the class implementing the callback.
Receive the activity itself at the constructor of the class implementing the callback.
First Approach
For example I could do this:
public MyClass(MyInterface listener) {
this.listener = listener;
}
And I could call myCallBackFunction() defined in MyActivity (which implements MyInterface) by writing listener.myCallBackFunction()
Second Approach
Or I could do this:
public MyClass(MyActivity activity) {
this.activity = activity;
}
And I could call myCallBackFunction() defined in MyActivity by writing activity.myCallBackFunction()
My concern: Is one approach better than the other? And if so, why?
Usually speaking, you'd better use first approach. The reason is here:
Suppose you have 4 classes, first is Vehicle, second is Bicycle, third is Bus and third is Subway. Bicycle, Bus and Subway are subclasses of Vehicle. There may be a method call drive(), which should have a parameter. Which one do you think best for parameter type? Bicycle, Bus, Subway, or Vehicle?
Apparently, passing Vehicle is best because you may want to add other kinds of vehicles in the future or you don't want to write nearly same code for different kinds of vehicles in your project. It is same to use Interface rather than specific class.
As a result, passing an interface to a method is always correct and better than passing a specific type of object to it. You can always implement the interface in other classes and they will also be parameter of that method. You don't need to think about actual type of the parameter, which will confuse you and make you think more about specific code for specific type. Instead, only one type, one piece of code macroscopically.
So the conclusion is: using MyActivity is good, but using MyInterface is better.
I think it can depend on what you're trying to achieve: the first approach may in general be better suited since MyClass is not required to know anything about the implementation of that interface method, so it's great for passing different objects (e.g. a RecyclerView Adapter being created with an OnItemClickedListener injected in the constructor can be re-used in different activities/fragments implementing the interface, whilst the adapter doesn't need to change). It helps to prevent coupling.
The second approach leaves one wondering: is MyClass tied to the activity lifecycle? It may still hold a reference to the activity after that activity has actually been destroyed by the system, which would leak memory as the Activity object is not garbage-collected. It's a matter of design, and can be seen as code smell, can you not achieve what you wanted within the activity itself, and rely on the lifecycle callbacks onCreate/.../onDestroy?
Is one approach better than the other? And if so, why?
Using Interface is the best way..
Assume that you are having
1) Activity MyActivity
2) class which extends Activity or View or Asynctask is Myclass.
Both MyActivity and Myclass are Implements MyInterface
If you are passing Activity you need to add one more constructor
public MyClass(MyActivity activity) {
this.activity = activity;
}
public MyClass(Myclass myclass) {
this.myclass= myclass;
}
If you are using interface
public MyClass(MyInterface listener) {
this.listener = listener;
}
that's it.
In one approach you are creating an instance of Interface and in another an instance of implementing activity. what is best is:
Interface interface;
public myClass(Activity acitivity)
{
interface = (Interface)activity;
}
i.e. typecast activity to interface. Now you can callback the overridden functions in Activity.
This way you can now loose information of Activity's functions and just access the overriden functions of interface from the activity.
You can avoid typecasting and create an object of Activity, if you need access to interface callbacks AND the activity's function/variables.
It depends on your needs.
I am new to the world of Android Programming,Here is my question.
Suppose I've an Activity named A and a Fragment named F. I know that the interaction between Activity and Fragment should be done through an Interface. I used to set the Interface in the onAttach() of Fragment like this
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mListener = (MyListenerInterface) activity;
}
and now am heard about the Static Factory Method from here.
My question is : Which is the best approach to init. a listener ? onAttach() method or initialize the listener through the static factory method ,like this?.
public static MyFragment newInstance(MyListenerInterface mListener) {
MyFragment f = new MyFragment();
this.mListener = mListener;
...........
return f;
}
I think, it is better to initialize the listener through the static factory method instead of casting from the activity,so we could avoid a null pointer exception.
Yes you do not need to cast anything via factory, but onAttach is better in my opinion because you have less chance of leaking an activity context. Let's say you make an instance with the factory and never use that fragment, it will leak the context of the Activity and there by everything in it. Also don't forget to destroy the interface in the onDetach.
Also you can have many instances of that fragment and with option one, they will all have the same listener, not good.
Also you should make what you could call a BaseActivity, an abstract activity all other extend from and define the interface methods there and you will avoid always casting to a lot of different classes. This will also come in handy if you need to quickly change something in every activity of your app.
First option (Initializing the listener in the OnAttach()) is a better one because
In first option the MyListenerInterface is an non-static variable, so each fragment has its own listener.
Whereas the second option's MyListenerInterface variable is an static that is reference maintained at the class level and common for all the other fragment instances this causes the problem when you need the same fragment in different activity then the listener of one activity will be overrided with another activity.
I wonder what way to call for parent's(Activity) function is the proper way to go, I have a activity which starts a fragment, from this fragment I want to call aFunction() in MyActivity.
is:
((MyActivity) getActivity()).aFunction();
or simply create an interface:
public class aFragment extends Fragment {
OnExampleListener mCallback;
// MyActivity must implement this interface
public interface OnExampleListener{
public void aFunction();
}
}
the best way to go about doing this?
It's not per se wrong, but it's discouraged as it makes your fragment dependent of the activity, which isn't the case if you're using interfaces. Use it for testing purposes, if you're serious about writing apps, use an interface.
Read the section about Fragment to Activity communication here to use interfaces: http://developer.android.com/training/basics/fragments/communicating.html
I have an application, which is including a library which exposes set of methods via a public class. Internally, this library uses the context passed on to it by the application.
Question: Since the public class in the library does not extend Activity, the methods use the Context object passed on to it by the application. In this case how to communicate the result/data back to the application? The context object does not have startActivityWithResult() method.
Any idea?
There is no any method like startActivityWithResult() for Activity, the method is startActivityForResult().
If your context is Activity reference then you can use startActivityForResult() method in that class. just use like,
((Activity)context).startActivityForResult();