【问题标题】:AsycTask Throwing IllegalStateException - Fragment Not Attached To ActivityAsycTask 抛出 IllegalStateException - 片段未附加到活动
【发布时间】:2014-08-12 11:21:33
【问题描述】:

我的 Android 应用程序中有以下 AsyncTask。此 AsyncTask 包含在扩展 PreferenceFragment 的类的 OnCreate() 方法中。

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;
        }
    });
}
}

我收到以下异常:

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)

有人可以向我解释为什么会发生这种情况并提出解决此问题的方法吗?

更新:

这是活动的代码:

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);
}
}

【问题讨论】:

  • 该类不在您显示的代码中。请向我们展示其余的代码。
  • @Akagami 代码已添加。

标签: java android exception fragment


【解决方案1】:

因为您在应用中执行后台任务。不能保证用户在任务完成之前会停留在同一个屏幕上,因此如果用户在任务完成之前导航到其他屏幕或按下主页按钮;您的片段与活动分离。因此,请始终确保您已将片段附加到 Activity。 尝试检查

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

在收到回调的地方添加上面的检查

【讨论】:

    【解决方案2】:

    将您的代码从onCreate 移动到onActivityCreated,而不是尝试移动到getActivity @onCreate

    这是因为片段可以在 Activity 尚未准备好时创建,也就是您尝试使用它的时候。

    这当然是如果您将片段添加到以下活动中:

    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(android.R.id.content, new PreferenceFragment()).commit();
    

    【讨论】:

    • 我不确定是否以这种方式将片段添加到活动中。我已经在主帖中发布了活动的代码。
    • @COBOL 将我提供的代码附加到您的PreferenceActivityonCreate 方法中。
    猜你喜欢
    • 2015-04-24
    • 2018-01-05
    • 2014-04-13
    • 2012-12-01
    • 2021-09-02
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多