android.support.v4.app.Fragment.setUserVisibleHint Nullzeiger bei Wiederaufnahme der App

Ich bekomme einen Absturz im Lebenslauf der App im Fragmentcode. Ich habe diesen Absturz noch nie gesehen, aber ich habe Absturzberichte von Benutzern über TestFlight erhalten. Ich vermute, es fehlt etwas, da der Code auf den meisten Computern gut funktioniert. Jede Hilfe wäre sehr dankbar.

Hier ist die Aufrufliste.

java.lang.NullPointerException
android.support.v4.app.Fragment.setUserVisibleHint in Fragment.java on Line 819
android.support.v4.app.FragmentPagerAdapter.setPrimaryItem in FragmentPagerAdapter.java on Line 130
android.support.v4.view.ViewPager.populate in ViewPager.java on Line 1066
android.support.v4.view.ViewPager.populate in ViewPager.java on Line 914
android.support.v4.view.ViewPager.onMeasure in ViewPager.java on Line 1436
android.view.View.measure in View.java on Line 15323
android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
android.widget.LinearLayout.measureChildBeforeLayout in LinearLayout.java on Line 1421
android.widget.LinearLayout.measureVertical in LinearLayout.java on Line 698
android.widget.LinearLayout.onMeasure in LinearLayout.java on Line 579
android.view.View.measure in View.java on Line 15323
android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
android.widget.FrameLayout.onMeasure in FrameLayout.java on Line 315
android.view.View.measure in View.java on Line 15323
android.support.v4.widget.DrawerLayout.onMeasure in DrawerLayout.java on Line 639
android.view.View.measure in View.java on Line 15323
android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
android.widget.FrameLayout.onMeasure in FrameLayout.java on Line 315
android.view.View.measure in View.java on Line 15323
android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
android.widget.LinearLayout.measureChildBeforeLayout in LinearLayout.java on Line 1421
android.widget.LinearLayout.measureVertical in LinearLayout.java on Line 698
android.widget.LinearLayout.onMeasure in LinearLayout.java on Line 579
android.view.View.measure in View.java on Line 15323
android.view.ViewGroup.measureChildWithMargins in ViewGroup.java on Line 4924
android.widget.FrameLayout.onMeasure in FrameLayout.java on Line 315
com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure in PhoneWindow.java on Line 2155
android.view.View.measure in View.java on Line 15323
android.view.ViewRootImpl.performMeasure in ViewRootImpl.java on Line 1854
android.view.ViewRootImpl.measureHierarchy in ViewRootImpl.java on Line 1102
android.view.ViewRootImpl.performTraversals in ViewRootImpl.java on Line 1275
android.view.ViewRootImpl.doTraversal in ViewRootImpl.java on Line 1000
android.view.ViewRootImpl$TraversalRunnable.run in ViewRootImpl.java on Line 4218
android.view.Choreographer$CallbackRecord.run in Choreographer.java on Line 725
android.view.Choreographer.doCallbacks in Choreographer.java on Line 555
android.view.Choreographer.doFrame in Choreographer.java on Line 525
android.view.Choreographer$FrameDisplayEventReceiver.run in Choreographer.java on Line 711
android.os.Handler.handleCallback in Handler.java on Line 615
android.os.Handler.dispatchMessage in Handler.java on Line 92
android.os.Looper.loop in Looper.java on Line 137
android.app.ActivityThread.main in ActivityThread.java on Line 4744
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke in Method.java on Line 511
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run in ZygoteInit.java on Line 786
com.android.internal.os.ZygoteInit.main in ZygoteInit.java on Line 553
dalvik.system.NativeStart.main(Native Method)

Zuerst habe ich den View-Pager in der OnResume-Funktion der Aktivität eingerichtet.

