Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A factory has already been set on this LayoutInflater Exception #155

Closed
bishwash-adhikari opened this issue Apr 8, 2015 · 28 comments · Fixed by #162
Closed

A factory has already been set on this LayoutInflater Exception #155

bishwash-adhikari opened this issue Apr 8, 2015 · 28 comments · Fixed by #162

Comments

@bishwash-adhikari
Copy link

java.lang.RuntimeException: Unable to start activity ComponentInfo{org.titibots.android.ide.remote/org.modebots.android.ide.ui.MainActivity}: java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
at android.view.LayoutInflater.setFactory(LayoutInflater.java:286)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.setFactory(CalligraphyLayoutInflater.java:85)
at android.support.v4.app.Fragment.getLayoutInflater(Fragment.java:935)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:548)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236)
at android.app.Activity.performStart(Activity.java:6006)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

@chrisjenx
Copy link
Owner

You are going to have to give more than that. Code examples: How have you included it in your project? What other libs are you using? Are you using custom layout inflators? are you using the latest version of v4/v7 support libs?

@bishwash-adhikari
Copy link
Author

I am using UXCam lib for UX analytics which is also using custom layout inflators. Is it that if another lib sets LayoutInflater.Factory before Calligraphy then this Exception is thrown.

my project dependencies are :
repositories {
maven{
url 'http://sdk.uxcam.com/android/'
}
}
dependencies {
compile 'com.android.support:support-v4:22.0.0'
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'uk.co.chrisjenx:calligraphy:2.0.2'
compile 'com.jakewharton:butterknife:5.1.2'
compile 'com.uxcam:uxcam:2.0.0@aar'
}

@chrisjenx
Copy link
Owner

Yeah that won't work you can't batch up layout inflaters.
You need to clone/extend your underlying layout inflaters then apply this
on top.

It's meant to do that but without seeing your implementation it's hard to
say.

On Thu, 9 Apr 2015 05:08 Bishwash notifications@github.com wrote:

I am using UXCam lib for UX analytics which is also using custom layout
inflators. Is it that if another lib sets LayoutInflater.Factory before
Calligraphy then this Exception is thrown.

my project dependencies are :
repositories {
maven{
url 'http://sdk.uxcam.com/android/'
}
}
dependencies {
compile 'com.android.support:support-v4:22.0.0'
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'uk.co.chrisjenx:calligraphy:2.0.2'
compile 'com.jakewharton:butterknife:5.1.2'

compile 'com.uxcam:uxcam:2.0.0@aar'

}


Reply to this email directly or view it on GitHub
#155 (comment)
.

@bishwash-adhikari
Copy link
Author

we set LayoutInflators in Application.ActivityLifecycleCallbacks : onActivityCreated method . Is there anyway we can prevent crash

@Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        LayoutInflater layoutInflater = activity.getLayoutInflater();
        final LayoutInflater.Factory existingFactory = layoutInflater.getFactory();
        try {
            Field field = LayoutInflater.class.getDeclaredField("mFactorySet");
            field.setAccessible(true);
            field.setBoolean(layoutInflater, false);
            LayoutInflater.from(activity).setFactory(new UxFactory(existingFactory));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

@chrisjenx
Copy link
Owner

Why are you not cloneing the current layout inflator and setting the
UXFactory on the new one? All layout inflators have to provide that method.

On Fri, 10 Apr 2015 06:52 Bishwash notifications@github.com wrote:

we set LayoutInflators in Application.ActivityLifecycleCallbacks :
onActivityCreated method . Is there any whey we can prevent crash

@OverRide
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
LayoutInflater layoutInflater = activity.getLayoutInflater();
final LayoutInflater.Factory existingFactory = layoutInflater.getFactory();
try {
Field field = LayoutInflater.class.getDeclaredField("mFactorySet");
field.setAccessible(true);
field.setBoolean(layoutInflater, false);
LayoutInflater.from(activity).setFactory(new UxFactory(existingFactory));
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}


Reply to this email directly or view it on GitHub
#155 (comment)
.

@talklittle
Copy link

This FC now occurs when using a ViewPager with FragmentStatePagerAdapter in appcompat-v7 v22.1.0.

Calligraphy initialized using super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));

java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
        at android.view.LayoutInflater.setFactory2(LayoutInflater.java:305)
        at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.setFactory2(CalligraphyLayoutInflater.java:96)
        at android.support.v4.view.LayoutInflaterCompatLollipop.setFactory(LayoutInflaterCompatLollipop.java:24)
        at android.support.v4.view.LayoutInflaterCompat$LayoutInflaterCompatImplV21.setFactory(LayoutInflaterCompat.java:49)
        at android.support.v4.view.LayoutInflaterCompat.setFactory(LayoutInflaterCompat.java:79)
        at android.support.v4.app.Fragment.getLayoutInflater(Fragment.java:936)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
        at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
        at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1085)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:931)
        at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1453)

@marcoRS
Copy link

marcoRS commented Apr 21, 2015

I switched to AppCompatActivity using appcompat 22.1.0 and started seeing a similar crash.

@dandc87
Copy link

dandc87 commented Apr 21, 2015

I believe I found a work around for the AppCompat 22.1.0 issue. Note, that I haven't tested this on a lot of Android versions; you might have to tweak this if you're targeting Gingerbread.

  1. Copy the source of AppCompatActivity into a new class
  2. Remove the line getDelegate().installViewFactory(); from onCreate()
  3. Override both onCreateView()s and return getDelegate().createView(parent, name, context, attrs) if super returns null

