SushiHangover

PowerShell, Learn it or Perish ;-)

master nix
Gitter

Xamarin Android Player / Genymotion - Foobar 101

I was really happy with Xamarin’s Android Player (XAP) on OS-X 10.11 (and 10.10.x before I upgraded). It is much better the Google’s plain-jane Android emulator, way way faster, easier setup as the images are pre-packaged Nexus images, etc… But you can not create custom images and that ends up being a problem as you need to test different configurations.

Someone recommended Genymotion and everything seemed fine, I could create custom Genymotion images and still use XAP for the basic testing…

BUT after a reboot of OS-X, everything went to @#$@#$@#. Android sessions in either player would take 10 minutes or more to start up and get to the lock screen and when I say ‘more’, I mean up to 20 minutes…or MORE. Even then, services would die, the VirtualBox instance would hang, Xamarin Studio would not connect, XAP would report that the OpenGL server is not available, Genymotion would report no IP address could be retrieved…

Removing Genymotion did not help. Deleting and re-install XAP did not help. Installing the latest VirtualBox did not help. Uninstall VirtualBox via their installer, deleting the XAP app and restarting from stratch did not help…. Removing all the original XAP Andriod images and re-downloading them did not help (I thought maybe the new VirtualBox updated them and caused a XAP issue, but no to that idea)…

Seems that I am not alone, if you started with Genymotion and later installed XAP, you could be in the same boot… after you reboot the first time. Seems Geny users call it “surviving the reboot”, if you make it past a reboot and everything is still working you should be golden, if not, your system is @#$#@$#.

I’m still looking for a solution other then re-installing the OS as some people have resorted to… I just do not have time do a fresh OS-X install so right now I can only test via actual physical devices :-(

AHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!!!!!!!!

Xamarin Android Shared Preferences

While I do not directly recommend this technique, it seems using the PreferenceManager.GetDefaultSharedPreferences is really popular in saving values between different activities. While you can create multiple names that do not conflict between different activities, it can get messy real fast.

Instead of using GetDefaultSharedPreferences, create multiple GetSharedPreferences with different names and thus you can store values with the same names without overwriting your values from a different activity. (Again, I am not a big fan of this technique either for anything more than some simple UI preference settings, see notes at bootom of post)

i.e.

        var title = "stack"; float price = 123.34f; long weight = 23; 
        var editor = GetSharedPreferences ("MyFirstActivity", Android.Content.FileCreationMode.Private);
        var edit = editor.Edit ();
        edit.PutString ("title", title);
        edit.PutFloat ("price", price);
        edit.PutLong ("weight", weight);
        edit.Apply ();

        title = "overflow"; price = 99.99f; weight = 99;
        editor = GetSharedPreferences ("MySecondActivity", Android.Content.FileCreationMode.Private);
        edit = editor.Edit ();
        edit.PutString ("title", title);
        edit.PutFloat ("price", price);
        edit.PutLong ("weight", weight);
        edit.Apply ();

        editor = GetSharedPreferences("MyFirstActivity", Android.Content.FileCreationMode.Private);
        title = editor.GetString("title", "empty");
        price = editor.GetFloat("price", 0);
        weight = editor.GetLong("weight", 0);
        Log.Info("activity1", string.Format("{0}:{1}:{2}", title, price, weight));

        editor = GetSharedPreferences("MySecondActivity", Android.Content.FileCreationMode.Private);
        title = editor.GetString("title", "empty");
        price = editor.GetFloat("price", 0);
        weight = editor.GetLong("weight", 0);
        Log.Info("activity2", string.Format("{0}:{1}:{2}", title, price, weight));

adb logcat output:

[activity1] stack:123.34:23
[activity2] overflow:99.99:99

Notes:

Personally when I see someone saving shopping cart data, using JSON to serialize objects in and out of SharedPerferences string values, etc…, my head starts to pound in a bad way. At that time you should really start looking for an asynchronous, persistent key-value store, like Akavache.

Windows Dependency Walker for debugging missing DLLs

I was trying to track down an issue on a fresh Window 10 install with a older application that was starting but faulting on a dependancy but I was not getting the std DLL missing message…

Running the .exe under Visual Studio was getting me no where fast and than I remembered a really old program called “Dependency Walker”.

What do you know, it is still avaiable and being kept up to date, well it lists Windows 8, but it seems to also run on an Insider Windows 10 Fast Track install just fine, and Solved my problem in less then a minute…

Error: At least one required implicit or forwarded dependency was not found.    Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.     Warning: At least one delay-load dependency module was not found.   Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

Dependency Walker

Dependency Walker is a free utility that scans any 32-bit or 64-bit Windows module (exe, dll, ocx, sys, etc.) and builds a hierarchical tree diagram of all dependent modules. For each module found, it lists all the functions that are exported by that module, and which of those functions are actually being called by other modules. Another view displays the minimum set of required files, along with detailed information about each file including a full path to the file, base address, version numbers, machine type, debug information, and more.

FYI: I remember using that program on Window’s ARCH types long forgotten… and the site still has versions available (unsupported of course) for Alpha, AXP64, MIPS, and PowerPC architectures…. wow, remember when Windows ran on those ;-)