private void initialiseViewPager()
{
    mLoginFragment = new WeakReference<LoginFragment>(new LoginFragment());
    Bundle loginBundle = new Bundle();
    loginBundle.putInt("SpinnerIndex", HDMSLiveSession.getInstance().getSpinnerPosition());
    loginBundle.putString("UserName", HDMSLiveSession.getInstance().getUsername());
    loginBundle.putString("Password", HDMSLiveSession.getInstance().getPassword());
    loginBundle.putInt("Mode", HDMSLiveSession.getInstance().getConnectionMode().ordinal());
    loginBundle.putBoolean("LoggedIn", HDMSLiveSession.getInstance().isLoggedIn());
    loginBundle.putBoolean("Connected", HDMSLiveSession.getInstance().isConnected());
    loginBundle.putString("LoginResult", HDMSLiveSession.getInstance().getLoginResult());
    loginBundle.putString("System", HDMSLiveSession.getInstance().getSystem());
    loginBundle.putInt("code", HDMSLiveSession.getInstance().getAccessCode());
    loginBundle.putLong("bytesSent", mCurrentSB);
    loginBundle.putLong("bytesReceived", mCurrentRB);
    loginBundle.putLong("nbytesSent", mNCurrentSB);
    loginBundle.putLong("nbytesReceived", mNCurrentRB);
    loginBundle.putInt("appid", mApp.getApplicationInfo().uid);
    loginBundle.putString(mWebSocketAddressPreference, mConnect.getWebSocketURL());
    loginBundle.putString(mAPIAddressPreference, mLogin.getLiveServerURL());
    loginBundle.putBoolean(mAutoLoginPreference, mAutoLoginEnabled);
    loginBundle.putBoolean(mAutoConnectPreference, mLogin.isAutoConnectEnabled());
    loginBundle.putInt(mAutoReconnectTimePreference, mConnect.getAutoReconnectTime());
    loginBundle.putInt(mMaxAutoReconnectionAttemptsPreference, mConnect.getMaxAutoReconnectionAttempts());
    loginBundle.putInt(mPingResponseTimePreference, mConnect.getPingResponseTime());
    loginBundle.putInt(mAutoPingTimePreference, mConnect.getAutoPingTime());
    loginBundle.putInt(mCurrentPingPreference, mConnect.getCurrentPing());
    loginBundle.putInt(mAutoReconnectAttemptsPreference, mConnect.getAutoReconnectAttempts());
    loginBundle.putInt(mAutoReconnectTotalAttemptsPreference, mConnect.getAutoReconnectTotalAttempts());
    loginBundle.putBoolean(mPlayListMessagePreference, messageSubscriptionContains(mPlayListMessage));
    loginBundle.putBoolean(mAutoPageSwapPreference, mAutoPageSwap);
    loginBundle.putBoolean(mWifiCheckedPreference, mWifiChecked);
    loginBundle.putBoolean(mAutoWebCheckedPreference, mConnect.isAutoWebChecked());
    loginBundle.putBoolean(mGatewayCheckedPreference, mGatewayChecked);
    loginBundle.putBoolean(mDHS1CheckedPreference, mDNS1Checked);
    loginBundle.putBoolean(mHDMSLiveCheckedPreference, mHDMSLiveChecked);
    loginBundle.putBoolean(mGoogleCheckedPreference, mGoogleChecked);
    loginBundle.putBoolean(mHDMSCheckedPreference, mHDMSChecked);
    loginBundle.putBoolean(mParrotCheckedPreference, mParrotChecked);
    loginBundle.putBoolean(mLocalIPCheckedPreference, mLocalIPChecked);
    loginBundle.putString(mLocalIPPreference, mLocalIP);
    loginBundle.putInt(mMaxImagesFromWebPreference, mMaxImagesFromWeb);
    loginBundle.putInt(mMaxPingAttemptsPreference, mConnect.getMaxPingAttempts());
    loginBundle.putInt(mFailedPingsPreference, mConnect.getFailedPings());
    loginBundle.putBoolean("AutoLogin", mLogin.isAutoLogin());
    loginBundle.putBoolean("wasLoggedIn", HDMSLiveSession.getInstance().wasLoggedIn());
    mLoginFragment.get().setArguments(loginBundle);

    mBAUFragment = new WeakReference<BAUFragment>(new BAUFragment());
    Bundle bauBundle = new Bundle();
    bauBundle.putBoolean("jump", mJumpToCurrent);
    bauBundle.putInt("place", mBAUPosition);
    bauBundle.putBoolean(mBAUExpandedPreference, mBAUExpanded);
    mBAUFragment.get().setArguments(bauBundle);
    mPlayerFragment = new WeakReference<PlayerFragment>(new PlayerFragment());

    mListFragment = new WeakReference<ListFragment>(new ListFragment());
    Bundle listBundle = new Bundle();
    listBundle.putInt(mListModePreference, mListMode);
    mListFragment.get().setArguments(listBundle);

    mSearchFragment = new WeakReference<SearchFragment>(new SearchFragment());
    Bundle searchBundle = new Bundle();
    searchBundle.putInt(mSearchModePreference, mSearchMode);
    searchBundle.putString("searchQueryA", mSearchTextA);
    searchBundle.putString("searchQueryS", mSearchTextS);
    searchBundle.putString("titleLast", mTitleLast);
    searchBundle.putString("artistLast", mArtistLast);
    searchBundle.putString("listLast", mListLast);
    searchBundle.putString("yearLast", mYearLast);
    searchBundle.putString("genreLast", mGenreLast);
    mSearchFragment.get().setArguments(searchBundle);

    mVideoFragment = new WeakReference<VideoFragment>(new VideoFragment());
    Bundle videoBundle = new Bundle();
    videoBundle.putInt(mVideoOutputPreference, mVideoOutput);
    mVideoFragment.get().setArguments(videoBundle);

    List<Fragment> fragments = new Vector<Fragment>();
    fragments.add(mVideoFragment.get());
    fragments.add(mPlayerFragment.get());
    fragments.add(mBAUFragment.get());
    fragments.add(mListFragment.get());
    fragments.add(mSearchFragment.get());
    fragments.add(mLoginFragment.get());
    mPagerAdapter  = new ViewPagerAdapter(getSupportFragmentManager(), fragments);

    mViewPager = (ViewPager)findViewById(R.id.contentViewPager);
    mViewPager.setAdapter(mPagerAdapter);
    mViewPager.setOnPageChangeListener(this);
    mViewPager.setVisibility(View.VISIBLE);

    ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    if (am.getMemoryClass() >= 32)
        mViewPager.setOffscreenPageLimit(Fragments.Max.ordinal());

    mLastFragment = -1;
    UpdateDisplay();
}

