ÚLTIMA INFORMACIÓN:
He reducido mi problema a ser un problema con fragmentManager que conserva instancias de fragmentos antiguos y mi visor no está sincronizado con mi FragmentManager. Ver este problema ... http://code.google.com/p/android/issues/detail?id=19211#makechanges . Todavía no tengo ni idea de cómo solucionar esto. Alguna sugerencia...
He intentado depurar esto durante mucho tiempo y cualquier ayuda sería muy apreciada. Estoy usando un FragmentPagerAdapter que acepta una lista de fragmentos como este:
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this, Fragment1.class.getName()));
...
new PagerAdapter(getSupportFragmentManager(), fragments);
La implementación es estándar. Estoy usando ActionBarSherlock y la biblioteca de computabilidad v4 para Fragments.
Mi problema es que después de salir de la aplicación y abrir varias otras aplicaciones y regresar, los fragmentos pierden su referencia a FragmentActivity (es decir getActivity() == null
). No puedo entender por qué está sucediendo esto. Traté de configurar manualmente setRetainInstance(true);
pero esto no ayuda. Supuse que esto sucede cuando se destruye mi FragmentActivity, sin embargo, esto aún sucede si abro la aplicación antes de recibir el mensaje de registro. ¿Hay alguna idea?
@Override
protected void onDestroy(){
Log.w(TAG, "DESTROYDESTROYDESTROYDESTROYDESTROYDESTROYDESTROY");
super.onDestroy();
}
El adaptador:
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
Uno de mis Fragmentos se quitó, pero me encontré con todo eso está quitado y todavía no funciona ...
public class MyFragment extends Fragment implements MyFragmentInterface, OnScrollListener {
...
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
handler = new Handler();
setHasOptionsMenu(true);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.w(TAG,"ATTACHATTACHATTACHATTACHATTACH");
context = activity;
if(context== null){
Log.e("IS NULL", "NULLNULLNULLNULLNULLNULLNULLNULLNULLNULLNULL");
}else{
Log.d("IS NOT NULL", "NOTNOTNOTNOTNOTNOTNOTNOT");
}
}
@Override
public void onActivityCreated(Bundle savedState) {
super.onActivityCreated(savedState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.my_fragment,container, false);
return v;
}
@Override
public void onResume(){
super.onResume();
}
private void callService(){
// do not call another service is already running
if(startLoad || !canSet) return;
// set flag
startLoad = true;
canSet = false;
// show the bottom spinner
addFooter();
Intent intent = new Intent(context, MyService.class);
intent.putExtra(MyService.STATUS_RECEIVER, resultReceiver);
context.startService(intent);
}
private ResultReceiver resultReceiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, final Bundle resultData) {
boolean isSet = false;
if(resultData!=null)
if(resultData.containsKey(MyService.STATUS_FINISHED_GET)){
if(resultData.getBoolean(MyService.STATUS_FINISHED_GET)){
removeFooter();
startLoad = false;
isSet = true;
}
}
switch(resultCode){
case MyService.STATUS_FINISHED:
stopSpinning();
break;
case SyncService.STATUS_RUNNING:
break;
case SyncService.STATUS_ERROR:
break;
}
}
};
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.activity, menu);
}
@Override
public void onPause(){
super.onPause();
}
public void onScroll(AbsListView arg0, int firstVisible, int visibleCount, int totalCount) {
boolean loadMore = /* maybe add a padding */
firstVisible + visibleCount >= totalCount;
boolean away = firstVisible+ visibleCount <= totalCount - visibleCount;
if(away){
// startLoad can now be set again
canSet = true;
}
if(loadMore)
}
public void onScrollStateChanged(AbsListView arg0, int state) {
switch(state){
case OnScrollListener.SCROLL_STATE_FLING:
adapter.setLoad(false);
lastState = OnScrollListener.SCROLL_STATE_FLING;
break;
case OnScrollListener.SCROLL_STATE_IDLE:
adapter.setLoad(true);
if(lastState == SCROLL_STATE_FLING){
// load the images on screen
}
lastState = OnScrollListener.SCROLL_STATE_IDLE;
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
adapter.setLoad(true);
if(lastState == SCROLL_STATE_FLING){
// load the images on screen
}
lastState = OnScrollListener.SCROLL_STATE_TOUCH_SCROLL;
break;
}
}
@Override
public void onDetach(){
super.onDetach();
if(this.adapter!=null)
this.adapter.clearContext();
Log.w(TAG, "DETACHEDDETACHEDDETACHEDDETACHEDDETACHEDDETACHED");
}
public void update(final int id, String name) {
if(name!=null){
getActivity().getSupportActionBar().setTitle(name);
}
}
}
Se llama al método de actualización cuando un usuario interactúa con un fragmento diferente y getActivity devuelve un valor nulo. Aquí está el método al que llama el otro fragmento ...
((MyFragment) pagerAdapter.getItem(1)).update(id, name);
Creo que cuando la aplicación se destruye y luego se crea nuevamente en lugar de simplemente iniciar la aplicación hasta el fragmento predeterminado, la aplicación se inicia y luego el visor navega a la última página conocida. Esto parece extraño, ¿no debería la aplicación cargarse en el fragmento predeterminado?