I just started development for Android in C# using Xamarin and VisualStudio 2017. Quite a different paradigm from Windows eco-system.. Target is a business app, that will have a specific audience, but before i get deep into that i'm just trying to learn the ropes, understand concepts & procedures..
Therefore, i start with simplest app, using Blank template. That results in creating a project with an activity (MainActivity.cs), and 2 resources (Resources\layout\Main.axml, Res..\values\Strings.xml), and a few other items (e.g. Properties\AndroidManifest.xml, GettingStarted.Xamarin, etc.).
I compile and run it on an attached BLU Vivo 5 Mini (Android 6.0 - API 23)
. So far so good!
Next come my first attempts at playing with anything .. that surprisingly end badly.
1. Renaming MainActivity results in:
Unhandled Exception:
Java.Lang.RuntimeException: Unable to instantiate activity ComponentInfo{App4.App4/md54bce54f405542800672a5cecd6c84592.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "md54bce54f405542800672a5cecd6c84592.MainActivity" on path: DexPathList[[zip file "/data/app/App4.App4-1/base.apk"],nativeLibraryDirectories=[/data/app/App4.App4-1/lib/arm, /data/app/App4.App4-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
Is the name MainActivity
some kind of a predefined entry-point, similar to C/C++'s main()
?
I haven't seen any reference to that. But then what's the point of [Activity(MainLauncher=true)]
attribute, if not to mark the main/startup activity?
Fine, for now i rename it back. Recompile, run .. ok.
2. Deleting GettingStarted.Xamarin
file ('cause it's just a list of links, present in every project) seems to result in the same problem!? That's just an HTML page, so what gives??
Fine, i won't be touching this file anymore. Close solution, re-create project, run .. ok.
3. Modifying Properties\AssemblyInfo.cs to: [assembly: AssemblyVersion( "1.0.*" )]
(to match the build-version numbering schema for other projects) results in the same problem!..
(Surprisingly, modifying AssemblyFileVersion
has no bad effect - it runs; maybe Android side is offended by results of using *
-wildcard? But why?..)
Fine, i'll forgo all the best hard-learned efforts to keep source code organized and maintainable.
Close solution, re-create project, run .. ok.
4. Renaming Main
layout (to ActMain
or even MainActivity
- to match activity name) results in yet another similar startup exception.
"Fool!", says i, and revert back. Recompile, run .. ok. I should learn by now, right?
What gets me is that code always compiles, all these issues are popping up at run time!?!?
Fine, i give up, i'm not gonna modify anything that Xamarin or VS generates upfront. To make the experiment clean even further i restart VS, kill off all the previous projects and create a new one - let's start fresh with a Blank template.
5. Going forward the entry-point into the app would be a Log-in "page", so i add some TextView
, EditText
and Button
controls to the Main.axml
:
Buttons don't do anything yet - code is empty. Compile, run .. so far so good. Lovely!
Now i add a new Activity and give it a name ActSettings
. Yes, i like Hungarian notation, hate me for that if you want, but it helps me keep my objects organized. But that is besides the point: at this moment i should be free to name a new class anything i want, shouldn't i?
Next i create a corresponding layout, and [obviously] name it ActSettings
. Slap a few controls into it as well.
Compile, run .. ok.
There was no code linking activities together yet - let's add it:
6. Here's the solution and MainActivity.cs code with added action:
I hear Doug Marcaida going: "It will compile. But will it run?"
7. Nope, here's what i get (.NET knows ActSettings
class pretty well, but not Java!?):
02-02 13:47:11.686 W/monodroid( 5867): JNIEnv.FindClass(Type) caught unexpected exception: Java.Lang.ClassNotFoundException: md54e704423a01db64492900da8de435cc0.ActSettings ---> Java.Lang.ClassNotFoundException: Didn't find class "md54e704423a01db64492900da8de435cc0.ActSettings" on path: DexPathList[[zip file "/data/app/J7980ca.J7980ca-1/base.apk"],nativeLibraryDirectories=[/data/app/J7980ca.J7980ca-1/lib/arm, /data/app/J7980ca.J7980ca-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
02-02 13:47:11.686 W/monodroid( 5867): --- End of inner exception stack trace ---
02-02 13:47:11.686 W/monodroid( 5867): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <657aa8fea4454dc898a9e5f379c58734>:0
02-02 13:47:11.686 W/monodroid( 5867): at Java.Interop.JniEnvironment+StaticMethods.CallStaticObjectMethod (Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <e736913786c2475188869561ae512b72>:0
02-02 13:47:11.686 W/monodroid( 5867): at Android.Runtime.JNIEnv.CallStaticObjectMethod (System.IntPtr jclass, System.IntPtr jmethod, Android.Runtime.JValue* parms) [0x0000e] in <0fb41b3e3d7346ce92c4a742b20078ff>:0
02-02 13:47:11.686 W/monodroid( 5867): at Android.Runtime.JNIEnv.CallStaticObjectMethod (System.IntPtr jclass, System.IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00017] in <0fb41b3e3d7346ce92c4a742b20078ff>:0
02-02 13:47:11.686 W/monodroid( 5867): at Android.Runtime.JNIEnv.FindClass (System.String classname) [0x0003d] in <0fb41b3e3d7346ce92c4a742b20078ff>:0
02-02 13:47:11.686 W/monodroid( 5867): at Android.Runtime.JNIEnv.FindClass (System.Type type) [0x00015] in <0fb41b3e3d7346ce92c4a742b20078ff>:0
02-02 13:47:11.686 W/monodroid( 5867): --- End of managed Java.Lang.ClassNotFoundException stack trace ---
02-02 13:47:11.686 W/monodroid( 5867): java.lang.ClassNotFoundException: md54e704423a01db64492900da8de435cc0.ActSettings
02-02 13:47:11.686 W/monodroid( 5867): at java.lang.Class.classForName(Native Method)
02-02 13:47:11.687 W/monodroid( 5867): at java.lang.Class.forName(Class.java:324)
02-02 13:47:11.687 W/monodroid( 5867): at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native Method)
02-02 13:47:11.687 W/monodroid( 5867): at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:30)
02-02 13:47:11.687 W/monodroid( 5867): at android.view.View.performClick(View.java:5265)
02-02 13:47:11.687 W/monodroid( 5867): at android.view.View$PerformClick.run(View.java:21534)
02-02 13:47:11.687 W/monodroid( 5867): at android.os.Handler.handleCallback(Handler.java:815)
02-02 13:47:11.687 W/monodroid( 5867): at android.os.Handler.dispatchMessage(Handler.java:104)
02-02 13:47:11.687 W/monodroid( 5867): at android.os.Looper.loop(Looper.java:207)
02-02 13:47:11.687 W/monodroid( 5867): at android.app.ActivityThread.main(ActivityThread.java:5765)
02-02 13:47:11.687 W/monodroid( 5867): at java.lang.reflect.Method.invoke(Native Method)
02-02 13:47:11.687 W/monodroid( 5867): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
02-02 13:47:11.687 W/monodroid( 5867): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
02-02 13:47:11.687 W/monodroid( 5867): Caused by: java.lang.ClassNotFoundException: Didn't find class "md54e704423a01db64492900da8de435cc0.ActSettings" on path: DexPathList[[zip file "/data/app/J7980ca.J7980ca-1/base.apk"],nativeLibraryDirectories=[/data/app/J7980ca.J7980ca-1/lib/arm, /data/app/J7980ca.J7980ca-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
02-02 13:47:11.687 W/monodroid( 5867): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
02-02 13:47:11.687 W/monodroid( 5867): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
02-02 13:47:11.687 W/monodroid( 5867): at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
02-02 13:47:11.688 W/monodroid( 5867): ... 13 more
02-02 13:47:11.688 W/monodroid( 5867): Suppressed: java.lang.ClassNotFoundException: md54e704423a01db64492900da8de435cc0.ActSettings
02-02 13:47:11.688 W/monodroid( 5867): at java.lang.Class.classForName(Native Method)
02-02 13:47:11.688 W/monodroid( 5867): at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
02-02 13:47:11.688 W/monodroid( 5867): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
02-02 13:47:11.688 W/monodroid( 5867): at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
02-02 13:47:11.688 W/monodroid( 5867): ... 14 more
02-02 13:47:11.688 W/monodroid( 5867): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
Unhandled Exception:
Java.Lang.ClassNotFoundException: md54e704423a01db64492900da8de435cc0.ActSettings occurred
And it doesn't matter, what i call it: SecondActivity
does not work either!
8. The closest similar question already asked is Second activity in Android, but a) it is from 2011, b) there's no accepted answer, c) answers point to AndroidManifest.xml
file.. Well, here it is:
Notice, that the file in the project doesn't even mention half the stuff! Yet the generated output has all the activities spelled out perfectly, which only deepens my confusion.
9. Another question How do I resolve ClassNotFoundException? is probably closest, but again, it's from 2013 and it's tagged Java
(not Android
, Xamarin
or anything related to phones).
I have absolutely no clue, where is that classpath
, how and what to set it to, and most importantly why would Xamarin or VisualStudio-2017 not do that for me properly in the first place?
I would expect that a modern IDE touting platform support would be properly covering all the bases. Eventually the app would need TCP/UDP communication over WiFi, background / foreground servi-ces, notifications, and what not. But i'm having a fit simply doing "Hello, world!" :o
I tried running (and renaming files and classes!) ActivityLifecycle example, which launches a second activity, and it works perfectly .. provided i have not changed any names. If i do - it fails, but reverting names makes it work again. I cannot find any reasonable differences between that sample's code and my own, which would explain why Android can't find my second activity.
What am i doing wrong? Or not doing? Please help!