问题
I'm using AppCompat library (com.android.support:appcompat-v7:22.1.0) in my app. I created an ActionBar in a fragment. When I click in a menu item it shows an Alert Dialog. Here is my code:
@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);
}
}
And my showInventoryDialog method:
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();
}
Everything works fine, but when I click on menu item, the logcat shows me an error:
I/AppCompatDelegate﹕ The Activity's LayoutInflater already has a Factory installed so we can not install AppCompat's
How to solve this?
回答1:
You are required to use the themed context in this case, i.e. instead of
new AlertDialog.Builder(getActivity());
you have to do
new AlertDialog.Builder(getSupportActionBar().getThemedContext());
Besides, you also need to follow the parent theme and windowActionBar tip given here - support.v7.app.AlertDialog throws NullPointerException on dismiss
回答2:
From what I can tell, appcompat 23.1.1 calls installViewFactory() in AppCompatDelegateImplV7 every time you show a dialog created by AlertDialog.Builder.
Call Stack:
at android.support.v7.app.AppCompatDelegateImplV7.installViewFactory(AppCompatDelegateImplV7.java:970) at android.support.v7.app.AppCompatDialog.onCreate(AppCompatDialog.java:58) at android.support.v7.app.AlertDialog.onCreate(AlertDialog.java:239) at android.app.Dialog.dispatchOnCreate(Dialog.java:361) at android.app.Dialog.show(Dialog.java:262) at 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");
}
}
As you can see, once the factory is already set it just logs the informational message. It seems pretty safe to ignore, but it can get annoying when it fills up your logs.
回答3:
Solution - The error "The Activity's LayoutInflater already has a Factory installed so we can not install AppCompat's" could also be due to incorrect code. In my case the code was calling "super.onCreate(savedInstanceState)" twice (code error) and once the duplicate call was removed the error was resolved.
This is my error log:
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:
Change
inflater.inflate(R.layout.dialog_filter_inventory,null);
to
inflater.inflate(R.layout.dialog_filter_inventory,null,false);
In case of inflating a Dialog, we don't want it to attach to the specified ViewGroup (== null).
This could help.
Second try
The info-log is thrown by the following code in 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");
}
}
Could it be you installed a Factory somewere earlier in your code?
来源:https://stackoverflow.com/questions/31677552/the-activitys-layoutinflater-already-has-a-factory-installed-so-we-can-not-inst