Android问题中LocalActivityManager类中的destroyActivity()错误

Android问题中LocalActivityManager类中的destroyActivity()错误,android,Android,我有一个选项卡活动,在选项卡中,我使用活动组。使用LocalActivityManger, 我正试图使用LocalActivityManger类中提供的以下函数调用销毁Activty manager.destroyActivity(mIdList.get(index), true); 在代码中。但后来我发现Android impl中有一个bug 问题的确切根源在LocalActivityManager.java中的以下代码块中: public Window de

我有一个选项卡活动,在选项卡中,我使用活动组。使用LocalActivityManger, 我正试图使用LocalActivityManger类中提供的以下函数调用销毁Activty

               manager.destroyActivity(mIdList.get(index), true); 
在代码中。但后来我发现Android impl中有一个bug

问题的确切根源在LocalActivityManager.java中的以下代码块中:

public Window destroyActivity(String id, boolean finish) {
LocalActivityRecord r = mActivities.get(id);
Window win = null;
if (r != null) {
    win = performDestroy(r, finish);
    if (finish) {
        mActivities.remove(r);
    }
}
return win;
} 变量mActivities是包含活动记录的hashmap,它使用传递到startActivity()的id作为键。在该方法中,为键传入的对象是LocalActivityRecord,而不是id字符串。这导致hashmap找不到条目,因此无法删除它

更多信息请参考此链接

我找到了解决此问题的方法,我使用以下功能来解决此问题。

       public boolean destroy(String id) {

        if(manager != null){
            manager.destroyActivity(id, false);
            try {
                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(manager);
                    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(manager);
                        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) {
                e.printStackTrace();
            }
            return true;
        }
        return false;
    }
公共布尔销毁(字符串id){
if(manager!=null){
经理。活动(id,假);
试一试{
最终字段mActivitiesField=LocalActivityManager.class.getDeclaredField(“mActivities”);
if(mActivitiesField!=null){
mActivitiesField.setAccessible(true);
@抑制警告(“未选中”)
最终映射mActivities=(Map)mActivitiesField.get(manager);
if(mActivities!=null){
mActivities.remove(id);
}
最终字段mActivityArrayField=LocalActivityManager.class.getDeclaredField(“mActivityArray”);
如果(mActivityArrayField!=null){
mActivityArrayField.setAccessible(true);
@抑制警告(“未选中”)
最终ArrayList mActivityArray=(ArrayList)mActivityArrayField.get(manager);
if(mActivityArray!=null){
用于(对象记录:mActivityArray){
最终字段idField=record.getClass().getDeclaredField(“id”);
if(idField!=null){
idField.setAccessible(true);
最终字符串_id=(字符串)idField.get(记录);
如果(id等于(_id)){
mActivityArray.remove(记录);
打破
}
}
}
}
}
}
}捕获(例外e){
e、 printStackTrace();
}
返回true;
}
返回false;
}
现在的问题是,这个补丁在Android API版本2.1、2.2和2.3中运行良好,但我在3.0中进行了测试。但它在这方面失败了。没有例外。

       public boolean destroy(String id) {

        if(manager != null){
            manager.destroyActivity(id, false);
            try {
                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(manager);
                    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(manager);
                        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) {
                e.printStackTrace();
            }
            return true;
        }
        return false;
    }
我想知道在哪个API版本中修复了此错误。

以及我可以对此进行哪些修复,以便它在2.1之后的所有API版本中都能正常工作。

       public boolean destroy(String id) {

        if(manager != null){
            manager.destroyActivity(id, false);
            try {
                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(manager);
                    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(manager);
                        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) {
                e.printStackTrace();
            }
            return true;
        }
        return false;
    }

谢谢你

你能告诉我在哪里使用这个方法吗?你好,karthi,你应该从finishFromChild()method@Override public void finishFromChild(Activity child){LocalActivityManager=getLocalActivityManager();int index=mIdList.size()-1;if(index<1){finish();return;}destroy(mIdList.get(index),manager);()mIdList.remove(index);index--;String lastId=mIdList.get(index);Intent lastIntent=manager.getActivity(lastId.getIntent();Window newWindow=manager.startActivity(lastId,lastIntent);setContentView(newWindow.getDecorView());}我已经粘贴了finishFromChild方法(Activity child)尝试使用它。感谢您的回复,但正如您指定的那样,我实现了该代码,但仍然执行了两次创建,版本:2.1。您可以帮助我吗。参考此网站,我发布了选项卡组活动类代码。