タブを使用したアクティビティがあり、デバイスを回転させると問題が発生します。たとえば、縦向きモードでアプリを起動して横向きに回転し、再び縦向きにすると、アプリがクラッシュし、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());
}
}
}