getContext() is NULL for a certain fragment flow - android

2 Fragments & 1 Activity are involved. Here is the flow wherein I am able to reproduce the issue, along with relevant code snippets.
#1. From Frag1, open Frag2
Frag2 fragment = Frag2.newInstance(pos);
BaseFragment.addToBackStack(getContext(), fragment);
Here is BaseFragment.addToBackStack()
BaseFragment
public static void addToBackStack(Context context, BaseFragment fragment) {
FragmentManager fragmentManager = ((BaseActivity) context).getSupportFragmentManager();
android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(BaseActivity.getContainerIdForCurrentActivity(context), fragment);
transaction.addToBackStack(null).commit();
}
#2. Press Back to open Frag1 again.
#3. Open Activity A1 with startActivityForResult() from an Adapter in Frag1.
Intent intent = new Intent(context, Act1.class);
intent.putExtra(..);
intent.putExtra(..);
((BaseActivity) context).startActivityForResult(intent, Frag1.REQ_CODE_ISSUE_DONE);
#4. Go back to Frag1, either by pressing Back or finishing A1 with
setResult()
#5. onActivityResult() of Frag1 is called. But inside it, both getContext() and getActivity() are NULL.
Frag1
if (resultCode == Ac1.RESULT_CODE_OPEN_LANDING_SCREEN) {
if (getActivity() instanceof MainActivity) {
BaseFragment.replaceStack(getContext(), landingFrag.newInstance());
} else {
Intent intent1 = new Intent(getContext(), MainActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
}
}
If A1 is opened directly from Frag1, then getContext() is NOT null inside startActivityForResult() and works perfectly.
Logcat:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=792, result=135, data=null} to activity {in.shadowfax.gandalf/in.shadowfax.gandalf.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ComponentName.<init>(ComponentName.java:128)
at android.content.Intent.<init>(Intent.java:4449)
at in.shadowfax.gandalf.help.issues.IssuesFrag.onActivityResult(IssuesFrag.java:153)
at in.shadowfax.gandalf.help.HelpPresenter.triggerIssuesFragOnActivityResult(HelpPresenter.java:72)
at in.shadowfax.gandalf.help.HelpFrag.onActivityResult(HelpFrag.java:100)
at in.shadowfax.gandalf.MainActivity.onActivityResult(MainActivity.java:901)
at android.app.Activity.dispatchActivityResult(Activity.java:6428)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) 
at android.app.ActivityThread.-wrap16(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Instead of
((BaseActivity) context).startActivityForResult(intent, Frag1.REQ_CODE_ISSUE_DONE);
using
fragment.startActivityForResult(intent, Frag1.REQ_CODE_ISSUE_DONE);
solved the issue.
onActivityResult() inside Nested Fragments is now called in support lib 23.2. So no need to reroute the onActivityResult() from Actvity to frag manually as I was doing in my case.
Ref: https://inthecheesefactory.com/blog/onactivityresult-nested-fragment-support-library-v23.2/en

Related

How to fix 'Attempt to invoke virtual method 'android.support.v4.app.p android.support.v4.app.k.a()' on a null object reference'

I am getting this crash from multiple users when trying to get fragment manager. Any idea why the crash?
#Override
public void onNoInternetError() {
Log.i("base", "no internet error!");
final FragmentTransaction ft = getFragmentManager().beginTransaction();
final NoInternetFragment fragment = new NoInternetFragment();
ft.replace(R.id.content_frame, fragment, "noInternetFragment");
ft.addToBackStack(null);
ft.commit();
Error
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.p android.support.v4.app.k.a()' on a null object reference
at com.abc.abc.fragments.ABCFragmentBase$1.onNoInternetError(ABCFragmentBase.java:112)
at com.abc.abc.ui.components.NoInternetListener.showNoInternetFragment(NoInternetListener.java:14)
at com.abc.abc.ServerManager.handleFailure(ServerManager.java:1875)
at com.abc.abc.ServerManager.access$100(ServerManager.java:54)
at com.abc.abc.ServerManager$33.onFailure(ServerManager.java:1220)
at com.abc.sdk.JsonObjectRequest.deliverError(JsonObjectRequest.java:70)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:108)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
from your code it seems like the getFragmentManager() call is returning null which probably means your fragment hasn't gone through onAttach() yet
you can add a flag for connection error and then after onAttach() display the relevant information

Avoid IllegalStateException when doing popBackStackImmediate during onResume in fragment

I have a single Activity with fragments and two simple methods inside the activity for managing fragments: pushFragmentImmediate() and popFragmentImmediate().
public void pushFragmentImmediate(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commitNow();
}
public void popFragmentImmediate() {
getSupportFragmentManager().popBackStackImmediate();
}
These transactions must execute immediately because of legacy code which depend on the back stack being up to date at all times.
Now I have a Fragment which pops off during onResume if some condition is satisfied:
#Override
public void onResume() {
super.onResume();
if (condition) {
((Main) getActivity()).popFragment();
}
}
This gives an error.
Can this error be avoided without changing popStackImmediate() to popBackStack()? Or can I move popBackStackImmediate() to some other phase when it will not return an error? Or am I thinking about this in the wrong way?
Full trace:
java.lang.RuntimeException: Unable to resume activity {se.esillen.testproject/se.esillen.testproject.Main}: java.lang.IllegalStateException: FragmentManager is already executing transactions
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3433)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3473)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2736)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1481)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:179)
at android.app.ActivityThread.main(ActivityThread.java:6152)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.IllegalStateException: FragmentManager is already executing transactions
at android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:2167)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2223)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:834)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:794)
at se.esillen.testproject.Main.popFragment(Main.java:25)
at se.esillen.testproject.TestFragment.onResume(TestFragment.java:26)
at android.support.v4.app.Fragment.performResume(Fragment.java:2401)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1465)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3217)
at android.support.v4.app.FragmentManagerImpl.dispatchResume(FragmentManager.java:3181)
at android.support.v4.app.FragmentController.dispatchResume(FragmentController.java:214)
at android.support.v4.app.FragmentActivity.onResumeFragments(FragmentActivity.java:470)
at android.support.v4.app.FragmentActivity.onPostResume(FragmentActivity.java:459)
at android.support.v7.app.AppCompatActivity.onPostResume(AppCompatActivity.java:171)
at android.app.Activity.performResume(Activity.java:6856)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3410)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3473) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2736) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1481) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:179) 
at android.app.ActivityThread.main(ActivityThread.java:6152) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
 

