问题
Hi and thank you for any help.
I am only at the very beginning of configuring my code to handle rotation: I have implemented onDestroy(), but not yet any onSaveInstanceState() or onRetainNonConfigurationInstance() because I am figuring out what will not cause problems if destroyed and recreated after rotation and what needs to be saved.
In my application I use a Service that runs an AsyncTask, and 3 fragments that get swapped on user pressing buttons.
I use the compatibility library for managing the fragments.
I suspect the error I encounter is related to the fragments;
To be specific, I would prefer the fragments to be destroyed and recreated on rotation, rather that preserving them (because it is my hope that this would make my code simpler...)
when I rotate the emulator I get the error in the title.
This is the code of the main activity:
public class Quotes extends FragmentActivity {
private String url2;
//public String responseBody;
public static ArrayList<Stock> lt;
public static ArrayList<Stock> best;
public static ArrayList<Stock> worst;
public static ArrayList<Stock> fav;// =new ArrayList<Stock>();
public static LocalService mService;
boolean mBound;// = false;
public MyAdapter myAdap;
public Messenger messenger;
public Messenger messenger2;
public Grab g;
public static Handler handler;
public static Handler handler2;
public Intent intent;
public ListView lv;
public dettagliofragment fragment;
public listafragment fragmentlista ;
public static boolean tablet;//=true;
public static WorstBest worstbest;
public static favouritesFragment fragmentfavourites;
public static FragmentActivity fragmentActivity;
public static int stack;
public static ArrayList<Integer> stackArray; // stackArray =new ArrayList<Integer>();
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
stackArray =new ArrayList<Integer>();
fav =new ArrayList<Stock>();
tablet=true;
mBound = false;
fragmentActivity = this;
setContentView(R.layout.splash);
url2=getString(R.string.url2);
g = new Grab(url2);
String s = g.vai();
//Log.e("", s);
Log.e("", "passo oltre l'invocazione al grab");
lt = new MyParser(s).parseResp();
fragmentlista = new listafragment();
fragmentfavourites= new favouritesFragment() ;
worstbest = new WorstBest();
/////////////////primo message handler
handler=new Handler() {
@Override
public void handleMessage(Message msg) {
Message mess=msg;
Log.e("","MESSAGGIO RICEVUTO");
lt = mService.ritira();
Log.e("what?", Integer.toString(mess.what));
if( mess.what==0){
worst=mService.ritiraWorst();
best=mService.ritiraBest();
fav=mService.ritiraFav();
setContentView(R.layout.main);
View view1=(View)findViewById(R.id.view1);
View view2=(View)findViewById(R.id.view2);
if(view2==null) {tablet=false;};
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.view1, fragmentlista);
if(tablet){fragmentTransaction.add(R.id.view2, worstbest);}
fragmentTransaction.commit();
g.fermaGrab();
Log.e("", "fermograb");
};
}
};
messenger = new Messenger(handler);
intent = new Intent(this, LocalService.class);
intent.putExtra("messenger", messenger);
/////////////////secondo message handler
handler2=new Handler() {
@Override
public void handleMessage(Message msg) {
Message mess=msg;
Log.e("","SECONDO MESSAGGIO RICEVUTO");
lt = mService.ritira();
worst=mService.ritiraWorst();
best=mService.ritiraBest();
fav=mService.ritiraFav();
if(lt==null){Log.e("","lt è nullo");};
if(fragmentlista==null){Log.e("","fragmentlista è nullo");};
fragmentlista.prendiLista(lt);
worstbest.prendiListaWorst(worst);
worstbest.prendiListaBest(best);
if(fav.size()>0)fragmentfavourites.prendiLista(fav);
};
};
messenger2 = new Messenger(handler2);
intent.putExtra("messenger2", messenger2);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
public static void layoutSchermo(int conf){
if(conf==1){
FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
if(!tablet){fragmentTransaction.replace(R.id.view1, fragmentfavourites);}
if(tablet){fragmentTransaction.replace(R.id.view2, fragmentfavourites);}
fragmentTransaction.addToBackStack(null);
stack=fragmentTransaction.commit();
stackArray.add(stack);
Log.e("","stack = "+ Integer.toString(stack));
}
if(conf==2){
FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
if(!tablet){fragmentTransaction.replace(R.id.view1, worstbest);}
if(tablet){fragmentTransaction.replace(R.id.view2, worstbest);}
fragmentTransaction.addToBackStack(null);
stack= fragmentTransaction.commit();
stackArray.add(stack);
Log.e("","stack = "+ Integer.toString(stack));
}
}
@Override
public void onBackPressed(){
FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
if(stackArray.size()>0)
{for(int i=1;i<stackArray.size();i++){
fragmentManager.popBackStackImmediate(stackArray.get(i), FragmentManager.POP_BACK_STACK_INCLUSIVE);}
}
super.onBackPressed();
}
protected void onStop() {
Log.e("onstop","passo per onstop");
mService.stop();
g.fermaGrab();
super.onStop();
}
protected void onPause() {
Log.e("onpause","passo per onpause");
mService.stop();
g.fermaGrab();
super.onPause();
}
protected void onDestroy() {
Log.e("ondestroy","passo per ondestroy");
mService.stop();
g.fermaGrab();
//handler.removeMessages(333);
stopService(intent);
//g=null;
FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
if(stackArray.size()>0)
{for(int i=1;i<stackArray.size();i++){
fragmentManager.popBackStackImmediate(stackArray.get(i), FragmentManager.POP_BACK_STACK_INCLUSIVE);}
}
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) { }
public static ArrayList<Stock> dammi(){
return lt;
}
public void inizia()
{
Log.e("","il serlizio è bound ? "+ mBound);
mService.prendi(lt);
mService.getNumber();
}
private ServiceConnection mConnection = new ServiceConnection() {
//@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
Log.e("", "sono in ServiceConnection");
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
//inizia();
mService.prendi(lt);
mService.getNumber();
}
//@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
mService = null;
}
};
Hes is my LogCat:
01-06 12:20:27.869: E/AndroidRuntime(2165): FATAL EXCEPTION: main
01-06 12:20:27.869: E/AndroidRuntime(2165): java.lang.RuntimeException: Unable to destroy activity {com.example.quotes/com.example.quotes.Quotes}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3273)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3291)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3489)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.ActivityThread.access$700(ActivityThread.java:130)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.os.Looper.loop(Looper.java:137)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.ActivityThread.main(ActivityThread.java:4745)
01-06 12:20:27.869: E/AndroidRuntime(2165): at java.lang.reflect.Method.invokeNative(Native Method)
01-06 12:20:27.869: E/AndroidRuntime(2165): at java.lang.reflect.Method.invoke(Method.java:511)
01-06 12:20:27.869: E/AndroidRuntime(2165): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-06 12:20:27.869: E/AndroidRuntime(2165): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-06 12:20:27.869: E/AndroidRuntime(2165): at dalvik.system.NativeStart.main(Native Method)
01-06 12:20:27.869: E/AndroidRuntime(2165): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:480)
01-06 12:20:27.869: E/AndroidRuntime(2165): at com.example.quotes.Quotes.onDestroy(Quotes.java:201)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.Activity.performDestroy(Activity.java:5172)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1109)
01-06 12:20:27.869: E/AndroidRuntime(2165): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3260)
01-06 12:20:27.869: E/AndroidRuntime(2165): ... 12 more
Thank you very much for any help !!!
回答1:
Thanks for your info. Meanwhile, I fixed this issue.
What was causing the problem was a Service that needed to be unbound when the Activty was destroyed because of rotation.
As far as I could understand the Fragments are not destroyed when the activity is destroyed. However, I would appreciate any comment on this.
So, I reinitialized the Fragments on the onCreate()
method when the Activty is created again after destruction, and this is not causing trouble to the application.
protected void onDestroy() {
mService.stop();
stopService(new Intent(this, LocalService.class));
unbindService(mConnection);
g.fermaGrab();
stopService(intent);
Log.e("ondestroy","passostopService(intent)");
super.onDestroy();
}
回答2:
Just because the other answers to this question led me on a wild goose hunt of WeakReferences, memory leaks, and onResumeFragments... you can get this error simply by having an onFocusChangeListener
that tries to pop up a dialog box when a control loses focus. The error comes in ActivityThread.handleRelaunchActivity
so it's a little tough to figure out.
来源:https://stackoverflow.com/questions/14182432/on-rotation-i-get-unable-to-destroy-activity-can-not-perform-this-action-af