Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Way to avoid layout file naming conflict among multiple Android projects

Tags:

android

Currently, I have an Android project, consists of 1 main project, and multiple library projects.

Just that recently, I realize that if there is same layout filename among main project and library project, bad thing can happen.

third-party-library-project
    - res
        - layout
            - actionbar_custom_view_done_discard.xml
main-project
    - res
        - layout
            - actionbar_custom_view_done_discard.xml

So, if in third-party-library-project, if you are having line of code in its activity,

final View customActionBarView = inflater.inflate(
                R.layout.actionbar_custom_view_done_discard, null);

Error stack trace caused by layout file naming conflict

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{org.yccheok.jstock.gui/group.pals.android.lib.ui.lockpattern.LockPatternActivity}: android.view.InflateException: Binary XML file line #24: Error inflating class <unknown>
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    at android.app.ActivityThread.access$600(ActivityThread.java:130)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #24: Error inflating class <unknown>
    at android.view.LayoutInflater.createView(LayoutInflater.java:613)
    at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:660)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
    at android.view.LayoutInflater.parseInclude(LayoutInflater.java:830)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:736)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
    at group.pals.android.lib.ui.lockpattern.LockPatternActivity.initActionBar(LockPatternActivity.java:356)
    at group.pals.android.lib.ui.lockpattern.LockPatternActivity.onCreate(LockPatternActivity.java:347)
    at android.app.Activity.performCreate(Activity.java:5008)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    ... 11 more
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.constructNative(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
    at android.view.LayoutInflater.createView(LayoutInflater.java:587)
    ... 25 more
Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f010137 a=-1}
    at android.content.res.Resources.loadDrawable(Resources.java:1892)
    at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
    at android.widget.TextView.<init>(TextView.java:614)
    at android.widget.TextView.<init>(TextView.java:442)
    ... 28 more

If I change the layout XML file in third-party-library-project to actionbar_custom_view_done_discard1.xml, the runtime error will gone.

This is not an issues, if the number of library projects is small. Conflict can be solved easily with simple renaming. However, when comes across huge number of library projects, what is a robust way, or strategy to overcome this problem?

like image 851
Cheok Yan Cheng Avatar asked Dec 21 '13 18:12

Cheok Yan Cheng


2 Answers

Library projects need to ensure that their resource names will be distinctive and not collide with other library projects, such as by applying a prefix to those resource names.

Note that apparently the new Gradle-based build system supports resource subdirectories. I have not yet experimented with this, but if the subdirectory names form part of the resource ID, then putting your resources in a distinctive subdirectory would help to keep the resource IDs distinct (at least for non-values resources).

like image 114
CommonsWare Avatar answered Sep 24 '22 19:09

CommonsWare


First I would suggest renaming your project resource file and not the 3rd party file in your first example since you may want to pull changes from the 3rd party library project again. Secondly I would suggest not using too many 3rd party library projects to begin with. From my experience the Android build system still has lots of hiccups with library projects. Things like BuildConfig.DEBUG do not work and I've had issues with library projects that contain jar file dependencies breaking the ability to run unit tests through Android instrumentation. There are tons of other bugs as well, most of them probably fairly obscure but enough of an issue that I don't suggest using library projects any more than absolutely necessary.

like image 24
Matt Wolfe Avatar answered Sep 22 '22 19:09

Matt Wolfe