Android App Starting Multiple Times

I noticed that when I ran WebcomiX on Android, backgrounded it and then came back to it later, sometimes the Faves screen would be blank and sometimes  it would appear to go through the whole launch procedure. I just assumed it had been unloaded from memory and was just starting up again.Then one day while debugging it, I noticed that the bringing it to the foreground actually caused the app to “start again” in the same debug session.

06-23 16:45:48.371 D/Mono    ( 5289): Assembly Ref addref System.Xml[0x6f160fe980] -> mscorlib[0x6f43026e00]: 51
Loaded assembly: System.Xml.dll [External]
[0:] MainActivity.OnCreate.
[0:] App started
[0:] MainPage.MainPage.
[0:] FavesPage.FavesPage.
[0:] LibraryPage.libraryPage.
[0:] ListView: GroupHeaderTemplate and GroupDisplayBinding can not be set at the same time, setting GroupDisplayBinding to null
[0:] AboutPage.AboutPage....
06-24 17:27:55.156 D/InputTransport( 9430): Input channel destroyed: fd=147
06-24 17:27:55.157 I/Choreographer( 9430): Skipped 36 frames! The application may be doing too much work on its main thread.
06-24 17:27:58.307 W/ActivityThread( 9430): handleWindowVisibility: no activity for token android.os.BinderProxy@a60629a
[0:] MainActivity.OnCreate.
06-24 17:27:58.420 D/InputTransport( 9430): Input channel constructed: fd=159
06-24 17:27:58.420 D/ViewRootImpl@870dd16[SplashActivity]( 9430): setView = DecorView@6f0697[SplashActivity] TM=true MM=false
06-24 17:27:58.436 D/ViewRootImpl@870dd16[SplashActivity]( 9430): dispatchAttachedToWindow
06-24 17:27:58.444 D/ViewRootImpl@870dd16[SplashActivity]( 9430): Relayout returned: old=[0,0][1080,2220] new=[0,0][1080,2220] result=0x1 surface={valid=false 0} changed=false
06-24 17:27:58.445 E/ViewRootImpl@870dd16[SplashActivity]( 9430): Surface is not valid.
06-24 17:27:58.445 W/ActivityThread( 9430): handleWindowVisibility: no activity for token android.os.BinderProxy@3120084
[0:] MainActivity.OnCreate.
[0:] App started
[0:] MainPage.MainPage.
[0:] FavesPage.FavesPage.
[0:] LibraryPage.libraryPage.
[0:] ListView: GroupHeaderTemplate and GroupDisplayBinding can not be set at the same time, setting GroupDisplayBinding to null
[0:] AboutPage.AboutPage.

This is the log file form one single debug session.  I have logging in all my constructors and as you can see, the App constructor was called once at the beginning of the app and then once later on.  Now, I am not sure what is going on here.  The data from the initial run of the app stills seems to be around.  In the latter case, I set a flag to say I have done my initial load and when it “starts” for the second time, it skips the whole “data load procedure” and carries on from where it left off.  I think in the former case some of my view model constructors were being run again and that was clearing some collections.

I posted this on the Xamarin.Forms forum and someone said this was a kown issue with Android apps and was to to with the way Activities are handled and OnCreate being called multiple times.  Hopefully Forms 4 will fix it.  But that is another post.

Update

By the look of it, you can’t guarantee that the data from the last”start” is still valid.  I have had instances where it has restarted and given errors when you try and click on something.  The UI is still bound to some data  but when you click on a comic you get a “key not found in dictionary error”, as if one of the main collections has been wiped.

Admob and Xamarin Forms

I had noticed that the advert on the Favourites screen had disappeared on my android phone. I spent a good day trying to fix it and I was most annoyed when I found out what the issue was.

Looking through the debug logging I had added, it started to display the ad but never finished. I googled anything that was logged and drew lots of blanks. Eventually after a good few hours searching I came across a throw away comment on the Xamarin forum.

