Category Archives: Compiler Errors

Running an Android App for the first time

Introduction

This is pretty much my first try on Android. I’ve downloaded tools in the past… and even faced one or two of the problems below, but I’ve never really stuck with it and actually run anything. The reason it reads like I don’t know what I’m doing and just flailing around in the dark is because I don’t and I am.

Software

In the past, the Android system has seemed to me, as a Visual Studio Developer, a little scattered. This is definitely still the case, but now less so. Android Studio seems to be the first step into a “download and run” system… but that is still a way off.

Steps

The first thing to do is to download Android Studio. Create a new project and build. You may get none of the following issues, but if you do, then this is how I got around them.

Androidpost1

This appears to be answered by this question. The problem was definitely the same one; when I compiled, I get this error:

C:\Users\Paul\AppData\Local\Android\sdk\tools\emulator.exe -avd MonoForAndroid_API_15 -netspeed full -netdelay none
emulator: ERROR: This AVD’s configuration is missing a kernel file!!

The suggested solution is to install the “ARM EABI v7a System Image”.

androidpost2

I enabled it, however, this did not fix the issue for me.

I then tried running Android Virtual Device Manager:

androidpost3

After creating a new AVD like the Nexus One above, ironically, Android Studio advises you to use x86. So I did… and got this error:

androidpost4

But it’s already installed:

andoidpost5

Weirdly, “Installed” is a misnomer; it doesn’t mean “installed”, it means… err… “not installed”. The way to properly install it is to go to the “extras” directory in explorer and run the installer from there:

androidpost6

I then got this error:

androidpost7

Okay – so this error is caused because you apparently can’t run Hyper-V and the HAXM emulator at the same time. I didn’t want to disable Hyper-V and, having tried several work-arounds, came to the conclusion that whatever the speed implications of not using the HAXM emulator, it was not as bad as having to reboot my machine to switch dev environments. So, I moved to ARM EABI-v7A:

androidpost8

As promised – this is slow! But it works:

androidpost9

Startup Uri Not Working – Cannot locate recource ‘mainwindow.xaml’

I recently re-visited this project, and found that, amongst other things, it would no longer run up. Clearly something had changed, and it was a while until I realised what. The error I was getting was this:

Cannot locate resource

The App.Xaml looked like this:


<Application x:Class="TFSUtils.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="clr-namespace:TFSUtils.ViewModel"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             StartupUri="MainWindow.xaml"
             mc:Ignorable="d">

Solution

I finally realised that I must have copied the MainWindow.Xaml into the Views folder as a last minute cleanup. The fix was very simple:


<Application x:Class="TFSUtils.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="clr-namespace:TFSUtils.ViewModel"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             StartupUri="View/MainWindow.xaml"
             mc:Ignorable="d">

Conclusion

So, there you go: long untouched and untested code just spontaneously breaks! Magic.

Detecting Recursion – JSON.Net Stack Overflow

Trying to save the game class of a game that I’m working on, I got a Stack Overflow error. I’m using MVVMCross, and my code looked like this:

        public void Save()
        {
            var jsonConv = Mvx.Resolve<IMvxJsonConverter>();
            string text = jsonConv.SerializeObject(this);
            FileHelper.SaveGameFile(text);
        }

The problem was that I got this error:

An unhandled exception of type ‘System.StackOverflowException’ occurred in mscorlib.dll

stackoverflow

I had a pretty good idea why. My game features a large population of “people”. Some of these people relate to each other; for example, they are parents, children, employers, etc. My guess was that I’d somehow messed up the creation routine and ended up with a recursive reference. (As it happened, far from messing it up, I hadn’t considered that a spouse relationship is recursive by definition!)

The Problem

The problem was that I had a starting population of 10,000 people. There are other ways to solve this: representing the reference between the classes as some kind of index, debugging the creation code, etc… However, I wanted to see if I could write a program to detect this.