Android FileObserver example in Xamarin/C#

This is from my answer on StackOverflow from a question that got closed. As not to lose it to the SO ‘on-hold/close’ flush, I am re-posting it.

Question

How can you write an Android FileObserver in C#?

i.e. Native Java example:

FileObserver observer = new FileObserver(imageUri.getPath()) {
    public String basePath;

    @Override
    public void onEvent(int event, String path) {
        String fullPath = basePath;
        if(path != null) {
            fullPath += path;
        }
        Log.d(TAG, "FILE: "+fullPath);
    }
};
observer.basePath = imageUri.getPath();
observer.startWatching();

Answer

Create a class that inherits from Android.OS.FileObserver, you only need to implement the OnEvent() and one(+) Constructors. Its a really simple pattern after you see it once… ;-)

Quick Notes:

  • Watch on a path, if you need to filter by file, do it in the OnEvent
  • Do not let your FileObserver object get GC’d or your OnEvents will magically stop :-/
  • Remember to call StartWatching() in order to receive OnEvent calls

C# FileObserver Class:

using System;
using Android.OS;
using Android.Util;

namespace MyFileObserver
{
    public class MyPathObserver : Android.OS.FileObserver
    {
        static FileObserverEvents _Events = (FileObserverEvents.AllEvents);
        const string tag = "StackoverFlow";

        public MyPathObserver (String rootPath) : base(rootPath, _Events)
        {
            Log.Info(tag, String.Format("Watching : {0}", rootPath)); 
        }

        public MyPathObserver (String rootPath, FileObserverEvents events) : base(rootPath, events)
        {
            Log.Info(tag, String.Format("Watching : {0} : {1}", rootPath, events)); 
        }

        public override void OnEvent(FileObserverEvents e, String path)
        {
            Log.Info(tag, String.Format("{0}:{1}",path, e)); 
        }
    }
}

Example Usage:

var pathToWatch = System.Environment.GetFolderPath (System.Environment.SpecialFolder.Personal);
// Do not let myFileObserver get GC'd, stash it's ref in an activty, or ...
myFileObserver = new MyPathObserver (pathToWatch);
myFileObserver.StartWatching (); // and StopWatching () when you are done...
var document = Path.Combine(pathToWatch, "StackOverFlow.txt");
button.Click += delegate {
    if (File.Exists (document)) {
        button.Text = "Delete File";
        File.Delete (document);
    } else {
        button.Text = "Create File";
        File.WriteAllText (document, "Foobar");
    }
};

adb logcat Output (when clicking on the test button):