It turned out that the advert was there all along, in fact if you launch the app and turn the phone 90 degrees, the advert appears. On the initial launch, the screen wasn’t laying itself out properly and the ad was there but with no height. Some people suggested setting the height of the view where the ad appears to a fixed number. Phone and tablet ads were both different heights. This was ok, except if there were no ads to display. Then you would have a blank space where the ad should be.

In the end I fixed it by displaying the page and then after a second hiding and showing the advert. This caused the visible screen to re-lay itself out and, hey presto, the advert was visible. This fix was wrapped in some IF statements as it appeared to be only Android 27+ where this happened.

Using Microsoft App Centre

If you are writing an app then you want some sort of reporting and diagnostics functionality that you can use to monitor your apps. Can I suggest the App Center by Microsoft.

You create an account, add your apps and then just add a Nuget to your projects. It is as simple as that.

  • Call stacks from crashes with the exception. I could immediately see where my app was crashing in the wild (no error handling in the properties the XAML was bound to). I could tell by the exception what was happening, so it was easy to fix. All this is logged by version number as well.
  • Error logging. So you have fixed the error and wrapped it all in a try/catch just to be safe. In the catch you collect any errors that still make it through and report them back to base. You can also add info to it like which method was it, which comic was it, what was it expecting, things like that. With that I can tell which comic was causing the most problems.
  • Analytics tells you how many users there are per day. You get a breakdown of which devices they are running and which version of the OS. Where they are, things like that.
  • Of the features I haven’t used, the ability to build and distribute to beta testers seems good.

My only criticism is that live user data gets mixed up with the development and beta test data. So you should change to a new version number once a release has gone out the door and any crashes or error still open against the old number should be marked as ignored. This should make the new crashes more findable.

All in all, thoroughly recommend it.

Test Driven Development

It is a buzzword that has been around for ages now, and when I first heard it I thought it was more hassle than it was worth. That was because management had decided to introduce it into an already established project. That doesn’t work. It is better to start to implement it when a project starts.

Ideally you have a design which separates the “business logic” from the interface. For example, with WebcomiX, the whole Comic and navigation and refreshing was in a stand alone library. It was easy to add unit tests to check that …

  • A GenericComic loaded its config data correctly.
  • The ComicCollection loaded a lot of GenericComics correctly.
  • The StatusRefresher refreshed the favourite GenericComics correctly.

If every on screen button just calls a method on one of your models, then it is easy to simulate the app in use without actually having an app yet. You do this iteratively as well. You start with your basic classes and get them working in tests. Then you add the more complex ones and get them working in tests. You know at any time that if the unit tests start failing then you have broken something. It is much easier to debug tests than it is to debug a full application.

Of course, if you change how something works, you have to change the tests as well. Don’t let tests stay broken for too long or you might as well forget about them. If they are not passing then they aren’t doing their job.

Symb*!!*cks

Is “symbolicating” really a word? Apple seem to think so. When you get a crash log back form them they have removed all the symbols (names of your classes and methods) and replaced them with numbers. To find out where your app crashed, you have to replace the numbers with their original symbols. They give you a tool but it is not easy, and they call the process “symbolicating”. Personally I would call it “symbolizing” as you are replacing one thing for another that represents it.

WebcomiX 3 Released

It has taken a couple of months but I clicked the publish buttons on iOS and Android yesterday and … it turns out there was an #IFDEF DEBUG section that I had forgotten about. So, Apple politely informed me it wasn’t working and a quick rummage through the crash log told me why. Resubmitted it with an updated android version as well. They hadn’t mention ed it was broken but it would have been.

Then there was an issue with M$ AppCentre. This handles analytics and crash reports for your app. The Android version worked fine. The iOS worked fine on the simulator and my devices. When Apple installed it though it crashed. Turns out I was using the Xamarin method of starting the appCentre rather than the Xamarin.Forms method. It took a while to re symboilize the crash logs but once I had done that I could see where the problem was.

As I speak, both apps are live in their respective stores.