My test program looks like this:

    class MyData
    {
        public MyData recursiveRef { get; set; }
        public string test { get;set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<MyData> data = new List<MyData>()
            {
                new MyData() {recursiveRef = null, test="non-recursive" },
                new MyData() {recursiveRef = null, test="recursive ref 1" },
                new MyData() {recursiveRef = null, test="recursive ref 2" },
                new MyData() {recursiveRef = null, test="recursive ref 3" },
                new MyData() {recursiveRef = null, test="recursive ref back to 1" }
            };
            data[1].recursiveRef = data[2];
            data[2].recursiveRef = data[3];
            data[3].recursiveRef = data[4];
            data[4].recursiveRef = data[1];

            SerialiseData(data);

            Console.ReadLine();
        }

        private static void SerialiseData(List<MyData> data)
        {
            JsonSerializerSettings settings = new JsonSerializerSettings()
            {
                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize,
                DateFormatHandling = DateFormatHandling.IsoDateFormat,
            };

            var ser = JsonConvert.SerializeObject(data, Formatting.None, settings);
            Console.Write(ser);
        }

Quickly running this will error with a stack overflow (to clarify, slowly running it will result in the same error!).

Detection Routine

Here’s the functions that I wrote to detect recursion:


        /// Itterate the list and call method CheckElement to analyse each element
        private static bool DetectRecursion<T>(IEnumerable<T> data)
        {
            Type typeT = typeof(T);

            foreach (T element in data)
            {
                if (CheckElement<T>(typeT, element, typeT, element))
                {
                    Console.WriteLine("Recursion found - exiting");
                    Console.ReadLine();
                    return true;
                }
            }

            return false;
        }

        private static List<object> recursionChain;

        /// Method recursively traverses the object to determine if there are any recursove references
        private static bool CheckElement<T>(Type baseType, T baseElement, Type checkType, object checkElement)
        {
            PropertyInfo[] piArr = checkType.GetProperties();
            foreach (PropertyInfo pi in piArr)
            {
                Console.WriteLine("Checking {0}, type {1}", pi.Name, pi.PropertyType);
                if (pi.PropertyType != baseType)
                    continue;

                var val = pi.GetValue(checkElement);
                if (val == null) continue;

                Console.WriteLine("Value for {0} is {1}", pi.Name, val.ToString());

                Type piType = val.GetType();

                if (piType == baseType && val.Equals(baseElement))
                {
                    return true;
                }

                if (CheckRecursionChain(val, piType)) return true;

                if (CheckElement<T>(baseType, baseElement, piType, val))
                {
                    Console.WriteLine("Successfully found recursive element {0}, {1}", piType.ToString(), val.ToString());
                    return true;
                }
            }

            return false;
        }

        /// Check the static recursion chain for a match
        private static bool CheckRecursionChain(object val, Type piType)
        {            
            if (Program.recursionChain != null && Program.recursionChain.Contains(val))
            {
                Console.WriteLine("Successfully found recursive element {0}, {1}", piType.ToString(), val.ToString());
                return true;
            }

            if (Program.recursionChain == null)
                Program.recursionChain = new List<object>();

            Program.recursionChain.Add(val);
            
            return false;
        }

This is, admittedly, not a simple or short piece of code; having said that, it doesn’t do anything complex, once you’re happy with the reflection, the rest is just a recursive tree.

To use this, simply call `DetectRecursion` in the above test program before calling serialize (or instead of).

...
DetectRecursion(data);

//SerialiseData(data);

...

Cannot modify members of ‘myVar’ because it is a ‘foreach iteration variable’

This can occur in a situation such as the following:

        private struct Position
        {
            public int left;
            public int top;
        }

        private static List<Position> _points = new List<Position>();

        private static void MyFunc()
        {
            foreach (Position pnt in _points)
            {
                pnt.top++;
            }
        }

This will fail to compile with the error message:

Cannot modify members of ‘pnt’ because it is a ‘foreach iteration variable’

Why?

The reason for this is simply that you cannot modify the collection that you iterate through, as you iterate through it. From the above statement, I can see that modifying the variable `top` would make no difference, but imagine this:

            foreach (Position pnt in _points.OrderBy(p => p.top))
            {
                pnt.top++;
            }

How to fix?

There’s two easy ways around this; the first is to switch a struct for a class:

    internal class Position
    {
        public int left;
        public int top;
    }

That would now work. The reason for this is the way that the two types are stored. Classes are reference types; which means that what is actually stored in the collection is a list of pointers to classes, and not the classes themselves; consequently, changing them does not affect the actual collection. You can even use orderby on the collection because it caches the order at the start of the loop (I’m certainly not advocating actually doing this).

What if you need to use a struct

Structs are immutable; which means you cannot change them. You can do something like this; although I personally can’t see why it’s easier that using a class:

            for (int i = 0; i <= _points.Count() - 1; i++)
            {
                _points[i] = new Position() { left = _points[i].left, top = _points[i].top + 1 };
            }