android中的本地活动管理器问题

android中的本地活动管理器问题,android,android-intent,Android,Android Intent,我在选项卡组活动类中使用本地活动管理器切换选项卡中的各种活动,例如,从我的主选项卡1,我切换以下活动的b/w Act1->Act2->Act3 在act2中,我根据tab1中的数据调用web服务,然后转到ACT3。但当我单击后退按钮时,Act2 onCreate将再次调用 我发现android local activity manager中存在问题,并在destroy方法中实现了相应的修复代码 下面是整个选项卡组活动代码 import java.lang.reflect.Field; imp

我在选项卡组活动类中使用本地活动管理器切换选项卡中的各种活动,例如,从我的主选项卡1,我切换以下活动的b/w Act1->Act2->Act3

在act2中,我根据tab1中的数据调用web服务,然后转到ACT3。但当我单击后退按钮时,Act2 onCreate将再次调用

我发现android local activity manager中存在问题,并在
destroy
方法中实现了相应的修复代码

下面是整个选项卡组活动代码

  import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Map;

import android.app.Activity;
import android.app.ActivityGroup;
import android.app.LocalActivityManager;

import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;

/**
 * The purpose of this Activity is to manage the activities in a tab.
 * Note: Child Activities can handle Key Presses before they are seen here.
 * @author Eric Harlow
 */
public class TabGroupActivity extends ActivityGroup {

