What's the difference between 'this' and 'getActivity()'? - android

I have an idea they both get the 'context' so that functions know how they fit into the scheme of things, is this right?
Any clues for the evolving ape?

this is a reference to the current class you are. It can be an Activity, Fragment, Adapter, View, etc. And when you use it what you are doing is just passing a reference of the current object of that class.
Let's say you are working on a custom View. Anywhere in the code of that view where you call this will be interpreted as the View itself, so the value of this changes depending on what class you are.
The method getActivity() is defined only in the Fragment class and any other class extending Fragment and this method returns and Object of the type Activity.
On Android development is very common mixing those two because most of the applications code is in Activity classes, and calling this on an Activity class will return an Activity object but as you can see they are not the same thing.
You can read more here

Related

What is the best way to know in activity method which fragment is calling that method

I have a common method to get image from gallery in activity which is accessed by different fragments what is the best way to know in activity method which fragment is calling this method so that I can put appropriate conditions.
I have tried by passing a string in fragment but is there any other clean way
Blockquote I have a common method to get image from gallery in activity which is accessed by different fragments what is the best way to know in activity method which fragment is calling this method so that I can put appropriate conditions.
Could you provide more details on what you are trying to achieve?
If I got it right, you have a method in your Activity that is accessed by different fragments. Is it right? If yes, then there is a high chance that it is not correct. Let me elaborate on this: by letting fragments invoke a method inside the hosting activity you are coupling them to the activity. What if you need to attach the same Fragment to different activities? Anyway, this is not always the case. For example, if you already know that these fragments will always be used with this particular activity, then it is OK.
In general, the communication between activities and fragments is achieved by means of interfaces to allow components to remain decoupled. I higly reccomend you to read the official docs on the topic here.
Anyway, if you want to have such function, and you are using Kotlin, you could exploit reified parameters. For example, in your activity you could have:
inline fun <reified T> invokerName() = T::class.simpleName // Do something with the class
that you can invoke this way:
activity.invokerName<Foo>()
you can pass the Fragment class like this :
(requireActivity() as YourActivity).method(this::class)
and in your activity take all available information about this class :
fun method(comesFromClass: KClass<out Fragment>) {
val simpleName = comesFromClass.simpleName
...
}

Define MainActivity as static variable in order to access findViewById method

While I was coding, I wanted to use findViewById method to find a view that cant access in the current view but can be accessed via the MainActivity. So two options came to my mind. One is creating a static method from that object in the MainActivity class and access the static object. The second method is to create a static object form MainActivity class itself(this) and access the findViewById method by calling the static object. Please answer the method I should use.
And apart from that, it got me thinking that whether an Android developer should come across this type of scenario or whether I have done some improper coding to access findViewById method in MainActivity while I was in a different view.
You can take a look at the code in the below repo.
https://github.com/chrish2015/ExpenseTrackerLatest
Thanks
If you are inside a class that is neither a Context nor an Activity and you need to use a method which exists inside the activity or context, then simply pass the activity as a parameter to that class and take an instance to that activity inside your class.
public class MyAdapter extends ArrayAdapter { // this is not activity
private Activity mActivity; // activity is a member of this class.
public MyAdapter(Activity activity, List<String> data) {
mActivity = activity;
}
public View getView(...) {
// if you need to use findViewById:
View view = mActivity.findViewById(R.id.some_id);
}
}
Don't use any of your two methods.
I might be misunderstanding your first sentence, but just to be sure, are you asking for a way to access a View that exists in the MainActivity, while you're inside of a Fragment?
If that's what you're asking, then yes, as an Android Developer, there will definitely be moments where we come across this scenario. However, the solution is definitely NOT by making your Views or Context static.
This is one of the easiest ways to cause bugs to appear throughout your app, with a very high chance to cause memory leaks too. Here's an Article from Google talking about memory leaks related to keeping a reference to a Context: https://android-developers.googleblog.com/2009/01/avoiding-memory-leaks.html
Rather than your two options, there are better solutions that developers typically use.
First of all, keep in mind that you should NOT be directly accessing any Views from outside of your current layout... meaning, that if you're in a second Activity, you don't directly access Views from the first Activity, or if you're in a Fragment, you don't directly access Views that belong to it's FragmentActivity.
Instead, you let the Activity or Fragment handle it's own Views.
So for example, if you're in another Activity and you want to update some data in the previous Activity, you can take advantage of an Activity's startActivityForResult() and onActivityResult() to obtain the data necessary to update the Activity immediately upon returning to the app.
For Fragments, there's actually a tutorial from the Android Documentation that describes a very good way to communicate between other Fragments: https://developer.android.com/training/basics/fragments/communicating
This method is to use interfaces as a callbacks, so another Fragment or the Activity will be able to receive data and update it's Views within it's own layout.
So for your case, if you're using Fragments and an Activity, you can easily have your fragments and activities communicate to each other in a safer and more reliable way.
Also, make sure you read up more on static and it's effects on your code, especially the side effects on Android components. Do not carelessly use static without considering some of the effects it might cause, because that would cause an endless amount of trouble to your code.

