Activity、FragmentActivity、AppCompatActivityの違い

15681 ワード

Activity


Activityは最も基本的なもので、他のクラスの直接または間接の親です.Activityではシステムに付属しているhost Fragment(API Level 11に追加)しか使用できず、getFragmentManagerメソッドに対応してActivityとFragment間のインタラクションを制御します.

FragmentActivity


v 4パッケージにFragmentActivityを導入し、FragmentActivityはActivityから間接的に継承され、v 4パッケージのsupport Fragmentのサポートを提供します.FragmentActivityでは、getSupportFragmentManagerメソッドを使用してsupport Fragmentのインタラクションを処理する必要があります.support Fragmentのネストを扱うこともできます.
Known limitations:

*  When using the `` tag, this implementation can not use the parent view's ID as the new fragment's ID. You must explicitly specify an ID (or tag) in the ``. 

AppCompatActivity


AppCompatActivityは、ActionBarActivityの代わりにFragmentActivityから継承されます.AppCompatActivityはActionBar機能をサポートし、ToolBarの使用を推奨します.AppCompatActivityは、Material Designスタイルコントロールをサポートするのに便利です.

シーンの操作


stack overflowの回答を参照してください.Activity is the baseline. Every activity inherits from Activity, directly or indirectly.
FragmentActivity is for use with the backport of fragments found in the support-v4 and support-v13 libraries. The native implementation of fragments was added in API Level 11, which is lower than your proposed minSdkVersion values. The only reason why you would need to consider FragmentActivity specifically is if you want to use nested fragments (a fragment holding another fragment), as that was not supported in native fragments until API Level 17.
AppCompatActivity is from the appcompat-v7 library. Principally, this offers a backport of the action bar. Since the native action bar was added in API Level 11, you do not need AppCompatActivity for that. However, current versions of appcompat-v7 also add a limited backport of the Material Design aesthetic, in terms of the action bar and various widgets. There are pros and cons of using appcompat-v7, well beyond the scope of this specific Stack Overflow answer.
ActionBarActivity is the old name of the base activity from appcompat-v7. For various reasons, they wanted to change the name. Unless some third-party library you are using insists upon an ActionBarActivity, you should prefer AppCompatActivity over ActionBarActivity.
So, given your minSdkVersion in the 15-16 range:
  • If you want the backported Material Design look, use AppCompatActivity
  • If not, but you want nested fragments, use FragmentActivity
  • If not, use Activity

  • Just adding from comment as note: AppCompatActivity extends FragmentActivity, so anyone who needs to use features of FragmentActivity can use AppCompatActivity.

    AppCompatActivityでのAppCompatシリーズコンポーネントの構造と置き換え


    AppCompatActivityではAppCompatDelegateでActivityを拡張します.AppCompatDelegateは任意のActivityで使用でき、適切なライフサイクルメソッドにリンクする必要があります.具体的には公式文書を参照してくださいhttps://developer.android.com/reference/android/support/v7/app/AppCompatDelegateまたはAppCompatDelegateのソースコードコメント.
    AppCompatActivityのonCreateメソッドでは、AppCompatDelegate(ベースクラス)のcreateメソッドを呼び出してインスタンスを作成しdelegateを呼び出す.installViewFactory()factoryを設定します.
    @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) { final AppCompatDelegate delegate = getDelegate(); delegate.installViewFactory(); delegate.onCreate(savedInstanceState); ...... super.onCreate(savedInstanceState); } 

    AppCompatDelegateサブクラスインスタンスを作成するコードは、携帯電話のアンドロイド版に基づいて本来異なるサブクラスインスタンスを作成する
    private static AppCompatDelegate create(Context context, Window window,
                AppCompatCallback callback) {
            if (Build.VERSION.SDK_INT >= 24) { return new AppCompatDelegateImplN(context, window, callback); } else if (Build.VERSION.SDK_INT >= 23) { return new AppCompatDelegateImplV23(context, window, callback); } else if (Build.VERSION.SDK_INT >= 14) { return new AppCompatDelegateImplV14(context, window, callback); } else if (Build.VERSION.SDK_INT >= 11) { return new AppCompatDelegateImplV11(context, window, callback); } else { return new AppCompatDelegateImplV9(context, window, callback); } } 

    android 6.0(API 23)を例に、AppCompatDelegateインスタンスオブジェクトの作成を追跡します.AppCompatDelegateImplV 23は、AppCompatDelegateImplV 9を間接的に継承し、LayoutInflaterを実現する.Factory 2インタフェース.
    AppCompatDelegateImplV 9のinstallViewFactoryがLayoutInflaterCompatを呼び出しました.setFactory 2は、自身のFactory 2実装を設定しています.
        @Override
        public void installViewFactory() { LayoutInflater layoutInflater = LayoutInflater.from(mContext); if (layoutInflater.getFactory() == null) { LayoutInflaterCompat.setFactory2(layoutInflater, this); } else { if (!(layoutInflater.getFactory2() instanceof AppCompatDelegateImplV9)) { Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed" + " so we can not install AppCompat's"); } } } 

    AppCompatActivityがviewを作成すると、PhoneWindow->LayoutInflater(createViewFromTag)によってFactory 2を実装するonCreateViewメソッドに入ります.LayoutInflater setFactoryステップsetContentView呼び出しフロー分析を参照
        /**
         * From {@link LayoutInflater.Factory2}.
         */
        @Override
        public final View onCreateView(View parent, String name, Context context, AttributeSet attrs) { // First let the Activity's Factory try and inflate the view final View view = callActivityOnCreateView(parent, name, context, attrs); if (view != null) { return view; } // If the Factory didn't handle it, let our createView() method try return createView(parent, name, context, attrs); } 

    AppCompatActivityがFactoryを設定していない場合は、DelegateインスタンスのcreateViewメソッドを呼び出してviewを作成します.
    @Override
        public View createView(View parent, final String name, @NonNull Context context, @NonNull AttributeSet attrs) { if (mAppCompatViewInflater == null) { mAppCompatViewInflater = new AppCompatViewInflater(); } boolean inheritContext = false; if (IS_PRE_LOLLIPOP) { inheritContext = (attrs instanceof XmlPullParser) // If we have a XmlPullParser, we can detect where we are in the layout ? ((XmlPullParser) attrs).getDepth() > 1 // Otherwise we have to use the old heuristic : shouldInheritContext((ViewParent) parent); } return mAppCompatViewInflater.createView(parent, name, context, attrs, inheritContext, IS_PRE_LOLLIPOP, /* Only read android:theme pre-L (L+ handles this anyway) */ true, /* Read read app:theme as a fallback at all times for legacy reasons */ VectorEnabledTintResources.shouldBeUsed() /* Only tint wrap the context if enabled */ ); } 

    上記のコードから分かるように、Delegateインスタンスは、AppCompatViewInflaterのcreateViewを呼び出して、特定のviewの描画を完了する.
    public final View createView(View parent, final String name, @NonNull Context context, @NonNull AttributeSet attrs, boolean inheritContext, boolean readAndroidTheme, boolean readAppTheme, boolean wrapContext) { final Context originalContext = context; // We can emulate Lollipop's android:theme attribute propagating down the view hierarchy // by using the parent's context if (inheritContext && parent != null) { context = parent.getContext(); } if (readAndroidTheme || readAppTheme) { // We then apply the theme on the context, if specified context = themifyContext(context, attrs, readAndroidTheme, readAppTheme); } if (wrapContext) { context = TintContextWrapper.wrap(context); } View view = null; // We need to 'inject' our tint aware Views in place of the standard framework versions switch (name) { case "TextView": view = new AppCompatTextView(context, attrs); break; case "ImageView": view = new AppCompatImageView(context, attrs); break; case "Button": view = new AppCompatButton(context, attrs); break; case "EditText": view = new AppCompatEditText(context, attrs); break; case "Spinner": view = new AppCompatSpinner(context, attrs); break; case "ImageButton": view = new AppCompatImageButton(context, attrs); break; case "CheckBox": view = new AppCompatCheckBox(context, attrs); break; case "RadioButton": view = new AppCompatRadioButton(context, attrs); break; case "CheckedTextView": view = new AppCompatCheckedTextView(context, attrs); break; case "AutoCompleteTextView": view = new AppCompatAutoCompleteTextView(context, attrs); break; case "MultiAutoCompleteTextView": view = new AppCompatMultiAutoCompleteTextView(context, attrs); break; case "RatingBar": view = new AppCompatRatingBar(context, attrs); break; case "SeekBar": view = new AppCompatSeekBar(context, attrs); break; } if (view == null && originalContext != context) { // If the original context does not equal our themed context, then we need to manually // inflate it using the name so that android:theme takes effect. view = createViewFromTag(context, name, attrs); } if (view != null) { // If we have created a view, check its android:onClick checkOnClickListener(view, attrs); } return view; } 

    上記のコードでは、AppCompatActivityにおけるTextViewなどのコンポーネントが、AppCompatTextViewなどに置き換えられ、AppCompatTextViewシリーズのコンポーネントの特性を利用することができることがわかる.ただし、カスタムビューを書く場合は、AppCompatコンポーネントを手動で使用する必要があります.

     


    AppCompatTextViewのヒントThis will automatically be used when you use TextView in your layouts and the top-level activity/dialog is provided by appcompat.You should only need to manually use this class when writing custom views.
    参照ドキュメント:https://stackoverflow.com/questions/31297246/activity-appcompatactivity-fragmentactivity-and-actionbaractivity-when-to-us
    作者:zizi 192
    リンク:https://www.jianshu.com/p/9d590c478828
    出典:簡書
    簡書の著作権は著者の所有であり、いかなる形式の転載も著者に連絡して授権を得て出典を明記してください.
    転載先:https://www.cnblogs.com/Jeely/p/11063435.html