So you should end up with:

public class CustomAppCompatActivity extends FragmentActivity implements AppCompatCallback ... {

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getDelegate().onCreate(savedInstanceState);
  }

  @Override
  public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
    View view = super.onCreateView(parent, name, context, attrs);
    if(view != null) {
      return view;
    }
    return getDelegate().createView(parent, name, context, attrs);
  }

  @Nullable @Override public View onCreateView(String name, Context context, AttributeSet attrs) {
    View view = super.onCreateView(name, context, attrs);
    if(view != null) {
      return view;
    }
    return getDelegate().createView(null, name, context, attrs);
  }

  ...
}

@finneapps
Copy link

I have the same problem with appcompat-v7:22.1.0

@SjoerdvGestel
Copy link

Same issue :(
Screen with viewpager won't load anymore with "java.lang.IllegalStateException: A factory has already been set on this LayoutInflater"

@Aracem
Copy link

Aracem commented Apr 22, 2015

Same with the DrawerLayout and appcompat v22.1.0

@ZacSweers
Copy link
Contributor

According to someone on Reddit:

If you have an existing LayoutInflater and want to add your own factory to it, use cloneInContext(Context) to clone the existing instance and then you can use this function (once) on the returned new instance. This will merge your own factory with whatever factory the original instance is using.

From here: http://developer.android.com/reference/android/view/LayoutInflater.html#setFactory(android.view.LayoutInflater.Factory) somewhere

This seems like something the library should handle internally when CalligraphyContextWrapper.wrap(newBase) is called.

@muresanb
Copy link

Same crash here

@chrisjenx
Copy link
Owner

Sorry guys I'm on holiday so away from a computer. If someone is able to
post a work around for now I would really appreciate it. Sorry about the
bad timing, goog never give heads up about these things.

On Wed, 22 Apr 2015 13:36 muresanb notifications@github.com wrote:

Same crash here


Reply to this email directly or view it on GitHub
#155 (comment)
.

@wispborne
Copy link

There is one report from https://github.com/Unpublished that 22.1.1 fixes the issue. It is still reproducing for me, but I just set it up so I can't rule out user error.

Can anybody else confirm one way or the other?

@JoelReeves
Copy link

I'm still running into the same error as well even after updating to AppCompat 22.1.1

@javakias
Copy link

I can confirm that the problem remains with AppCompat 22.1.1

@jssingh
Copy link

jssingh commented Apr 27, 2015

Yup, issue still present with 22.1.1. Wonder if its an issue with Calligraphy, or material-dialogs or with the AppCompat itself.

@harism
Copy link

harism commented Apr 27, 2015

I'm not too familiar with functionality behind changing the fonts on Calligraphy but leaving a pointer here anyway. It seems so that there's a new interface being introduced within AppCompat 22.1;

http://developer.android.com/reference/android/support/v4/view/LayoutInflaterFactory.html

Just wondering if not using it relates to these crashes.

@chrisjenx
Copy link
Owner

I'll have a dive into this. Thanks for the heads up.

On Mon, 27 Apr 2015 at 12:30 Harri Smått notifications@github.com wrote:

I'm not too familiar with functionality behind changing the fonts on
Calligraphy but leaving a pointer here anyway. It seems so that there's a
new interface being introduced within AppCompat 22.1;

http://developer.android.com/reference/android/support/v4/view/LayoutInflaterFactory.html

Just wondering if not using it relates to these crashes.


Reply to this email directly or view it on GitHub
#155 (comment)
.

@harism
Copy link

harism commented Apr 27, 2015

Not sure is this a proper fix but I noticed setFactory2 gets called multiple times and causes the crash. Though wondering if checking for already existing Factory/Factory2 would do the trick?

CalligraphyLayoutInflater.java

@Override
public void setFactory(Factory factory) {
    // Only set our factory and wrap calls to the Factory trying to be set!
    if (getFactory() == null) { // Avoid setting Factory again
        if (!(factory instanceof WrapperFactory)) {
            super.setFactory(new WrapperFactory(factory, this, mCalligraphyFactory));
        } else {
            super.setFactory(factory);
        }
    }
}

@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void setFactory2(Factory2 factory2) {
    // Only set our factory and wrap calls to the Factory2 trying to be set!
    if (getFactory2() == null) { // Avoid setting Factory2 again
        if (!(factory2 instanceof WrapperFactory2)) {
            super.setFactory2(new WrapperFactory2(factory2, mCalligraphyFactory));
        } else {
            super.setFactory2(factory2);
        }
    }
}

As per documentation setting those more than once should cause a crash.

@chrisjenx
Copy link
Owner

2.1.0 Snapshot is available with a fix.

@marcoRS
Copy link

marcoRS commented Apr 27, 2015

👍 You're the greatest! :-D

@chrisjenx
Copy link
Owner

Fixed by #162

@martinlockett
Copy link

"You're the greatest!" - Confirmed

@Aracem
Copy link

Aracem commented Apr 29, 2015

Thank you very much to everybody that help here! 👍 💃 👯

@yayaa
Copy link

yayaa commented Apr 29, 2015

I've just got updated to appcompat-v7:22.1.0 and got this error, which has been already solved :) Thanks @chrisjenx

@niravfaraswami
Copy link

Thanks, man!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet