0

J'essaie d'utiliser des groupes d'activités - puisque j'utilise des onglets, et que vous voulez avoir les onglets lors du chargement et de l'activité après avoir cliqué sur l'élément de la liste. mais je reçois nullpointerexception dans la ligne suivante:Android ActivityGroup - NullPointerException

View view1 = S1_Group.group.getLocalActivityManager() 
          .startActivity("S1", intent) 
          .getDecorView(); 

Le code est ...

lv.setOnItemClickListener(new OnItemClickListener() { 
    public void onItemClick(AdapterView<?> parent, View view, 
      int position, long id) { 


     Intent intent = new Intent(getApplicationContext(), S1.class); 

     intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     Log.d("test","Before view"); 
     try{ 
      View view1 = S1_Group.group.getLocalActivityManager() 
       .startActivity("S1", intent) 
       .getDecorView(); 
       Settings_Group.group.setContentView(view1);  
     } 
     catch (Exception e){ 
      Log.e("test","view failded:"+e); 
     } 
.... 

mise à jour: ce que mon activité de groupe est:. Je ne pouvais pas trouver quel était le problème,

public class S1_Group extends ActivityGroup { 

    public static S1_Group group; 
    private ArrayList<View> history; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     this.history = new ArrayList<View>(); 
     group = this; 

     View view = getLocalActivityManager().startActivity("F1", 
       new Intent(this, F1.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView(); 

     setContentView(view); 
    } 
} 
+1

Étape de débogage de base: Si vous obtenez un NPE sur une ligne avec plusieurs chaîne "." invoque, par exemple 'a(). b(). c(). d()', alors probablement l'une de ces méthodes renvoie null. Divisez cette ligne en appels individuels, par ex. X X = a(); Y y = x.b(); Z z = y.c(); W w = z.d() ', et ajoute des contrôles pour voir lequel retourne null. –

Répondre

1

J'ai eu le même problème. Pour le résoudre, je décomposé la ligne d'appel à plusieurs en trois lignes comme la première réponse suggérée:

  LocalActivityManager processManager =activityGroup.group.getLocalActivityManager(); 
      Window w = processManager.startActivity("ActivityOne", myIntent); 
      View view = w.getDecorView(); 

ensuite découvert que la première ligne est le premier problème. Comme j'appelle ActivityOne à partir d'une activité en dehors du groupe d'activités (il s'agit d'une activité sous un onglet différent), le static "activityGroup.group ...." n'a pas encore été initialisé. Donc, le correctif plutôt kludgy est de passer à cet onglet et de revenir à cet onglet avant de lancer l'intention. Donc, ajoutez ce qui suit juste avant le code ci-dessus:

  AppName.switchToTab(2); 
      AppName.switchToTab(1); 

qui a fait l'affaire et vous ne pouvez pas voir le commutateur onglet. Une solution plus ordonnée serait peut-être de passer à tous les onglets au démarrage pour s'assurer qu'ils sont tous initialisés ...

1

Came à travers le même problème et il semble qu'il y ait (ou ait été) un bug avec le LocalActivityManager qui se produit lorsque vous essayez de (re) démarrer une activité avec le même ID qu'une activité précédemment détruite. Il retournera simplement null comme Window, à cause d'un bug à l'intérieur de la méthode destroyActivity. La solution que je utilise, utilise la réflexion pour bien détruire une activité (explication détaillée après la solution de contournement):

public boolean destroyActivityWorkAround(String id) { 
    final LocalActivityManager activityManager = getLocalActivityManager(); 
    if(activityManager != null){ 
     activityManager.destroyActivity(id, false);    
     try { 
      // Use reflection to get to the HashMaps with the records(which activities are started ect.) 
      // to remove the records properly 
      // http://code.google.com/p/android/issues/detail?id=10083 
      final Field mActivitiesField = LocalActivityManager.class.getDeclaredField("mActivities"); 
      if(mActivitiesField != null){ 
       mActivitiesField.setAccessible(true); 
       @SuppressWarnings("unchecked") 
       final Map<String, Object> mActivities = (Map<String, Object>)mActivitiesField.get(activityManager); 
       if(mActivities != null){ 
        mActivities.remove(id); 
       } 
       final Field mActivityArrayField = LocalActivityManager.class.getDeclaredField("mActivityArray"); 
       if(mActivityArrayField != null){ 
        mActivityArrayField.setAccessible(true); 
        @SuppressWarnings("unchecked") 
        final ArrayList<Object> mActivityArray = (ArrayList<Object>)mActivityArrayField.get(activityManager); 
        if(mActivityArray != null){ 
         for(Object record : mActivityArray){ 
          final Field idField = record.getClass().getDeclaredField("id"); 
          if(idField != null){ 
           idField.setAccessible(true); 
           final String _id = (String)idField.get(record); 
           if(id.equals(_id)){ 
            mActivityArray.remove(record); 
            break; 
           } 
          } 
         } 
        } 
       } 
      } 
     } catch (Exception e) { 
      Log.e(LOGTAG, this.getClass().getSimpleName() + ".destroyActivityWorkAround() removing activity using reflection failed with error:", e); 
      //e.printStackTrace(); 
     } 
     return true; 
    } 
    return false; 
} 

Ceci est une solution de contournement parce que le LocalActivityManager.destroyActivity (...) contient un bogue dans plusieurs API- versions. La méthode ne supprime pas l'activité correctement de son de HashMap (LocalActivityManager's source):

 public Window destroyActivity(String id, boolean finish) { 
     LocalActivityRecord r = mActivities.get(id); //<-- id's are the key's for the HashMap 
     Window win = null; 
     if (r != null) { 
      win = performDestroy(r, finish); 
      if (finish) { 
        mActivities.remove(r); //--> This works on id's not the 'r object', this doesn't remove anything 
      } 
     } 
     return win; 
    } 

l'instruction if (arrivée) doit être aussi suivi pour enlever le LocalActivityRecord de l'activité destruction:

if (finish) { 
    mActivities.remove(id); //--> mActivities should remove the id 
    mActivityArray.remove(r); //--> mActivitiesArray should remove the 'r object' (LocalActivityRecord) 
} 

Bien qu'ils disent qu'il est corrigé pour Froyo mais je l'ai encore rencontré sur une galaxie Samsung S2 en cours d'exécution 2.3.3