Android ActivityGroup - NullPointerException

后端 未结 3 1860
耶瑟儿~
耶瑟儿~ 2021-01-16 20:27

I\'m trying to use activity groups - since I use tabs, and want to have the tabs when loading and activity after the list item was clicked,. but I\'m getting nullpointerexce

3条回答
  •  长情又很酷
    2021-01-16 20:40

    Came across the same issue and it seems that there is(or was) a bug with the LocalActivityManager that occurs when you're trying to (re)start an Activity with the same ID as a previously destroyed Activity. It will simply return null as Window, because of a bug inside the destroyActivity method. The workaround I'm using, uses reflection to properly destroy a activity (detailed explanation after the workaround) :

    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 mActivities = (Map)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 mActivityArray = (ArrayList)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;
    }
    
    
    

    This is a workaround because the LocalActivityManager.destroyActivity(...) contains a bug in several API-versions. The method doesn't remove the Activity properly from its HashMap's (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;
         } 
    

    the if(finish) statement should be as followed to remove the LocalActivityRecord of the activity being destroyed:

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

    Although they say it's being fixed for Froyo but I still encountered it on a Samsung galaxy S2 running 2.3.3

    提交回复
    热议问题