Android. Fragment getActivity() sometime returns null
Android. Fragment getActivity() sometime returns null
In developer console error reports sometime I see reports with NPE issue. I do not understand what is wrong with my code. On emulator and my device application works good without forcecloses, however some users get NullPointerException in fragment class when the getActivity() method is called.
Activity
pulic class MyActivity extends FragmentActivity{ private ViewPager pager; private TitlePageIndicator indicator; private TabsAdapter adapter; @Override public void onCreate(Bundle savedInstanceState) { pager = (ViewPager) findViewById(R.id.pager); indicator = (TitlePageIndicator) findViewById(R.id.indicator); adapter = new TabsAdapter(getSupportFragmentManager(), false); adapter.addFragment(new FirstFragment()); adapter.addFragment(new SecondFragment()); indicator.notifyDataSetChanged(); adapter.notifyDataSetChanged(); // push first task FirstTask firstTask = new FirstTask(MyActivity.this); // set first fragment as listener firstTask.setTaskListener((TaskListener) adapter.getItem(0)); firstTask.execute(); } indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { Fragment currentFragment = adapter.getItem(position); ((Taskable) currentFragment).executeTask(); } @Override public void onPageScrolled(int i, float v, int i1) {} @Override public void onPageScrollStateChanged(int i) {} }); }
AsyncTask class
public class FirstTask extends AsyncTask{ private TaskListener taskListener; ... @Override protected void onPostExecute(T result) { ... taskListener.onTaskComplete(result); } }
Fragment class
public class FirstFragment extends Fragment immplements Taskable, TaskListener{ public FirstFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.first_view, container, false); } @Override public void executeTask() { FirstTask firstTask = new FirstTask(MyActivity.this); firstTask.setTaskListener(this); firstTask.execute(); } @Override public void onTaskComplete(T result) { // NPE is here Resources res = getActivity().getResources(); ... } }
Maybe this error happens when applications resumed from background. In this case how I should handle this situation properly?
Answer by Georgy Gobozov for Android. Fragment getActivity() sometime returns null
It seems that I found a solution to my problem. Very good explanations are given here and here. Here is my example:
pulic class MyActivity extends FragmentActivity{ private ViewPager pager; private TitlePageIndicator indicator; private TabsAdapter adapter; private Bundle savedInstanceState; @Override public void onCreate(Bundle savedInstanceState) { .... this.savedInstanceState = savedInstanceState; pager = (ViewPager) findViewById(R.id.pager);; indicator = (TitlePageIndicator) findViewById(R.id.indicator); adapter = new TabsAdapter(getSupportFragmentManager(), false); if (savedInstanceState == null){ adapter.addFragment(new FirstFragment()); adapter.addFragment(new SecondFragment()); }else{ Integer count = savedInstanceState.getInt("tabsCount"); String[] titles = savedInstanceState.getStringArray("titles"); for (int i = 0; i < count; i++){ adapter.addFragment(getFragment(i), titles[i]); } } indicator.notifyDataSetChanged(); adapter.notifyDataSetChanged(); // push first task FirstTask firstTask = new FirstTask(MyActivity.this); // set first fragment as listener firstTask.setTaskListener((TaskListener) getFragment(0)); firstTask.execute(); } private Fragment getFragment(int position){ return savedInstanceState == null ? adapter.getItem(position) : getSupportFragmentManager().findFragmentByTag(getFragmentTag(position)); } private String getFragmentTag(int position) { return "android:switcher:" + R.id.pager + ":" + position; } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("tabsCount", adapter.getCount()); outState.putStringArray("titles", adapter.getTitles().toArray(new String[0])); } indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { Fragment currentFragment = adapter.getItem(position); ((Taskable) currentFragment).executeTask(); } @Override public void onPageScrolled(int i, float v, int i1) {} @Override public void onPageScrollStateChanged(int i) {} });
The main idea in this code is that, while running your application normally, you create new fragments and pass them to the adapter. When you are resuming your application fragment manager already has this fragment's instance and you need to get it from fragment manager and pass it to the adapter.
UPDATE
Also, it is a good practice when using fragments to check isAdded before getActivity() is called. This helps avoid a null pointer exception when the fragment is detached from the activity. For example, an activity could contain a fragment that pushes an async task. When the task is finished, the onTaskComplete listener is called.
@Override public void onTaskComplete(List result) { progress.setVisibility(View.GONE); progress.setIndeterminate(false); list.setVisibility(View.VISIBLE); if (isAdded()) { adapter = new FeedAdapter(getActivity(), R.layout.feed_item, result); list.setAdapter(adapter); adapter.notifyDataSetChanged(); } }
If we open the fragment, push a task, and then quickly press back to return to a previous activity, when the task is finished, it will try to access the activity in onPostExecute() by calling the getActivity() method. If the activity is already detached and this check is not there:
if (isAdded())
then the application crashes.
Answer by Pawan M for Android. Fragment getActivity() sometime returns null
The best to get rid of this is to keep activity reference when onAttach is called and use the activity reference wherever needed, for e.g.
@Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = activity; }
Answer by blackvibes for Android. Fragment getActivity() sometime returns null
Don't call methods within the Fragment that require getActivity() until onStart in the parent Activity.
private MyFragment myFragment; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); myFragment = new MyFragment(); ft.add(android.R.id.content, youtubeListFragment).commit(); //Other init calls //... } @Override public void onStart() { super.onStart(); //Call your Fragment functions that uses getActivity() myFragment.onPageSelected(); }
Answer by Paul Freez for Android. Fragment getActivity() sometime returns null
Ok, I know that this question is actually solved but I decided to share my solution for this. I've created abstract parent class for my Fragment
:
public abstract class ABaseFragment extends Fragment{ protected IActivityEnabledListener aeListener; protected interface IActivityEnabledListener{ void onActivityEnabled(FragmentActivity activity); } protected void getAvailableActivity(IActivityEnabledListener listener){ if (getActivity() == null){ aeListener = listener; } else { listener.onActivityEnabled(getActivity()); } } @Override public void onAttach(Activity activity) { super.onAttach(activity); if (aeListener != null){ aeListener.onActivityEnabled((FragmentActivity) activity); aeListener = null; } } @Override public void onAttach(Context context) { super.onAttach(context); if (aeListener != null){ aeListener.onActivityEnabled((FragmentActivity) context); aeListener = null; } } }
As you can see, I've added a listener so, whenever I'll need to get Fragments
Activity
instead of standard getActivity()
, I'll need to call
getAvailableActivity(new IActivityEnabledListener() { @Override public void onActivityEnabled(FragmentActivity activity) { // Do manipulations with your activity } });
Answer by user1868713 for Android. Fragment getActivity() sometime returns null
Since Android API level 23, onAttach(Activity activity) has been deprecated by onAttach(Context context). http://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity)
Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72
0 comments:
Post a Comment