java.lang.ClassNotFoundException on DexPathList when inflating widget

Hi,

so I tried to learn how to create android widgets. Found blog about creating clock widget in java and made same steps with xamarin. All was fine while I was using default views, but then I tried to implement something custom (custom view to be exact). When I added it in axml problem occured: dalvik.system.BaseDexClassLoader seems to not find class and I when I add widget to home screen I see message something like "problem inserting widget" instead of my clock widget. When I use same View in Main.axml everything is fine (It clearly uses different class loader).

Error form logcat:

01-25 12:11:13.460  3218  3218 W AppWidgetHostView: android.view.InflateException: Binary XML file line #1: Binary XML file line #1: Error inflating class md5d8adc3c14e6553bc4cf71593996cd669.CustomClock
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.widget.RemoteViews.apply(RemoteViews.java:2762)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.appwidget.AppWidgetHostView.updateAppWidget(AppWidgetHostView.java:393)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at com.htc.launcher.LauncherAppWidgetHostView.updateAppWidget(LauncherAppWidgetHostView.java:116)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.appwidget.AppWidgetHost.updateAppWidgetView(AppWidgetHost.java:403)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.appwidget.AppWidgetHost$UpdateHandler.handleMessage(AppWidgetHost.java:131)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.os.Handler.dispatchMessage(Handler.java:102)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.os.Looper.loop(Looper.java:168)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.app.ActivityThread.main(ActivityThread.java:5885)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at java.lang.reflect.Method.invoke(Native Method)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView: Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class md5d8adc3c14e6553bc4cf71593996cd669.CustomClock
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:776)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     ... 12 more
01-25 12:11:13.460  3218  3218 W AppWidgetHostView: Caused by: java.lang.ClassNotFoundException: Didn't find class "md5d8adc3c14e6553bc4cf71593996cd669.CustomClock" on path: DexPathList[[zip file "/data/app/com.htc.launcher-2/base.apk"],nativeLibraryDirectories=[/data/app/com.htc.launcher-2/lib/arm, /data/app/com.htc.launcher-2/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.createView(LayoutInflater.java:583)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     ... 16 more
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     Suppressed: java.lang.ClassNotFoundException: md5d8adc3c14e6553bc4cf71593996cd669.CustomClock
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:             at java.lang.Class.classForName(Native Method)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:             at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:             at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:             at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:             ... 19 more
01-25 12:11:13.460  3218  3218 W AppWidgetHostView:     Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

custom class:

namespace EpicWatch
{
    public class CustomClock : TextClock
    {
        #region  default constuctors
    ...
        #endregion
    }
}

clock_widget_layout.axml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android";
    android:id="@+id/custom_clock_widget";
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center">
  <EpicWatch.CustomClock
    android:id="@+id/AnalogClock3";
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
         />
</RelativeLayout>

widget provider:

namespace EpicWatch
{
    [BroadcastReceiver(Label = "@string/app_name")]
    [IntentFilter(actions:new string[] { "android.appwidget.action.APPWIDGET_UPDATE" })]
    [MetaData("android.appwidget.provider", Resource ="@xml/clock_widget")]
    public class ClockWidget : AppWidgetProvider
    {
        ...
    }
}

clock_widget.xml:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android";
    android:minWidth="146dp"
    android:minHeight="146dp"
    android:updatePeriodMillis="0"
    android:initialLayout="@layout/clock_widget_layout";
/>

I develop using Visual Studio Enterprise 2017 Version 15.5.1
Xamarin 4.8.0.753 (6575bd113)
Xamarin.Android SDK 8.1.0.24 (HEAD/9cfa7836b)
Thing is tested on htc device running Android 5.0.

I have no clue what exactly is wrong and what i missed for it to work. Does widget needs to register additional path to my custom class in DexPath? Should I somehow indicate that my custom class is compiled in my apk file, or maybe some attributes to export it to existing paths?
All suggestions how to overcome this are welcome :smile:

p.s.: If I missed to add something, just tell me..

Best Answer

  • Accepted Answer

    It seems that the thing that I missed was part of Android documentation in https://developer.android.com/guide/topics/appwidgets/index.html#Manifest

    You must define an initial layout for your App Widget in XML and save it in the project's res/layout/ directory. You can design your App Widget using the View objects listed below, but before you begin designing your App Widget, please read and understand the App Widget Design Guidelines.

    Creating the App Widget layout is simple if you're familiar with Layouts. However, you must be aware that App Widget layouts are based on RemoteViews, which do not support every kind of layout or view widget.

    A RemoteViews object (and, consequently, an App Widget) can support the following layout classes:

    FrameLayout
    LinearLayout
    RelativeLayout
    GridLayout
    

    And the following widget classes:

    AnalogClock
    Button
    Chronometer
    ImageButton
    ImageView
    ProgressBar
    TextView
    ViewFlipper
    ListView
    GridView
    StackView
    AdapterViewFlipper
    

    Descendants of these classes are not supported.

    I was smashing my head against the wall trying to understand what is wrong, and the answer is simple as "it is not desing the way you want to use it"

Answers

  • SteponasBreidokas.8339SteponasBreidokas.8339 USMember ✭✭
    Accepted Answer

    It seems that the thing that I missed was part of Android documentation in https://developer.android.com/guide/topics/appwidgets/index.html#Manifest

    You must define an initial layout for your App Widget in XML and save it in the project's res/layout/ directory. You can design your App Widget using the View objects listed below, but before you begin designing your App Widget, please read and understand the App Widget Design Guidelines.

    Creating the App Widget layout is simple if you're familiar with Layouts. However, you must be aware that App Widget layouts are based on RemoteViews, which do not support every kind of layout or view widget.

    A RemoteViews object (and, consequently, an App Widget) can support the following layout classes:

    FrameLayout
    LinearLayout
    RelativeLayout
    GridLayout
    

    And the following widget classes:

    AnalogClock
    Button
    Chronometer
    ImageButton
    ImageView
    ProgressBar
    TextView
    ViewFlipper
    ListView
    GridView
    StackView
    AdapterViewFlipper
    

    Descendants of these classes are not supported.

    I was smashing my head against the wall trying to understand what is wrong, and the answer is simple as "it is not desing the way you want to use it"

Sign In or Register to comment.