4

タブを使用したアクティビティがあり、デバイスを回転させると問題が発生します。たとえば、縦向きモードでアプリを起動して横向きに回転し、再び縦向きにすると、アプリがクラッシュし、LogCat で次のように表示されます。

android.os.StrictMode$InstanceCountViolation: class com.example.MyActivity; instances=2; limit=1

これは私の活動のonCreate()方法です:

mTabManager = new TabManager(this, mTabHost, R.id.realtabcontent, R.id.realtabcontentleft);
mTabManager.addTab(mTabHost.newTabSpec(TAB1_ID).setIndicator(indicator1), Fragment.class, args, SendType.SEND1);
mTabManager.addTab(mTabHost.newTabSpec(TAB2_ID).setIndicator(indicator2), Fragment.class, args, SendType.SEND2);

if (savedInstanceState != null || shouldSetCurrentTag) {
    mTabHost.setCurrentTabByTag(currentTabTag);
}

フラグメント クラス - これは拡張する空のクラスですSherlockFragment(私は ActionBarSherlock を使用します)。

TabManagerクラスは次のとおりです。

public static class TabManager implements TabHost.OnTabChangeListener {

    private final FragmentActivity mActivity;
    private final TabHost mTabHost;
    private final int mContainerId;
    private final int mLeftContainerId;
    private boolean mIsDualPane = false;
    private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>();
    TabInfo mLastTab;

    static final class TabInfo {

        private final String tag;
        private final String leftContainerTag;
        private final Class<?> clss;
        private final Bundle args;
        private Fragment fragment;
        private Fragment leftContainerFragment;

        TabInfo(String _tag, String _leftTag, Class<?> _class, Bundle _args) {
            tag = _tag;
            leftContainerTag = _leftTag;
            clss = _class;
            args = _args;
        }
    }

    static class DummyTabFactory implements TabHost.TabContentFactory {

        private final Context mContext;

        public DummyTabFactory(Context context) {
            mContext = context;
        }

        @Override
        public View createTabContent(String tag) {
            View v = new View(mContext);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }
    }

    public TabManager(FragmentActivity activity, TabHost tabHost,
            int containerId, int leftContainerId) {
        mActivity = activity;
        mTabHost = tabHost;
        mContainerId = containerId;
        mLeftContainerId = leftContainerId;
        mTabHost.setOnTabChangedListener(this);

        View leftContainerView = activity.findViewById(leftContainerId);
        mIsDualPane = leftContainerView != null
                && leftContainerView.getVisibility() == View.VISIBLE;
    }

    public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args,
            SendType sendType) {
        tabSpec.setContent(new DummyTabFactory(mActivity));
        String tag = tabSpec.getTag();
        String leftTag = tag + "_LEFT";

        if (mIsDualPane) {
            if (args == null) {
                args = new Bundle();
            }

            args.putInt(BoxTypeFragment.EXTRA_BOX_TYPE, sendType.ordinal());
        }

        TabInfo info = new TabInfo(tag, leftTag, clss, args);

        // Check to see if we already have a fragment for this tab, probably
        // from a previously saved state. If so, deactivate it, because our
        // initial state is that a tab isn't shown.
        info.fragment = mActivity.getSupportFragmentManager()
                .findFragmentByTag(tag);
        if (info.fragment != null && !info.fragment.isDetached()) {
            FragmentTransaction ft = mActivity.getSupportFragmentManager()
                    .beginTransaction();
            ft.detach(info.fragment);
            ft.commit();
            mActivity.getSupportFragmentManager().executePendingTransactions();
        }

        if (mIsDualPane) {
            // if this is a tablet, then check if we already have a left
            // container fragment and then detach it
            info.leftContainerFragment = mActivity.getSupportFragmentManager()
                    .findFragmentByTag(leftTag);
            if (info.leftContainerFragment != null
                    && !info.leftContainerFragment.isDetached()) {
                FragmentTransaction ft = mActivity.getSupportFragmentManager()
                        .beginTransaction();
                ft.detach(info.leftContainerFragment);
                ft.commit();
                mActivity.getSupportFragmentManager()
                        .executePendingTransactions();
            }
        }

        mTabs.put(tag, info);
        mTabHost.addTab(tabSpec);
    }

    @Override
    public void onTabChanged(String tabId) {
        TabInfo newTab = mTabs.get(tabId);

        if (mLastTab != newTab) {
            FragmentTransaction ft = mActivity.getSupportFragmentManager()
                    .beginTransaction();

            if (mLastTab != null) {
                if (mLastTab.fragment != null) {
                    ft.detach(mLastTab.fragment);
                }

                if (mIsDualPane) {
                    if (mLastTab.leftContainerFragment != null) {
                        ft.detach(mLastTab.leftContainerFragment);
                    }
                }
            }

            if (newTab != null) {
                if (newTab.fragment == null) {
                    newTab.fragment = Fragment.instantiate(mActivity,
                            newTab.clss.getName(), newTab.args);
                    newTab.fragment.setHasOptionsMenu(true);
                    ft.add(mContainerId, newTab.fragment, newTab.tag);
                } else {
                    ft.attach(newTab.fragment);
                }

                if (mIsDualPane) {
                    if (newTab.leftContainerFragment == null) {
                        newTab.leftContainerFragment = Fragment.instantiate(
                                mActivity, BoxTypeFragment.class.getName(),
                                newTab.args);
                        ft.add(mLeftContainerId, newTab.leftContainerFragment,
                                newTab.leftContainerTag);
                    } else {
                        ft.attach(newTab.leftContainerFragment);
                    }
                }
            }

            mLastTab = newTab;
            ft.commit();
            mActivity.getSupportFragmentManager().executePendingTransactions();
        }
    }
}

staticクラスとアクティビティ変数から削除しようとしましfinalたが、役に立ちませんでした。

回転すると、アクティビティを破棄して再作成する必要があると思いますが、おそらくどこかへの参照があり、破棄できません。

誰かが私を助けることができますか?

編集:厳密モードを設定したアクティビティとアプリケーション クラスが 1 つだけの空の Android アプリケーション プロジェクトを作成しましたが、同じエラーが発生しました。これを厳密モードに使用します:

public class StrictModeWrapper {
public static void init(Context context) {
    int appFlags = context.getApplicationInfo().flags;

    if ((appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .build());

        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .penaltyDeath()
            .build());
    }
}
}
4

0 に答える 0