为什么我在android.support.v4.app.Fragment.setTargetFragment期间收到java.lang.IllegalArgumentException

时间:2018-03-06 03:26:47

标签: android android-fragments

将我的应用升级到

  • targetSdkVersion 27
  • com.android.support:support-v4:27.0.2

我从实时

获取以下崩溃日志
Caused by: java.lang.IllegalArgumentException:  
  at android.support.v4.app.Fragment.setTargetFragment (Fragment.java:545)

我看一下支持片段的源代码(不完全是545行。我不确定如何获取支持片段库的最新源代码)

https://android.googlesource.com/platform/frameworks/support/+/cef09fe/v4/java/android/support/v4/app/Fragment.java#598

598 public void setTargetFragment(Fragment fragment, int requestCode) {
599     mTarget = fragment;
560     mTargetRequestCode = requestCode;
561 }

我无法看到java.lang.IllegalArgumentException被抛出的原因。也许我正在查看错误版本的支持库源代码?

你有什么想法,为什么我在java.lang.IllegalArgumentException

期间获得android.support.v4.app.Fragment.setTargetFragment

我的源代码如下

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;

public class BuyPortfolioFragment extends Fragment {

    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...

        // If not retained (or first time running), we need to create it.
        if (this.statusBarUpdaterFragment == null) {
            this.statusBarUpdaterFragment = StatusBarUpdaterFragment.newInstance();
            // Tell it who it is working with.
            this.statusBarUpdaterFragment.setTargetFragment(this, 0);
            fm.beginTransaction().add(statusBarUpdaterFragment, STATUS_BAR_UPDATER_FRAGMENT).commitAllowingStateLoss();
        } else {
            statusBarUpdaterFragment.setTargetFragment(this, 0);
        }

1 个答案:

答案 0 :(得分:1)

这是我的代码,有时可能会崩溃。您可以通过将后台进程限制减少到1来重现。

enter image description here

public class BuyPortfolioFragment extends Fragment {

    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...

        // If not retained (or first time running), we need to create it.
        if (this.statusBarUpdaterFragment == null) {
            this.statusBarUpdaterFragment = StatusBarUpdaterFragment.newInstance();
            // Tell it who it is working with.
            this.statusBarUpdaterFragment.setTargetFragment(this, 0);
            fm.beginTransaction().add(statusBarUpdaterFragment, STATUS_BAR_UPDATER_FRAGMENT).commitAllowingStateLoss();
        } else {
            statusBarUpdaterFragment.setTargetFragment(this, 0);
        }

注意,由于Is calling setTargetFragment on headless fragment no longer necessary during UI fragment re-creation?

,可能并非总是需要调用setTargetFragment

但是,为了玩一个安全的游戏,我使用以下修复程序。

public class BuyPortfolioFragment extends Fragment {

    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...

        // If not retained (or first time running), we need to create it.
        if (this.statusBarUpdaterFragment == null) {
            this.statusBarUpdaterFragment = StatusBarUpdaterFragment.newInstance();
            // Tell it who it is working with.
            this.statusBarUpdaterFragment.setTargetFragment(this, 0);
            fm.beginTransaction().add(statusBarUpdaterFragment, STATUS_BAR_UPDATER_FRAGMENT).commitAllowingStateLoss();
        } else {
            // Google poses new restriction recently. A fragment need to have same fragment
            // manager as StatusBarUpdaterFragment, in order to become its target fragment. It
            // is OK not to call setTargetFragment. Although you may get null from
            // statusBarUpdaterFragment.getTargetFragment, during onResume,
            // statusBarUpdaterFragment.getTargetFragment will magically return correct fragment.

            //statusBarUpdaterFragment.setTargetFragment(this, 0);
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        ...

        // This code block might not be necessary. Just to be safe.
        if (statusBarUpdaterFragment != null) {
            // Google poses new restriction recently. A fragment need to have same fragment
            // manager as StatusBarUpdaterFragment, in order to become its target fragment. It
            // is OK not to call setTargetFragment. Although you may get null from
            // statusBarUpdaterFragment.getTargetFragment, during onResume,
            // statusBarUpdaterFragment.getTargetFragment will magically return correct fragment.

            try {
                statusBarUpdaterFragment.setTargetFragment(this, 0);
            } catch (java.lang.IllegalArgumentException e) {
                // Shouldn't happen. Just to be safe.
                Log.e(TAG, "", e);
            }
        }