    private ArrayList<String> mIdList;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);       
        if (mIdList == null) mIdList = new ArrayList<String>();
    }

    /**
     * This is called when a child activity of this one calls its finish method. 
     * This implementation calls {@link LocalActivityManager#destroyActivity} on the child activity
     * and starts the previous activity.
     * If the last child activity just called finish(),this activity (the parent),
     * calls finish to finish the entire group.
     */
  @Override
  public void finishFromChild(Activity child) {
      LocalActivityManager manager = getLocalActivityManager();
      int index = mIdList.size()-1;

      if (index < 1) {
          finish();
          return;
      }
      System.out.println("Destroy called");
      boolean rt=destroy(mIdList.get(index),manager);
      System.out.println("Destroy called"+rt);
//      manager.destroyActivity(mIdList.get(index), true);
      mIdList.remove(index); index--;
      String lastId = mIdList.get(index);
      Intent lastIntent = manager.getActivity(lastId).getIntent();
      Window newWindow = manager.startActivity(lastId, lastIntent);
      setContentView(newWindow.getDecorView());
  }

  /**
   * Starts an Activity as a child Activity to this.
   * @param Id Unique identifier of the activity to be started.
   * @param intent The Intent describing the activity to be started.
   * @throws android.content.ActivityNotFoundException.
   */
  public void startChildActivity(String Id, Intent intent) {     
      Window window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
      if (window != null) {
          mIdList.add(Id);
          setContentView(window.getDecorView()); 
      }    
  }

  /**
   * The primary purpose is to prevent systems before android.os.Build.VERSION_CODES.ECLAIR
   * from calling their default KeyEvent.KEYCODE_BACK during onKeyDown.
   */
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
      if (keyCode == KeyEvent.KEYCODE_BACK) {
          //preventing default implementation previous to android.os.Build.VERSION_CODES.ECLAIR
          return true;
      }
      return super.onKeyDown(keyCode, event);
  }

  /**
   * Overrides the default implementation for KeyEvent.KEYCODE_BACK 
   * so that all systems call onBackPressed().
   */
  @Override
  public boolean onKeyUp(int keyCode, KeyEvent event) {
      if (keyCode == KeyEvent.KEYCODE_BACK) {
          onBackPressed();
          return true;
      }
      return super.onKeyUp(keyCode, event);
  }

  /**
   * If a Child Activity handles KeyEvent.KEYCODE_BACK.
   * Simply override and add this method.
   */
  public void  onBackPressed  () {
      int length = mIdList.size();
      if ( length > 1) {
          Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
          System.out.println("Activity Being close"+current.getLocalClassName());
          current.finish();
      }  
  }
  public boolean destroy(String id,LocalActivityManager activityManager) {

        if(activityManager != null){
            activityManager.destroyActivity(id, false);
            // http://code.google.com/p/android/issues/detail?id=12359
            // http://www.netmite.com/android/mydroid/frameworks/base/core/java/android/app/LocalActivityManager.java
            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(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) {
                e.printStackTrace();
            }
            return true;
        }
        return false;
    }

}
import java.lang.reflect.Field;
导入java.util.ArrayList;
导入java.util.Map;
导入android.app.Activity;
导入android.app.ActivityGroup;
导入android.app.LocalActivityManager;
导入android.content.Intent;
导入android.os.Bundle;
导入android.view.KeyEvent;
导入android.view.Window;
/**
*此活动的目的是管理选项卡中的活动。
*注意:子活动可以在此处显示之前处理按键。
*@作者埃里克·哈洛
*/
公共类选项卡GroupActivity扩展了ActivityGroup{
私有ArrayList中间列表;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
如果(mIdList==null)mIdList=new ArrayList();
}
/**
*当此活动的子活动调用其finish方法时,将调用它。
*此实现在子活动上调用{@link LocalActivityManager#destroyActivity}
*并开始上一个活动。
*如果最后一个子活动刚刚调用finish(),则此活动(父活动),
*调用finish以完成整个组。
*/
@凌驾
public void finishFromChild(活动子项){
LocalActivityManager=getLocalActivityManager();
int index=mIdList.size()-1;
如果(指数<1){
完成();
返回;
}
System.out.println(“调用销毁”);
布尔rt=destroy(mIdList.get(index),manager);
System.out.println(“销毁称为”+rt);
//manager.destroyment(mIdList.get(index),true);
删除(索引);索引--;
字符串lastId=mIdList.get(索引);
Intent lastIntent=manager.getActivity(lastId).getIntent();
Window newWindow=manager.startActivity(lastId,lastIntent);
setContentView(newWindow.getDecorView());
}
/**
*将活动作为此活动的子活动启动。
*@param Id要启动的活动的唯一标识符。
*@param intent描述要启动的活动的意图。
*@抛出android.content.ActivityNotFoundException。
*/
public void startChildActivity(字符串Id,意图){
Window Window=getLocalActivityManager().startActivity(Id,intent.addFlags(intent.FLAG\u ACTIVITY\u CLEAR\u TOP));
如果(窗口!=null){
添加(Id);
setContentView(window.getDecorView());
}    
}
/**
*主要目的是防止android.os.Build.VERSION_CODES.ECLAIR之前的系统
*在onKeyDown期间调用默认的KeyEvent.KEYCODE_。
*/
@凌驾
公共布尔onKeyDown(int-keyCode,KeyEvent事件){
if(keyCode==KeyEvent.keyCode\u BACK){
//阻止android.os.Build.VERSION_CODES.ECLAIR之前的默认实现
返回true;
}
返回super.onKeyDown(keyCode,event);
}
/**
*重写KeyEvent.KEYCODE\u的默认实现
*因此所有系统都调用onBackPressed()。
*/
@凌驾
公共布尔onKeyUp(int-keyCode,KeyEvent事件){
if(keyCode==KeyEvent.keyCode\u BACK){
onBackPressed();
返回true;
}
返回super.onKeyUp(keyCode,event);
}
/**
*如果子活动处理KeyEvent.KEYCODE\u返回。
*只需重写并添加此方法。
*/
反压时的公共无效(){
int length=mIdList.size();
如果(长度>1){
当前活动=getLocalActivityManager().getActivity(mIdList.get(length-1));
System.out.println(“正在关闭的活动”+current.getLocalClassName());
当前。完成();
}  
}
公共布尔销毁(字符串id,LocalActivityManager activityManager){
如果(activityManager!=null){
activityManager.destroyActivity(id,false);
// http://code.google.com/p/android/issues/detail?id=12359
// http://www.netmite.com/android/mydroid/frameworks/base/core/java/android/app/LocalActivityManager.java
试一试{
最终字段mActivitiesField=LocalActivityManager.class.getDeclaredField(“mActivities”);
if(mActivitiesField!=null){
mActivitiesField.setAccessible(true);
@抑制警告(“未选中”)
最终映射mActivities=(Map)mActivitiesField.get(activityManager);
if(mActivities!=null){
mActivities.remove(id);
}
最终字段mActivityArrayField=LocalActivityManager.class.getDeclaredField(“mActivityArray”);
如果(mActivityArrayField!=null){
mActivityArrayField.setAccessible(true);
@抑制警告(“未选中”)
最终ArrayList mActivityArray=(ArrayList)mActivityArrayField.get(activityManager);
if(mActivityArray!=null){
用于(对象记录:mActivityArray){
最终字段idField=record.getClass().getDeclaredField(“id”);
if(idField!=null){
idField.setAccessible(true);
最终字符串_id=(字符串)idField.get(记录);
如果(id等于(_id)){
mActivityArray.remove(记录);
 @Override
  public void finishFromChild(Activity child) {
      LocalActivityManager manager = getLocalActivityManager();
      int index = mIdList.size()-1;

      if (index < 1) {
          finish();
          return;
      }
      System.out.println("Destroy called");
      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.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP));
        setContentView(newWindow.getDecorView());
  }