I/StackoverFlow( 3596): StackOverFlow.txt:Create
I/StackoverFlow( 3596): StackOverFlow.txt:Open
I/StackoverFlow( 3596): StackOverFlow.txt:Modify
I/StackoverFlow( 3596): StackOverFlow.txt:CloseWrite
I/StackoverFlow( 3596): StackOverFlow.txt:Delete
I/StackoverFlow( 3596): StackOverFlow.txt:Create
I/StackoverFlow( 3596): StackOverFlow.txt:Open
I/StackoverFlow( 3596): StackOverFlow.txt:Modify
I/StackoverFlow( 3596): StackOverFlow.txt:CloseWrite
I/StackoverFlow( 3596): StackOverFlow.txt:Delete
I/StackoverFlow( 3596): StackOverFlow.txt:Create
I/StackoverFlow( 3596): StackOverFlow.txt:Open
I/StackoverFlow( 3596): StackOverFlow.txt:Modify
I/StackoverFlow( 3596): StackOverFlow.txt:CloseWrite

iTerm2 OSX: Jump Word-wise left and right in Navigation

Jumping word-wise in the iTerm2 (3.0 beta):

  • Open the Preferences Pane
  • Goto Tab Keys
  • Create a new Key Binding with the Shortcut “⌥ + ←” and use “Send Escape Sequence” as the Action and Set “Esc + b”
  • Create a new Key Binding with the Shortcut “⌥ + →” and use “Send Escape Sequence” as the Action and Set “Esc + f”

iTerm Jump/Tab Words

OS-X El Capitan Adobe Air Installer

Have problems trying to install Adobe Air on a fresh install of OS-X 10.11? The current version of the installer that linked @ https://get.adobe.com/air/ will just hang and you will have to force quit it.

Try the latest Adobe Air Beta 20 and your problems will be sovled.

Note: This also solves the issue for older versions of Adobe CS (6 and others) failing to install properly. Install the latest Air version and retry your Adove CS install.

Git OS-X Credentials

Setting up a fresh install of El Capitan…

I installed git via homebrew:

brew git

And since it has been such a long time since I had to link git to the OS-X key chain, I totally forgot how… After way to much searching, I figured I’d post this as a reminder for at least myself ;-)

But if you installed git using homebrew, you should already have the osxkeychain helper. You can verify this by trying to run it:

git credential-osxkeychain

To tell git to use osxkeychain, simply set the global git config:

git config --global credential.helper osxkeychain

MonoDevelop.AddinMaker - CI Build and Install .mpack

Using mhutch/MonoDevelop.AddinMaker to create your Addins? If not, you should convert your Addin Project (see his “Migrating Existing Projects” notes in the repo’s README.md file)

Need to intergate building, creating the .mpack, and installing it into Xamarin Studio into your CI process?

Package your Addin to a .mpack file

xbuild PlayScript.Addin.csproj /t:CreatePackage

Install your .mpack

mdtool setup install bin/Debug/PlayScript.Addin.PlayScript.Addin_1.0.mpack

FYI: Using mhutch/MonoDevelop.AddinMaker makes developing and debugging Addins so much easier, there is still a huge documention gap in the MonoDevelop Addin system, but M. Hutch’s AddinMaker sure helps a ton (thanks mhutch!).

Xamarin OS-X Addins Location

In the process of working on an Xamarin Studio Language Addin for PlayScript I needed to to manually find and update some of the installed Addin files. But where are the Addin files?

Within the ~/Library/Application Support directory you will find one based on the version of Xamarin Studio or Monodevelop that you are using:

  • MonoDevelop-4.0
  • MonoDevelop-5.0
  • MonoDevelop-6.0
  • XamarinStudio-4.0
  • XamarinStudio-5.0
  • XamarinStudio-6.0

Within one of those directories you will find:

  • LocalInstall/Addins

So for me, that ended up being:

~/Library/Application Support/XamarinStudio-6.0/LocalInstall/Addins ~/Library/Application Support/MonoDevelop-6.0/LocalInstall/Addins