Android ActivityGroup - NullPointerException - PullRequest
       25

Android ActivityGroup - NullPointerException

0 голосов
/ 06 февраля 2011

Я пытаюсь использовать группы действий - поскольку я использую вкладки и хочу иметь вкладки при загрузке и активности после нажатия на элемент списка ,. но я получаю nullpointerexception в следующей строке:

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

Код это ...

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);
        }
....

обновление: такова моя групповая активность: я не смог найти, в чем проблема.,

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);
    }
}

Ответы [ 3 ]

1 голос
/ 23 марта 2011

У меня была такая же проблема.Чтобы решить эту проблему, я разложил линию множественных вызовов на три строки, как и предлагал первый ответ:

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

Затем обнаружил, что первая строка является проблемной.Поскольку я вызываю ActivityOne из действия за пределами группы действий (это действие на другой вкладке), статический "activityGroup.group ...." еще не был инициализирован.Таким образом, довольно клёвое исправление состоит в том, чтобы переключиться на эту вкладку и вернуться на эту вкладку перед запуском намерения.Поэтому добавьте следующее прямо перед кодом выше:

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

Это сработало, и вы не можете видеть переключатель табуляции.Возможно, более аккуратным решением было бы переключиться на все вкладки при запуске, чтобы убедиться, что они все инициализированы ...

1 голос
/ 04 октября 2011

Столкнулся с той же проблемой, и кажется, что есть ошибка (или была) с LocalActivityManager, которая возникает, когда вы пытаетесь (повторно) запустить действие с тем же идентификатором, что и ранее уничтоженное действие.Он просто вернет null как Window из-за ошибки внутри метода destroyActivity.Обходной путь, который я использую, использует отражение для правильного уничтожения действия (подробное объяснение после обходного пути):

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;
}

Это обходной путь, потому что LocalActivityManager.destroyActivity (...) содержит ошибку в несколькихAPI-версия.Метод не удаляет Activity должным образом из его 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;
     } 

оператор if (finish) должен быть таким, как следует, чтобы удалить LocalActivityRecord активностиуничтожено:

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

Хотя говорят, что это исправлено для Froyo, но я все еще сталкивался с этим на Samsung galaxy S2 под управлением 2.3.3

0 голосов
/ 06 февраля 2011

не знаю, как вы реализовали ActivityGroup, но группа должна быть статической переменной.

Я нашел это руководство в Google, и оно описывает, как реализовать ActivityGroup. http://blog.henriklarsentoft.com/2010/07/android-tabactivity-nested-activities/

Надеюсь, это поможет, Tobias

...