Java Question Problem with maven repositories and design-support library.

corwin42

Expert
Licensed User
Longtime User
I'm trying to update the Design support library to use maven repositories and get a strange problem/error.

The DesignSupport library depends on AppCompat libraries and a AppCompat Theme.

If I remove all @DependsOn Annotations from the libraries (AppCompat and DesignSupport) and only add
B4X:
#AdditionalJar: com.android.support:design
in the B4A Code, all works fine.

The google design support library has dependencies itself for appcompat, so the correct libraries like appcompat and support v4 are automatically added to the project.

Now the problem:
If I add the
B4X:
@DependsOn(values = { "com.android.support:appcompat-v7" })
to the AppCompat Library OR I just add
B4X:
#AdditionalJar: com.android.support:appcompat-v7
BEFORE the #AdditionalJar entry for the design support Library I get this error:

** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
** Activity (main) Create, isFirst = false **
main_activity_create (java line: 337)
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:166)
at anywheresoftware.b4a.objects.ActivityWrapper.LoadLayout(ActivityWrapper.java:209)
at example.tablayout.scrollingtabs.main._activity_create(main.java:337)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at example.tablayout.scrollingtabs.main.afterFirstLayout(main.java:102)
at example.tablayout.scrollingtabs.main.access$000(main.java:17)
at example.tablayout.scrollingtabs.main$WaitForLayout.run(main.java:80)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.objects.CustomViewWrapper.AfterDesignerScript(CustomViewWrapper.java:64)
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:158)
... 14 more
Caused by: java.lang.IllegalArgumentException: You need to use a Theme.AppCompat theme (or descendant) with the design library.
at android.support.design.widget.ThemeUtils.checkAppCompatTheme(ThemeUtils.java:36)
at android.support.design.widget.TabLayout.<init>(TabLayout.java:291)
at android.support.design.widget.TabLayout.<init>(TabLayout.java:285)
at android.support.design.widget.TabLayout.<init>(TabLayout.java:281)
at de.amberhome.objects.TabLayoutWrapper.innerInitialize(TabLayoutWrapper.java:87)
at anywheresoftware.b4a.objects.ViewWrapper.Initialize(ViewWrapper.java:65)
at de.amberhome.objects.TabLayoutWrapper.Initialize(TabLayoutWrapper.java:53)
at de.amberhome.objects.TabLayoutWrapper._initialize(TabLayoutWrapper.java:95)
... 17 more
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException

So the design support library does not detect that it runs with an AppCompat Theme. I have no idea, why this happens but I think it has something to do with the order the libraries are added.

@Erel: Any idea how to fix this?
 

corwin42

Expert
Licensed User
Longtime User
Hello Erel,


here the example project with a problem.

The libraries do not have any DependsOn Annotations in the xml.

If you only add "#AdditionalJar: com.android.support:design" in the B4A Project everything is fine.
If you add #AdditionalJar: com.android.support:appcompat-v7 AFTER the above AdditionalJar, then everything seems to be fine, too.
If you add #AdditionalJar: com.android.support:appcompat-v7 BEFORE the design AdditionalJar, you will get the error.

Maybe it has something to do with the order the resX folders are generated in Objects/bin/extra?
 

Attachments

  • ScrollingTabs_bug.zip
    8.2 KB · Views: 298
  • CustomLibsForProblem.zip
    120.1 KB · Views: 317

corwin42

Expert
Licensed User
Longtime User
Note that I've uploaded Beta #2. Try it with that version. There were several changes in the way the libraries are collected.

Ok, I will try it. Anyway I've attached the xml.
 

Attachments

  • DesignSupport.xml
    20 KB · Views: 455

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've investigated this issue. It seems to me that it is a bug in Android library. There is a reference to a constant resource. Resources in libraries should not be constant to avoid clashes.

You can use this code as a workaround:
B4X:
Private Sub WorkaroundInvalidResource
   Try
     Dim x As XmlLayoutBuilder
     Dim r As Reflector
     r.SetStaticField2("android.support.design.widget.ThemeUtils", "APPCOMPAT_CHECK_ATTRS", Array As Int(x.GetResourceId("attr", "colorPrimary")))
   Catch
     Log(LastException)
   End Try
End Sub
Call it before loading the layout.
 

corwin42

Expert
Licensed User
Longtime User
I've investigated this issue. It seems to me that it is a bug in Android library. There is a reference to a constant resource. Resources in libraries should not be constant to avoid clashes.

Thanks for looking into it.

It seems that AndroidStudio avoids this problem somehow because I haven't found anything about such a problem with a Google search.

Thanks for the workaround. Do you think it will be possible to add a similar code to DesignerCreateView() in the library? I don't want to release a library that at first forces the developer use a workaround to make the library work at all. May be the library can fix the issue itself?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
After another test, I'm more convinced that it is a bug in the latest version of the support library.

Compare the compiled code of v24 (beta):
B4X:
private static final int[] APPCOMPAT_CHECK_ATTRS = { 2130772097 }; //the R id should not be constant.

And v23.4:
B4X:
  private static final int[] APPCOMPAT_CHECK_ATTRS = { R.attr.colorPrimary };

As you saw it can seem to work properly depending all the randomly assigned ids.
Do you think it will be possible to add a similar code to DesignerCreateView() in the library?
Yes.
Add this code to your class (I haven't tested it):
B4X:
static {
     try {
       java.lang.reflect.Field f = Class.forName("android.support.design.widget.ThemeUtils").getDeclaredField("APPCOMPAT_CHECK_ATTRS");
       f.setAccessible(true);
       f.set(null, new int[] {BA.applicationContext.getResources().getIdentifier( "colorPrimary", "attr", BA.packageName)});
     } catch (Exception e) {
       e.printStackTrace();
     }
   }
 
Top