问题描述
我创建了一个小的测试应用程序,它重新presents我的问题。我使用ActionBarSherlock实现制表符(福尔摩斯)片段。
我的code: TestActivity.java
公共类TestActivity扩展SherlockFragmentActivity {
私人ActionBar的动作条;
@覆盖
公共无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
setupTabs(savedInstanceState);
}
私人无效setupTabs(包savedInstanceState){
动作条= getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
addTab1();
addTab2();
}
私人无效addTab1(){
标签TAB1 = actionBar.newTab();
tab1.setTag(1);
串tabText =1;
tab1.setText(tabText);
tab1.setTabListener(新TabListener&其中; MyFragment>(TestActivity.this,1,MyFragment.class));
actionBar.addTab(TAB1);
}
私人无效addTab2(){
标签TAB1 = actionBar.newTab();
tab1.setTag(2);
串tabText =2;
tab1.setText(tabText);
tab1.setTabListener(新TabListener&其中; MyFragment>(TestActivity.this,2,MyFragment.class));
actionBar.addTab(TAB1);
}
}
TabListener.java
公共类TabListener<吨延伸SherlockFragment>实现com.actionbarsherlock.app.ActionBar.TabListener {
私人最终SherlockFragmentActivity mActivity;
私人最终字符串MTAG;
私人最终类别< T> mClass;
公共TabListener(SherlockFragmentActivity活动,字符串变量,类< T> CLZ){
mActivity =活动;
MTAG =标签;
mClass = CLZ;
}
/ *下面是每个ActionBar.TabListener回调* /
公共无效onTabSelected(TAB键,FragmentTransaction英尺){
SherlockFragment preInitializedFragment =(SherlockFragment)mActivity.getSupportFragmentManager()findFragmentByTag(MTAG)。
//检查片段已初始化
如果(preInitializedFragment == NULL){
//如果没有,实例化并把它添加到活动
SherlockFragment mFragment =(SherlockFragment)SherlockFragment.instantiate(mActivity,mClass.getName());
ft.add(android.R.id.content,mFragment,MTAG);
} 其他 {
ft.attach(preInitializedFragment);
}
}
公共无效onTabUnselected(TAB键,FragmentTransaction英尺){
SherlockFragment preInitializedFragment =(SherlockFragment)mActivity.getSupportFragmentManager()findFragmentByTag(MTAG)。
如果(preInitializedFragment!= NULL){
//分离的片段,因为另一个被连接
ft.detach(preInitializedFragment);
}
}
公共无效onTabReselected(TAB键,FragmentTransaction英尺){
//用户选择已经选择的选项卡。通常什么也不做。
}
}
MyFragment.java
公共类MyFragment扩展SherlockFragment {
@覆盖
公共无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
新的AsyncTask<虚空,虚空,虚空>(){
@覆盖
保护无效doInBackground(虚空...... PARAMS){
尝试 {
视频下载(2000);
}赶上(InterruptedException的前){
}
返回null;
}
@覆盖
保护无效onPostExecute(无效的结果){
。getResources()的getString(R.string.app_name);
}
}。执行();
}
}
我已经添加了视频下载
部分模拟下载数据。在code。在 onPostExecute
是模拟使用片段
。
当我旋转屏幕非常快的横向和纵向的,我得到一个异常的 onPostExecute
code:
我想这是因为新的 MyFragment
在此期间已创建,并附着在的AsyncTask $ C $活动C>完成。在
onPostExecute
的code呼吁一个独立的 MyFragment
。
但我怎么才能解决这个问题?
我已经找到了非常简单的答案:的:
@覆盖
保护无效onPostExecute(无效的结果){
如果(isAdded()){
。getResources()的getString(R.string.app_name);
}
}
要避免 onPostExecute
被调用的时候,片段
未连接到活动
是取消的AsyncTask
暂停或停止片段时
。然后 isAdded()
就没有必要了。不过,最好是保持这种检查到位。
I've created a small test app which represents my problem.I'm using ActionBarSherlock to implement tabs with (Sherlock)Fragments.
My code:TestActivity.java
public class TestActivity extends SherlockFragmentActivity {
private ActionBar actionBar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupTabs(savedInstanceState);
}
private void setupTabs(Bundle savedInstanceState) {
actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
addTab1();
addTab2();
}
private void addTab1() {
Tab tab1 = actionBar.newTab();
tab1.setTag("1");
String tabText = "1";
tab1.setText(tabText);
tab1.setTabListener(new TabListener<MyFragment>(TestActivity.this, "1", MyFragment.class));
actionBar.addTab(tab1);
}
private void addTab2() {
Tab tab1 = actionBar.newTab();
tab1.setTag("2");
String tabText = "2";
tab1.setText(tabText);
tab1.setTabListener(new TabListener<MyFragment>(TestActivity.this, "2", MyFragment.class));
actionBar.addTab(tab1);
}
}
TabListener.java
public class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener {
private final SherlockFragmentActivity mActivity;
private final String mTag;
private final Class<T> mClass;
public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
/* The following are each of the ActionBar.TabListener callbacks */
public void onTabSelected(Tab tab, FragmentTransaction ft) {
SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
// Check if the fragment is already initialized
if (preInitializedFragment == null) {
// If not, instantiate and add it to the activity
SherlockFragment mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(preInitializedFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
if (preInitializedFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(preInitializedFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// User selected the already selected tab. Usually do nothing.
}
}
MyFragment.java
public class MyFragment extends SherlockFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
}
return null;
}
@Override
protected void onPostExecute(Void result){
getResources().getString(R.string.app_name);
}
}.execute();
}
}
I've added the Thread.sleep
part to simulate downloading data. The code in the onPostExecute
is to simulate use of the Fragment
.
When I rotate the screen very fast between landscape and portrait, I get an Exception at the onPostExecute
code:
I think it's because a new MyFragment
has been created in the meantime, and was attached to the Activity before the AsyncTask
finished. The code in onPostExecute
calls upon a unattached MyFragment
.
But how can I fix this?
I've found the very simple answer: isAdded()
:
@Override
protected void onPostExecute(Void result){
if(isAdded()){
getResources().getString(R.string.app_name);
}
}
To avoid onPostExecute
from being called when the Fragment
is not attached to the Activity
is to cancel the AsyncTask
when pausing or stopping the Fragment
. Then isAdded()
would not be necessary anymore. However, it is advisable to keep this check in place.
这篇关于片段MyFragment不附到活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!