Here is what I use to trigger method on MainActvity.java from my Fragment page:
((MainActivity) getActivity()).openGallery();
Once I get to slide in the fragment page for the first time after opening app, and execute this code, IT WORKS. But, when I hide that fragment page and then bring it back, and execute that code again, the app crashes, saying something like:
Attempt to invoke virtual method 'void com.test.test7.MainActivity.openGallery()' on a null object reference
None of the answers I found cover this problem, when it works for the first time and the crashes at the second time.
Any help is apreciated.
try this.
if(getActivity()!=null){
((MainActivity) getActivity()).openGallery();
}
try to use context of that fragment and do something like
((MainActivity) mContext).openGallery();
You can refer to the documentation under Section "Handling the Fragment Lifecycle". Basically somewhere in your code you called ((MainActivity) getActivity()).openGallery() while the fragment is not attached to activity, hence parent context return null.
You should not assume that activity context is always available because more often than not the fragment gets detached and reattached again. You should
(if context is necessary for you) only call getContext() in methods where fragment is guaranteed to be attached (see previous link on available fragment callbacks), or
always perform a conditional check to ensure (MainActivity) getActivity() is not null before use.
Related
In my application I create a fragment with the keyword new and set it by FragmentTransaction.
Upon rotation a stumbled upon a NullPointerException in the method onActivityCreated() indicating a missing injection, that I do after the call to new. I suspected the fragment was not created by my code und proved this by logging the hashCode(). It looks like a fragment is created automatically by the system upon rotation.
Where does it come from?
Is it created by the fragment manager?
How am I supposed to use it correctly?
How can I access it, to set the missing value?
For now I ignore it by testing for the null value, in which case onActivityCreated() does nothing. Instead use the fragment I create with new. However, this does not feel very satisfying, to throw away an object, that was already created.
Where does it come from? Is it created by the fragment manager?
On Activity recreation, Android will restore the fragments which already exist in activity's fragments manager
How am I supposed to use it correctly?
public void onCreate(Bundle savedInstanceState){
if(savedInstanceState == null){
//activity is created for first time
//commit the fragment
}else{
//Activity is recreated(by means of rotation or something else)
//Dont commit the fragment, fragmet will be restored by the system
}
}
How can I access it, to set the missing value?
Normally, you have to handle this inside the fragment using onSaveInstanceState method. You can get the fragment instance by using, getSupportFragmentManager.findFragmentById(R.id.container) or getSupportFragmentManager.findFragmentByTag(tagName)
android.app.Fragment android.app.FragmentManager.findFragmentByTag(java.lang.String)'
on a null object reference
I had found numerous posts with this issue here on SO, but none of them helped me.
It happens relatively rarely (1/100). The place where I call the getFragmentManager() is on the main thread, when a button is clicked :
My flow is simple , first I have fragment A, then add on it several fragments until I get to fragment X.
Once a button is clicked in a custom view class that is instantiated and held in the fragment X, I call :
fragment A.getInstance().showLoadBar();
in fragment A the showLoadBar calls a fragment just for displaying loading, and it uses the getFragmentManager() there.
Most of the time it works great, and I am not able to recreate this crash. But I can see that this crash does happen sometimes.
I am new to Android and learning to create fragments in Android by following this
example: Fragment Navigation Drawer
The code between Navigating between Menu Items and Add Navigation Header consists a method getActivity().
As the author didn't mentioned where to paste this code, I pasted in my MainActivity.java file
Is code between Navigating between Menu Items and Add Navigation Header pasted at correct location by me?
In method selectDrawerItem(MenuItem menuItem) there is a comment // Create a new fragment and specify the planet to show based on position
Does author expects me to add something over here.
The project files layout created by me on AndroidStudio is as follow:AndroidStudio Snapshot
You can use:
this Or `MainActivity.this`
Instead of:
getActivity()
An Activity has no getActivity() method.
Fragments have.
Because getActivity() says: "return the Activity which contains me".
And while Framents are contained in Activities, Activities themselves aren't.
It has been clearly pointed out that you cannot use the getActivity() method in an activity. Well, other alternatives apart from the this keyword could be;
Get current activity context : using the getContext()
This method can be called on a View like text view like so textView.getContext(); This will give the context of the activity in which the view is currently hosted in. i.e something like so View.getContext();
Get App-level context : getApplicationContext() this method returns the activity that houses the entire life cycle of the application.
In Fragment it is best to use onAttach() method to get the instance of an Activity attached to it.
here is a sample code:
#Override
public void onAttach (Activity activity) {
super.onAttach(activity);
}
I have been reading very much about the nested Fragments onActivityResult issues.
I got the next conclusions.
1) At the Fragment, should call this.startActivityForResult() instead of this.getActivity.startActivityForResult()
2) Overwriting onActivityResult() at the parent Activity calling super.onActivityResult() to propagate the response through fragments.
Until here, the normal way to configure onActivityResult in Fragments.
But I use one implementation of nested fragments. Then I should do some more steps.
3) Here we can see the full process.
First, all my fragments are in root level, doesn't exist another fragment levels.
Then, to try solved the problem, I extend this fix Activity in the main Activity.
CommonActivity
Here, only one difference, I've replaced ActionBarActivity by FragmentActivity.
4)Finally, in the result ListActivity I have the next test code.
Intent output = new Intent();
output.putExtra("pos", position);
this.setResult(Activity.RESULT_OK, output);
this.finish();
THE QUESTION, debbuging, I can see when this.startActivityForResult() is called from Fragment, CommonActivity.startActivityFromFragment(..) is working. But, when response is throw from result ListActivity CommonActivity.onActivityResult(..) never is called.
Why?, Where can be the problem?
When called startActivityForResult, results always go to the same Activity from where was called or to Activity the Fragment was attached to(your case), so you can try Override onAttach (Activity activity) - function of Fragment, and see to which Activity was attached the Fragment.
Or other way to call startActivityForResult as public function of CommonActivity, so results always will go to CommonActivity.onActivityResult. Good Luck with that!
An Activity may inflate an arbitrary layout xml that may or may not have a Fragment placeholder in it.
If it does , the Fragment will be instantiated and attached to the Activity.
Is there any way to get a reference to the Fragment from the Activity that has been attached to it ?
FragmentManger.findFragmentById() assumes you know the ID in advance to make it work but in this situation I am proposing, it is not available.
The behavior I'd ideally like to have is that the Activity is aware of any Fragments attaching itself to it so that it may respond to it.
Whenever a fragment is attached to an activity the following callback method is called with the fragment attached as the parameter, you can use it store the reference.
onAttachFragment(Fragment fragment)
http://developer.android.com/reference/android/app/Activity.html#onAttachFragment(android.app.Fragment)