2013-10-01 4 views
1

Я работаю над своим проектом Android, разрабатывающим HTC Desire (Gingerbread 2.3.7) и Google Nexus 7 (Jelly Bean 4.3). Мне нужно отправить некоторые данные из MainActivity в InfoActivity, поэтому я использую намерение. В этой InfoActivity у меня также есть пункт меню на панели действий, чтобы обновить информацию.ActionBar пункт меню по-разному

enter image description here

В InfoActivity я показать данные пользователю. Но это не проблема, проблема с меню. Посмотрите на следующий код:

public class ShowInfoActivity extends ActionBarActivity { 

    private MenuItem menuItem = null; 
    // ... 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // ... 
     new OneTask().execute(...); 
     // ... 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     case R.id.refresh: 
      menuItem = item; 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
     } 
    } 

    private class OneTask extends AsyncTask<Object, Void, String> { 
     // ... 
     @Override 
     protected void onPreExecute() { 
      MenuItemCompat.setActionView(menuItem, 
         R.layout.actionbar_indeterminate_progress); 
      MenuItemCompat.expandActionView(menuItem); 
     } 
     // ... 
     @Override 
     protected void onPostExecute(String result) { 
      MenuItemCompat.collapseActionView(menuItem); 
      MenuItemCompat.setActionView(menuItem, null); 
     } 
    } 

Очевидно, что в первый раз она выполняется, MENUITEM = NULL, поэтому он должен врезаться. Невероятно, что в HTC он отлично работает, но в Nexus он явно падает. Почему это отличается от устройств?

PS: Я уже решил, но я хочу знать, почему такое поведение ...

ответ

1

В случае сомнений всегда проверяйте исходный код. Если вы посмотрите на MenuItemCompat.java вы увидите, что он переключается на основе уровня API, как так:

static final MenuVersionImpl IMPL; 
    static { 
     final int version = android.os.Build.VERSION.SDK_INT; 
     if (version >= 14) { 
      IMPL = new IcsMenuVersionImpl(); 
     } else if (version >= 11) { 
      IMPL = new HoneycombMenuVersionImpl(); 
     } else { 
      IMPL = new BaseMenuVersionImpl(); 
     } 
    } 

базовый метод setActionView для реализации базового (который используется для 2.3 устройств) просто возвращает MenuItem, так что это не будет когда-либо выбросить исключение:

@Override 
public MenuItem setActionView(MenuItem item, View view) { 
    return item; 
} 

HoneycombMenuVersionImpl, с другой стороны, делегаты другого класса:

 @Override 
     public boolean setShowAsAction(MenuItem item, int actionEnum) { 
      MenuItemCompatHoneycomb.setShowAsAction(item, actionEnum); 
      return true; 
     } 

и класс делегата АТТ фактически лишает вызвать фактический метод на MenuItem, который будет бросать исключение:

public static void setShowAsAction(MenuItem item, int actionEnum) { 
    item.setShowAsAction(actionEnum); 
} 

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

0

setActionView()/collapseActionView() являются носителями функции в Android 4 ... проходящее нуль MenuItem, безусловно, будет неодобрительно ,

На вашем устройстве Android 2.3 библиотека совместимости (android.support.v4) имеет собственные внутренние реализации setActionView()/collapseActionView(), которые, вероятно, более устойчивы к плохому вводу.

 Смежные вопросы

  • Нет связанных вопросов^_^