Android - Fragment Transition issue

I currently am working on a newsfeed module where i have this issue of fragment transition.
Transition Example :
Newsfeed >a> Profile >b> Detail >c> Profile.
Newsfeed >a> Detail >b> Profile >c> Detail.
Every time i visit a page twice and tries to back again at "a". My app crashed giving nullpointerexception on
getActivity().onBackPressed();
in fragment. Each stack is poped in MainActivity in override onBackPressed. All flows are fine when there are no 2 of the same fragment transition in the backstack.
PopBackStack Example :
getSupportFragmentManager().popBackStack("profile", FragmentManager.POP_BACK_STACK_INCLUSIVE);
Let me know if you need more codes to help.
Any help would be appreciated.
Thank you!
Edit:
Logcat Error :
09-19 02:15:02.399 29778-29778/com.dbs.alive E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dbs.alive, PID: 29778
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.onBackPressed()' on a null object reference
at com.dbs.alive.ProfileFragment$1.onClick(ProfileFragment.java:171)
at android.view.View.performClick(View.java:5210)
at android.view.View$PerformClick.run(View.java:21328)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5551)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Main Activity (onBackPressed)
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
//this.finish();
super.onBackPressed();
} else {
for (int i = getSupportFragmentManager().getBackStackEntryCount(); i > 0; i--) {
String ide = getSupportFragmentManager().getBackStackEntryAt(i - 1).getName();
if (ide != null) {
//1. FROM NEWSFEED
if (ide.equals("newsfeed")) {
getSupportFragmentManager().popBackStack("newsfeed", FragmentManager.POP_BACK_STACK_INCLUSIVE);
break;
} else if (ide.equals("profile")) {
getSupportFragmentManager().popBackStack("profile", FragmentManager.POP_BACK_STACK_INCLUSIVE);
break;
}
Fragment AddBackStack
Fragment fragment = ProfileFragment.newInstance("", "");
Bundle mBundle = new Bundle();
mBundle.putString("profileid", postOwnerId);
mBundle.putString("profilename", postOwnerName);
mBundle.putString("profileicon", RealmHelper.getUserProfileUrl(postOwnerId));
fragment.setArguments(mBundle);
FragmentTransaction transaction = ((AppCompatActivity) activity).getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.newsfeed_layout, fragment);
transaction.addToBackStack("profile");
transaction.commit();

android.app.Application cannot be cast to android.support.v7.app.AppCompatActivity

I'm trying to start a Fragment inside my RecycleAdapter but when cast my Context with the AppCompatActivity the App crashed and inside logcat I got the message that android.app.Application cannot be cast to android.support.v7.app.AppCompatActivity.
here is my onClickListener inside RecycleAdapter.
holder.ItemClickButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction;
Toast.makeText(CTX,"Row Clicked id : "+homeCycleDataProvider.getId(),Toast.LENGTH_SHORT).show();
ItemsFragment fragobj = new ItemsFragment();
FragmentManager manager = ((AppCompatActivity) CTX).getSupportFragmentManager();
fragmentTransaction = manager.beginTransaction()
fragmentTransaction.replace(R.id.main_container, fragobj);
fragmentTransaction.commit();
}
});
here is my Adapter Initialization where I pass the context.
adapter = new ItemsRecycleAdapter(arrayList,getContext());
LOGCAT.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.a1appstudio.sabirhossain.xpresdelivery, PID: 3109
java.lang.ClassCastException: android.app.Application cannot be cast to android.support.v7.app.AppCompatActivity
at com.a1appstudio.sabirhossain.xpresdelivery.ItemsListViewPackage.ItemsRecycleAdapter$1.onClick(ItemsRecycleAdapter.java:66)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
A context is not always an Activity, even when you're in an Activity. It could be an Application, or a wrapper around another context. It's almost always wrong to cast a Context to an Activity. If you absolutely need one, you should pass in an Activity as a parameter, rather than a Context. Or better yet, pass in the support fragment manager directly rather than the activity, since that's all you need it for.
adapter = new ItemsRecycleAdapter(arrayList,getActivity());
you can try this
if (context instanceof MainActivity ) {
MainActivity myActivity = (MainActivity)context;
myActivity.getSupportFragmentManager();
}