Alle Fragmente bleiben erhalten, es sei denn, es handelt sich um ein Gerät mit einem kleinen Speicherhaufen. Derzeit gibt es 6 Fragmente, der Absturz trat auf, wenn dort nur 4 im Speicher waren. Ich weiß also, dass die Anzahl der Fragmente nicht das Problem ist. Ich habe versucht, die View Pager-Einstellungen auf die Standardeinstellung zurückzusetzen. Der einzige Unterschied ist die Geschwindigkeit, da die App Fragmente laden muss, wenn der Benutzer wischt. Alle Fragmente werden zerstört, wenn die App angehalten wird.

@Override
protected void onSaveInstanceState(Bundle outState)
{
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (mLoginFragment.get() != null)
        ft.remove(mLoginFragment.get());
    if (mPlayerFragment.get() != null)
        ft.remove(mPlayerFragment.get());
    if (mBAUFragment.get() != null)
        ft.remove(mBAUFragment.get());
    if (mListFragment.get() != null)
        ft.remove(mListFragment.get());
    if (mSearchFragment.get() != null)
        ft.remove(mSearchFragment.get());
    if (mVideoFragment.get() != null)
        ft.remove(mVideoFragment.get());
    ft.commit();

    mLoginFragment = new WeakReference<LoginFragment>(null);
    mPlayerFragment = new WeakReference<PlayerFragment>(null);
    mBAUFragment = new WeakReference<BAUFragment>(null);
    mListFragment = new WeakReference<ListFragment>(null);
    mSearchFragment = new WeakReference<SearchFragment>(null);
    mVideoFragment = new WeakReference<VideoFragment>(null);
    mPagerAdapter = null;
    mViewPager = null;

    mFragmentsLoaded = 0;
    mLastFragment = -1;
}

Hier ist mein View-Pager-Code.

package com.hdms.manager.Fragments;

/**
 * Created by bradj on 8/10/13.
 *
 */
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.view.View;

import java.util.List;

public class ViewPagerAdapter extends FragmentPagerAdapter
{
    private final List<Fragment> mFragments;
    FragmentManager mFragmentManager;

    public ViewPagerAdapter(FragmentManager aFragmentManager, List<Fragment> aFragments)
    {
        super(aFragmentManager);

        mFragmentManager = aFragmentManager;
        mFragments = aFragments;
    }

    @Override
    public Fragment getItem(int aPosition)
    {
        return mFragments.get(aPosition);
    }

    @Override
    public long getItemId(int aPosition)
    {
        return aPosition;
    }

    @Override
    public void destroyItem(android.view.ViewGroup aContainer, int aPosition, java.lang.Object aObject)
    {
        if (aPosition <= getCount() && aObject != null)
        {
            FragmentTransaction trans = mFragmentManager.beginTransaction();
            trans.remove((Fragment) aObject);
            trans.commit();
        }
    }

    @Override
    public int getCount()
    {
        return mFragments.size();
    }
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage