2015-12-29 1 views
2

Я создал абстрактный класс, чтобы предотвратить избыточный код в каждом из моих действий.Аннотация класс, чтобы избавиться от избыточного кода в действиях

public abstract class MyGeneralizedActivity extends Activity { 
     @Override 
     protected void onCreate(Bundle savedInstanceState) 
     { 
      super.onCreate(savedInstanceState); 
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
     } 

     @Override 
     public void attachBaseContext(Context newBase) { 
      super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); 
     } 
     //... 
} 

Я был прекрасно, делая это:

public class MyActivity extends MyGeneralizedActivity{...} 

Но теперь я попал в точку, где я должен простираться от MyActivityFragmentActivity. Это означает, что я больше не могу распространяться от MyGeneralizedActivity.

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

EDIT
Только путем расширения MyGeneralizedActivity от FragmentActivity не решит мою проблему. например TabActivity приведет к той же проблеме.

UPDATE
Для тех, кто может быть заинтересован в решении с той же проблемой в Android я нашел простое решение. Существует класс Application, который обеспечивает, помимо прочего, интерфейс ActivityLifecycleCallbacks. Он делает именно то, что мне нужно, позволяя нам перехватывать и добавлять ценность в важные события для всех видов деятельности.

Все, что вам нужно сделать, это расширить класс Android Application и создать частный класс, в котором реализуется ActivityLifecycleCallbacks.
Не забудьте добавить/переименовать приложение в файле AndroidManifests:

<application 
    android:name=".application.MyApplication" 
    //... 
/> 
+0

Вы можете создать интерфейс с методом по умолчанию при использовании Java 8. Затем вы можете реализовать несколько интерфейсов таким образом и получить желаемый результат. –

+3

Данный ['FragmentActivity' сам является подклассом' Activity'] (http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html), есть ли причина, по которой вы не можете просто make 'MyGeneralizedActivity расширяет FragmentActivity'? – PPartisan

+1

Почему вы не распространяетесь на AppCompatActivity? Кроме того, просто любопытно, какое у вас требование для FragmentActivity? – AdamMc331

ответ

0

См FragmentActivity source code. FragmentActivity распространяется Activity класс. Я думаю, вы должны попробовать и посмотреть.

Удачи.

+0

@Tazqir см. Мой отредактированный начальный пост. – spyfx

0

Вы можете создать интерфейс с использованием метода по умолчанию при использовании Java 8. Тогда вы можете реализовать несколько интерфейсов таким образом и получить желаемый результат.

см Подробности: Interface with default methods vs Abstract class in Java 8

+0

Можете ли вы подробнее рассказать об этом предложении? Идеально привести пример. Хотя верно, что можно создать реализацию по умолчанию для интерфейсов в Java 8, существуют ограничения (например, у вас нет доступа к состоянию экземпляра), поэтому это не обязательно решение. – vpiTriumph

1

Как и FragmentActivityMyGeneralizedActivity и классы и интерфейсы не существует никакого способа создать тип, который является подтипом обоих.

Java ограничивает вас одиночным наследованием, поэтому, если вы зависите от реализации совместного использования, которая включена в два класса, ваш лучший выбор здесь опирается на композицию.

Например:

public class MyActivity extends Activity { 
    FragmentActivity fragmentActivity; 
    MyGeneralizedActivity myGeneralizedActivity; 

    public MyActivity(FragmentActivity fragmentActivity, MyGeneralizedActivity myGeneralizedActivity) { 
    this.fragmentActivity = fragmentActivity; 
    this.myGeneralizedActivity = myGeneralizedActivity; 
    } 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    this.fragmentActivity.onCreate(savedInstanceState); 
    this.myGeneralizedActivity.onCreate(savedInstanceState); 
    //... 
    } 

    @Overridepublic void attachBaseContext(Context newBase) { 
    this.fragmentActivity.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); 
    this.myGeneralizedActivity.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); 
    //... 
    } 

} 
+1

Я не думаю, что вы можете перегрузить конструктор класса 'Activity' таким образом. – PPartisan

+0

Это хороший момент. Я очищу свое предложение. – vpiTriumph

+0

При ближайшем рассмотрении 'Activity', имеет конструктор по умолчанию, поэтому вы должны иметь возможность создавать подтип' Activity' точно так же, как я предложил, если я не пропущу что-то. – vpiTriumph

1

Это кажется проблемой для Decorator Pattern.

Намерение

  • Присоединить дополнительные обязанности к объекту динамически.Декораторы обеспечивают гибкую альтернативу подклассу для расширения функциональности.
  • Клиентское обозначение основного объекта путем рекурсивного его обертывания.
  • Обернуть подарок, положить его в коробку и обернуть коробку.

Проблема

Вы хотите добавить поведение или состояние отдельных объектов во время выполнения. Наследование невозможно, поскольку оно является статичным и относится ко всему классу.

Структура

Каноническая форма: Decorator Pattern Diagram

Мышление конкретно о вашем случае, поскольку Android API не определяет интерфейс для деятельности, мы могли бы пропустить некоторые бюрократии и просто сделать это в (не так) быстрый и грязный способ:

abstract public class ActivityDecorator extends Activity { 
    protected Activity original; 

    public MyAcitvityDecorator(Activity original) { 
     this.original = original; 
    } 

    protected void onCreate(Bundle savedInstanceState) { 
     this.original.onCreate(savedInstanceState); 
    } 

    /* ... Because there is no better way of doing it in Java, you should do 
    * this for every method in the Activity class: delegate the execution of 
    * the method to the original activity object. 
    * Yes, there is A LOT of methods! 
} 

Затем вы должны создать конкретный декоратора и переопределить причитающиеся методы:

class MyActivityDecorator extends ActivityDecorator { 
     @Override 
     protected void onCreate(Bundle savedInstanceState) 
     { 
      this.original.onCreate(savedInstanceState); 
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
     } 

     @Override 
     public void attachBaseContext(Context newBase) { 
      this.original.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); 
     } 
} 

Затем вы можете использовать его как это:

Activity myActivity = new MyActivityDecorator(new Activity()); 

Поскольку MyAcitvityDecorator является экземпляром Activity, вы можете передать его вокруг seemlessly.

Можно даже цепи декораторы и изменить первоначальный Activity объект так:

Activity myActivity = new MyActivityDecorator(
    new AnotherActivityDecorator(
     new TabActivity() 
    ) 
); 
Смежные вопросы