The right way to pass an object to fragments?

I want to pass an object to fragments
when the object shouldn't or can't recreate in a fragment (e.g. LruCache).
Is it possible without using static variable?
since passing variable may not always same object
Edit:
To make it clear I don't want the object to be null when activity recreated
For passing object to fragment you should use interface have a look at this link.
You can pass object via constructor and getter and setter also but in case of app resume object might be null that will cause NullPointerException on app resume.
Edited
If you are working with LruCache and want to share its data within fragments. I will suggest you to create a fragment without a onCreateView() method, means it will be invisible fragment. Implement a LruCache object in fragment and have getters and setters to get and set desired objects from LruCache.
Fragments have a characteristics of re-usability in contrast to a simple class. You can find a fragment by its tag.
For example: To add a fragment-
activity.getFragmentManager().beginTransaction().add(fragment, TAG).commitAllowingStateLoss();
and to get a fragment-
activity.getFragmentManager().findFragmentByTag(TAG);
In contrast to normal class Fragment class is removed from memory only when device is in sort of memory. Whenever fragment is null you will have to re-initialize it.
To know more about its implementation details visit this link

Android : Accessing container activity object from fragment using putExtra?

I am building a tab interface using Action bar and fragment. I would need assistance in sending data from container activity to the fragment.
To elaborate, I have job object in container activty. And I have created few tabs based on the information in job object (like company details, experience details etc). I need to pass the job object to these fragments so that it can display respective information.
I have created container activity and tab fragments. I would need an example on how to pass the object across them. I cannot use intent.putExtra. Can I access parent container's object from fragment?
Any help shall be appreciated.
Thanks.
Make the method in your activity, e.g getJob that will return the Job object and its information
MyActivity extends Activity{
Job mJob;
public Job getJob(){
return this.mJob;
}
}
then in your Fragment you do this:
MyFragment extends Fragment{
#Override
public void onActivityCreated(){
super.onActivityCreated();
((MyActivity)this.getActivity()).getJob();
}
}
use getActivity and the method getJob(); to get the object
There are multiple ways of achieving this.
Make a static variable to hold your data and access that data from inside the fragments - this is the most fast but it creates bad design patterns if used improperly.
A way of Fragment-to-Fragment communication possible through the parent Activity is posted here: http://developer.android.com/training/basics/fragments/communicating.html You can use the sample code to just do a Activity - Fragment data send.
The top voted answer here: Accessing instance of the parent activity? mentions a way to avoid using static data (1.) and contains source code examples using ActivityGroup
"If you need access to some values in your First activity without
making a static reference to it, you could consider putting your
activities in an ActivityGroup."
What you choose is your preference, these are just a few options!
Edit: I'm not sure if number 3 will work with fragments since I haven't tested a method similar to it, the example is Activity - Activity communication.

Reuse fragment structure and passing complex arguments

I have implemented a DialogFragment class which shows a dialog and call a custom listener when its button is pressed.
Since I want to reuse this class in many projects I need to pass the listener when I create the fragment. However I don't know how I could do it.
I know I should not pass the listener in the constructor because Android could call the default constructor if it has to recreate the fragment and I cannot pass the listener via Bundle arguments because Bundle does not support it.
The unique solution I found is make the activity implement the custom listener and check it in onAttach method. The problem is that this way would limit the implementing classes to the owner activity and maybe it does not fit to the application.
Does you find a better solution?
Thanks!
You normally have a static newInstance() method to create your fragment and pass in any values your fragment might need. That's the method to pass your listener to.
Have a look here where a newInstance() method is also used as an example:
http://developer.android.com/reference/android/app/Fragment.html

Categories

Resources