Android findFragmentById returns null

I have this problem when working on communicating from the main activity to fragment. The Monitor keeps saying:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.mick.myApplication.FragmentCal.readfiles(java.util.LinkedList)' on a null object reference
at com.example.mick.myApplication.main.onCreate(main.java:101)
at android.app.Activity.performCreate(Activity.java:6289)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758) 
at android.app.ActivityThread.access$900(ActivityThread.java:177) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:5942) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 
This is the code for fragment transaction and sending the message:
fragmentinfo = new FragmentInfo();
fragmentcal = new FragmentCal();
fragmentrep = new FragmentRep();
fragmentdicn = new FragmentDicn();
fragmentManager = getSupportFragmentManager();
if (!fragmentcal.isAdded()) {
if (currentFragment == null) {
fragmentManager.beginTransaction().add(R.id.fragmentlayout, fragmentcal).commit();
} else {
fragmentManager.beginTransaction().hide(currentFragment).add(R.id.fragmentlayout, fragmentcal).commit();
}
FragmentCal fragmentCal = (FragmentCal) getSupportFragmentManager().findFragmentById(R.id.fragmentlayout);
fragmentCal.readfiles(nameList);
} else {
fragmentManager.beginTransaction().hide(currentFragment).show(fragmentcal).commit();
}
currentFragment = fragmentcal;
And for that, I import android.support.v4.app.Fragment for all activities and fragments.
You can't perform a findFragmentById before adding the fragment to your activity. When you make a setContentView the Activity inflates the layout and adds its views to the current window. In the case of having a Fragment in this layout, it is added with the given Id or Tag provided in the xml to the FragmentManager. Only in this moment you can find it there. So what you have to do is move the findFragmentById below the setContentView.
Source: NullpointerException when findFragmentById
Hope it helps! Good luck!

Categories

Resources