【问题标题】:The Activity's LayoutInflater already has a Factory installed so we can not install AppCompat'sActivity 的 LayoutInflater 已经安装了 Factory,所以我们无法安装 AppCompat 的
【发布时间】:2016-02-29 22:27:18
【问题描述】:

我在我的应用中使用 AppCompat 库 (com.android.support:appcompat-v7:22.1.0)。我在片段中创建了一个 ActionBar。当我单击菜单项时,它会显示一个警报对话框。这是我的代码:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
        case R.id.action_new:
            showFilterDialog();
            return true;
        case R.id.action_send:
            new sendInventoryTask().execute();
            return true;           
        default:
            return super.onOptionsItemSelected(item);
    }
}

还有我的 showInventoryDialog 方法:

private void showFilterInventoryDialog() {
    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());

    LayoutInflater inflater= getActivity().getLayoutInflater();

    View v = inflater.inflate(R.layout.dialog_filter_inventory,null);
    alert.setView(v);
    alert.setTitle(getResources().getString(R.string.filters));
    alert.setPositiveButton(getResources().getString(R.string.filter), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            // TODO
        }

    });

    alert.setNegativeButton(getResources().getString(R.string.cancel), null);
    alert.show();
}

一切正常,但是当我点击菜单项时,logcat 显示错误:

I/AppCompatDelegate:Activity 的 LayoutInflater 已经安装了 Factory,所以我们无法安装 AppCompat 的

如何解决?

【问题讨论】:

  • 你的activity类扩展了什么类?
  • MainActivity 扩展 AppCompatActivity

标签: android android-appcompat


【解决方案1】:

据我所知,每次显示由AlertDialog.Builder 创建的对话框时,appcompat 23.1.1 都会在AppCompatDelegateImplV7 中调用installViewFactory()

调用栈:

在 android.support.v7.app.AppCompatDelegateImplV7.installViewFactory(AppCompatDelegateImplV7.java:970) 在 android.support.v7.app.AppCompatDialog.onCreate(AppCompatDialog.java:58) 在 android.support.v7.app.AlertDialog.onCreate(AlertDialog.java:239) 在 android.app.Dialog.dispatchOnCreate(Dialog.java:361) 在 android.app.Dialog.show(Dialog.java:262) 在 android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:902)

    @Override
    public void installViewFactory() {
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        if (layoutInflater.getFactory() == null) {
            LayoutInflaterCompat.setFactory(layoutInflater, this);
        } else {
            Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed"
                    + " so we can not install AppCompat's");
        }
    }

如您所见,一旦工厂设置完毕,它只会记录信息性消息。忽略它似乎很安全,但是当它填满你的日志时会很烦人。

【讨论】:

    【解决方案2】:

    在这种情况下,您需要使用主题上下文,即,而不是

    new AlertDialog.Builder(getActivity());

    你必须这样做

    new AlertDialog.Builder(getSupportActionBar().getThemedContext());
    

    此外,您还需要遵循此处给出的父主题和 windowActionBar 提示 - support.v7.app.AlertDialog throws NullPointerException on dismiss

    【讨论】:

    • 这似乎不适用于 L 或 M 设备上的最新 AppCompat。
    • 这没有任何作用,我仍然收到logcat消息。
    【解决方案3】:

    解决方案 - 错误“活动的 LayoutInflater 已经安装了工厂,因此我们无法安装 AppCompat”也可能是由于代码不正确。在我的情况下,代码调用了两次“super.onCreate(savedInstanceState)”(代码错误),一旦重复调用被删除,错误就解决了。

    这是我的错误日志:

    02-29 04:54:40.706 4417-4417/com.projects.ajay.example2 I/AppCompatDelegate: The Activity's LayoutInflater already has a Factory installed so we can not install AppCompat's
    02-29 04:54:40.709 4417-4417/? D/AndroidRuntime: Shutting down VM
    02-29 04:54:40.715 4417-4417/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.projects.ajay.example2, PID: 4417
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.projects.ajay.example2/com.projects.ajay.example2.MainActivity}: java.lang.IllegalStateException: Already attached
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2331)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2393)
        at android.app.ActivityThread.access$800(ActivityThread.java:151)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5351)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
     Caused by: java.lang.IllegalStateException: Already attached
        at android.support.v4.app.FragmentManagerImpl.attachController(FragmentManager.java:2025)
        at android.support.v4.app.FragmentController.attachHost(FragmentController.java:95)
        at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:276)
        at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:61)
        at com.projects.ajay.example2.MainActivity.onCreate(MainActivity.java:24)
        at android.app.Activity.performCreate(Activity.java:6020)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2284)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2393) 
        at android.app.ActivityThread.access$800(ActivityThread.java:151) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:135) 
        at android.app.ActivityThread.main(ActivityThread.java:5351) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:372) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703) 
    02-29 04:54:40.727 4417-4417/? I/Process: Sending signal. PID: 4417 SIG: 9
    

    【讨论】:

      【解决方案4】:

      改变

      inflater.inflate(R.layout.dialog_filter_inventory,null);
      

      inflater.inflate(R.layout.dialog_filter_inventory,null,false);
      

      在膨胀 Dialog 的情况下,我们不希望它附加到指定的 ViewGroup (== null)。

      这会有所帮助。

      第二次尝试

      信息日志由AppCompatDelegateImplV7中的以下代码抛出:

      @Override
      public void installViewFactory() {
          LayoutInflater layoutInflater = LayoutInflater.from(mContext);
          if (layoutInflater.getFactory() == null) {
              LayoutInflaterCompat.setFactory(layoutInflater, this);
          } else {
              Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed"
                      + " so we can not install AppCompat's");
          }
      }
      

      可能是您在代码中更早的地方安装了工厂吗?

      【讨论】:

      • 我做了更改,但还是一样
      • 您使用的是标准版还是 v7 版的 AlertDialog?
      • 我正在导入 android.support.v7.app.AlertDialog
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-07
      • 2020-01-20
      • 2017-05-14
      • 1970-01-01
      • 2019-10-10
      相关资源
      最近更新 更多