AsycTask Throwing IllegalStateException - Fragment Not Attached To Activity

17,526

Solution 1

Since you are performing background task in your app. there is no guarantee that user will stay on same screen until task finishes so if user navigates to other screen or presses home button before task is completed; your fragment is detached from activity. So always make sure that you have fragment attached with the Activity. try checking with

if (isAdded) { //Do your UI stuff here }

add above check wherever you get callback

Solution 2

Move your code from onCreate to onActivityCreated instead of trying to getActivity @ onCreate.

That's because the fragment can be created when the activity is not yet ready, that's when you are trying to use it.

That is of course if you are adding the fragment to an activity like:

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(android.R.id.content, new PreferenceFragment()).commit();
Share:
17,526
COBOL
Author by

COBOL

Updated on June 04, 2022

Comments

  • COBOL
    COBOL almost 2 years

    I have the following AsyncTask in my Android application. This AsyncTask is contained with within the OnCreate() method of a class that extends PreferenceFragment.

    public class NotificationsPreferenceFragment extends PreferenceFragment {
    
    private static Context context;
    
    public NotificationsPreferenceFragment() {
    
    }
    
    public NotificationsPreferenceFragment(Context context) {
        this.context = context;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref_notifications);
    
        getPreferenceManager().findPreference(getString(R.string.send_all_notifications))
                .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
                    @Override
                    public boolean onPreferenceClick(Preference preference) {
    
                            class NotificationSendTask extends DialogAsyncTask {
    
                                public static final String TAG = "NotificationFragment";
    
                                public NotificationSendTask(Activity activity, String dialogMsg) {
                                    super(activity, dialogMsg);
                                }
    
                                @Override
                                protected String doInBackground(String... params) {
                                    String url = PreferenceManager.getDefaultSharedPreferences(getActivity()).getString(getString(R.string.notification_web_service_url), getString(R.string.default_notification_web_service_url));
    
                                    if (NetworkingHelper.isNetworkAvailable(getActivity())) {
                                        NotificationDao notificationDao = new NotificationDaoImpl(DatabaseManager.getInstance(getActivity().getApplicationContext()), getActivity().getApplicationContext());
    
                                        List<Notification> unsentNotificationList = notificationDao.findAllNotSent();
                                        if (unsentNotificationList.size() != 0) {
                                            NotificationSenderTask ns = new NotificationSenderTask(url, context);
                                            try {
                                                if (ns.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (unsentNotificationList)).get()) {
                                                    return getString(R.string.success);
                                                }
                                            } catch (InterruptedException e) {
                                                Log.e(TAG, e.getMessage());
                                            } catch (ExecutionException e) {
                                                Log.e(TAG, e.getMessage());
                                            }
    
                                            return getString(R.string.failed_to_send_notifications);
                                        } else {
                                            return getString(R.string.no_notifications_to_send);
                                        }
                                    } else {
                                        return getString(R.string.no_connection_notifications);
                                    }
                                }
    
                                public void onPostExecute(String result) {
                                    super.onPostExecute(result);
                                    if (dialog != null && dialog.isShowing()) {
                                        dialog.hide();
                                    }
                                    Toast.makeText(activity, result, Toast.LENGTH_SHORT).show();
                                }
                            }
                            NotificationSendTask notificationSendTask = new NotificationSendTask(getActivity(), "Sending unsent notifications...");
                            notificationSendTask.execute();
                            return true;
    
                    }
                });
    
        getPreferenceManager().findPreference(getString(R.string.export_notifications)).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                NotificationExportTask notificationExportTask = new NotificationExportTask(NotificationsPreferenceFragment.this.getActivity(), 1);
                notificationExportTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                return true;
            }
        });
    }
    }
    

    I am getting the following exception:

    java.lang.IllegalStateException: Fragment NotificationsPreferenceFragment{416092f8} not attached to Activity
    at android.app.Fragment.getResources(Fragment.java:741)
    at android.app.Fragment.getString(Fragment.java:763)
    

    Can someone please explain to me why this is happening and suggest ways to fix this issue?

    UPDATE:

    Here is the code for the Activity:

    public class SettingsActivity extends PreferenceActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    
    @Override
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.pref_headers, target);
    }
    }
    
  • COBOL
    COBOL almost 10 years
    I'm not sure that the fragment is being added to the activity in that way. I have posted the code for the activity in the main post.
  • Simas
    Simas almost 10 years
    @COBOL append the code I supplied to your PreferenceActivity's onCreate method.