Archiv für Tech Blog

Zeige Ergebnisse 1 - 15 von 267

Jahre

Monate (2012)

Logging from C/C++ on Android (instead of debugging)

With the Android NDK Google lets us write C/C++ code for Android. I don’t like writing C/C++ code because it’s error-prone but sometimes there’s no other way.

Unfortunately (this is the “I don’t like this” part), debugging Android C/C++ code is terribly difficult. If you don’t have a week to get the debugging toolchain working, and if you only need some quick and temporary solution, logging may be an alternative.

9.Mai 2012

HTTP instead of HTTPS in Android SDK Manager

Sometimes (often?) downloads in the Android SDK Manager are annoyingly slow. The problem is that downloads are done over HTTPS. HTTPS is more secure but also slower than HTTP. Fortunately, Google allows us to change this behavior.

2.April 2012

Creating an Application class in Mono for Android

Android provides an Application class.

Base class for those who need to maintain global application state.

Here’s how to create such a class in Mono for Android:

[Application]  // <-- Attribute required
class MyApp : Application {
  // Required constructor
  public MyApp(IntPtr javaReference, JniHandleOwnership transfer) 
    : base(javaReference, transfer) { }

  // Test method - not required
  public override void OnCreate() {
    base.OnCreate();
  }
}

Note: There can only be one such class in an Android application.

30.März 2012

Accessing Java Classes from Mono for Android via JNI

Mono for Android let’s you write Android applications in a .NET language (for example, C#). It comes with wrappers for almost the entire Android API so building “standard” apps is easy enough. However, sometimes you may need to work with third party Java classes that aren’t part of Android itself. These classes usually come as a .jar file. Fortunately, Mono for Android provides a way to access those Java classes. Unfortunately, this way is a “little” bit tricky and documentation on this is (currently) quite limited.

This article will show some basic example of how to call a method of a Java class from Mono for Android. We will use Visual Studio 2010 in this article, as it is (in my opinion) currently superior to Mono Develop.

One last word before we start:

  • There are currently some limitation tied to JNI (which we will use to access Java classes). Specifically you can’t subclass existing Java classes or implement existing Java interfaces from Mono. This limitation can be circumvented by creating your own Java classes for third party and calling them from Mono. Update: According to Binding Android Types this is possible.
  • Also, I’ve been told that we can expect better support for third party jars in the next few months with some alpha code presented here.

Prerequisites

For this article I’ll assume you know your way around in Java and C#, and have installed:

  • Visual Studio 2010 (other version may work as well). Note that you can not use the Express Edition as it doesn’t support Add-Ins (specifically the “Mono for Android” Add-In here).
  • Mono for Android. This includes the Android SDK and the Visual Studio Add-In. You don’t need a paid version for this article. The evaluation version will do just fine.
  • Eclipse with ADT. We’ll use this to create a simple .jar file that depends on some Android APIs.

Native Java Library

To demonstrate accessing a Java library, let’s create a very simple one.

Create a new Android project called “JarLibForMonoDroid” (without an Activity). Then open the project settings and under Android activate Is Library.

Note: A working project is provided in the example source code available in the Download section below.

Activated "Is Library" in the project's Android settings

Create a class called JniTest in package com.mayastudios.jnitest. Here’s its contents:

package com.mayastudios.jnitest;

public class JniTest {
  public JniTest() { 
    // Force the user to create an instance
  }
  
  public String getGreetingText() {
    return "Hello, " + android.os.Build.MODEL;
  }
}

Save the Java file. The ADT should now have created a .jar file in the bin directory. (If it’s not there, make sure you’ve activated Is Library in the Android project settings.) That’s it.

Location of the automatically generated .jar file

Note: Normally, you don’t need an Android project but could create a pure Java project as well. In this example, we use an Android project to demonstrate the ability to access the Android API from within the Java classes and to have an easy way to create a .jar file for our project.

Accessing the Java Class from Mono

Create a simple Mono for Android project in Visual Studio.

Add jar to the project

The first step is to add the .jar file that was created in the previous section to the project (via Add existing item). For ease of use you should add this file as a link (by clicking on the down arrow at the Add button) like shown in the screenshot. If you don’t do this, the .jar file will be copied into the project directory and you need to re-copy it every time it changes.

Adding the .jar file as a link

You should now have an entry for the .jar file in your Solution Explorer pane. Note that there’s a small arrow in the jar’s icon indicating that it’s a link.

Linked jar file in the Solution Explorer

The last thing you need to do is to open up the jar’s Properties (via context menu or Alt+Return) and set the Build Action to AndroidJavaLibrary. This makes the classes contained in the jar accessible to JNI.

Setting the jar's "Build Action" to "AndroidJavaLibrary"

Important: You need to rebuild the project every time the .jar file has changed. The Mono for Android Add-In currently doesn’t detect the change automatically.

Add JNI code

Now, let’s access the Java class. For this, in Mono for Android you use a Mono version of JNI. With JNI in Java native libraries written in C++ can access Java objects. So, with JNI in Mono .NET classes can access Java objects.

To get started, in the Activity1 class, create a new method (called GetGreetingText) and change button’s Click event handler to set the button’s text with the return value of the method. (This all assumes that Xamarin didn’t change the default project example code when you read this. Otherwise you need to adapt the code.) The code should now look similar to this:

[Activity(Label = "MonoJniExample", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity {
  protected override void OnCreate(Bundle bundle) {
    base.OnCreate(bundle);

    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);

    // Get our button from the layout resource,
    // and attach an event to it
    Button button = FindViewById<Button>(Resource.Id.MyButton);

    button.Click += (s, e) => {      button.Text = GetGreetingText();    };  }

  string GetGreetingText() {
    // Code to be added here
  }
}

We will now add the necessary JNI code to GetGreetingText. In the end it’ll return “Hello, <Your Device Name here>”. The code should be pretty much self-explanatory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
string GetGreetingText() {
  // Get a pointer to the Java class.
  IntPtr nativeJavaClass = JNIEnv.FindClass("com/mayastudios/jnitest/JniTest");
  // Find the parameterless constructor.
  IntPtr defaultConstructor = JNIEnv.GetMethodID(nativeJavaClass,
                                                 "<init>",
                                                 "()V");
  // Create a new instance of the class.
  IntPtr instance = JNIEnv.NewObject(nativeJavaClass, defaultConstructor);
 
  // Find our example method.
  IntPtr method = JNIEnv.GetMethodID(nativeJavaClass,
                                     "getGreetingText",
                                     "()Ljava/lang/String;");
  // Call the method.
  IntPtr resultPtr = JNIEnv.CallObjectMethod(instance, method);
  // Convert pointer to return value into a usable object (here a string).
  Java.Lang.String nativeResult
    = new Java.Lang.Object(resultPtr, JniHandleOwnership.TransferLocalRef)
                          .JavaCast<Java.Lang.String>();
 
  // Convert the Java string into a .NET string and return it.
  return nativeResult.ToString();
}

There are a few that should be noted here:

  • The method JNIEnv.GetMethodID() takes the method name as second parameter and the method signature as third parameter.

    • The method name for a constructor is always <init>.
    • The signature is composed of the parameter list followed by the return type of the method. It adheres the JNI rules for specifying the signature. I suggest you use this JNI Cheat Sheet for trying to understand the syntax.
  • Some rudimentary description of JNI’s methods can be found in the JNI specification.
  • The JniHandleOwnership enumeration (line 19) hasn’t been documented yet. So I can’t really say anything about it. I’m currently waiting for an answer about this.

You should now be able to run the app and when you tap on the button it should change its text.

Download the Project Files

I’ve compiled a small .zip file containing the source code and all project files.

projectfiles.zip

12.Februar 2012

Battle of the Action Figures

Vergleich der Action-Figuren von Qui-Gon Jinn (Liam Neeson, Star Wars) und Capt. Jean-Luc Picard (Patrick Stewart, Star Trek TNG):

YouTube Preview Image
7.Februar 2012

Meaningful C++ error message

During my time as a student at the University of Stuttgart we had to learn the programming language Ada. Back then I was swearing about the compiler error message because they were totally meaningless (at least to me).

I am currently working on a C++ project and I have to say that C++ isn’t an inch better than Ada. Consider the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <Windows.h>
 
namespace Geometry {
  class Polyline { };
}
 
using Geometry::Polyline;
 
namespace OtherNS {
  Polyline* get() {
    return NULL;
  }
}

Trying to compile this code gives you the following error message (on Visual C++ 2010):

using_test.cpp(10): error C2143: syntax error : missing ';' before '*'
using_test.cpp(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
using_test.cpp(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

What? Syntax error? And then you start looking where you missed a ;.

The problem, however, is completely different. It’s because there is a function called Polyline() defined somewhere in Windows.h and now the compiler tries to use this function as return type instead of the class Polyline (but doesn’t say anything about that). <irony>This, of course, becomes totally clear just by reading this extremely meaningful error message.</irony> *sigh*

GCC isn’t better here (in case you were blindly blaming Microsoft for writing bad error messages):

error: ‘Polyline’ does not name a type

By the way, the problem can be solved by placing the using statement inside the OtherNS namespace.

1.Februar 2012

C++ references and inheritance

The last few days I’ve been hunting a bug in a C++ project I’ve been working on. This hunt again showed me how easily you can break C++ programs by accident (something that isn’t possibly in Java or C#). You need to completely understand the inner workings of C++ to avoid such pitfalls.

The whole problem was a result of me thinking that C++ references (&) are just pointers (*) that have some restrictions (e.g. they can’t be NULL). Wrong! What’s even worse: They’re sometimes just pointers with some restriction. This makes them work in some cases but fail in others.

Let me take you on my journey and you’ll hopefully avoid this (very subtle) mistake in your work.

Verliebt in Siri

YouTube Preview Image

(via)

18.Januar 2012

Stoppt SOPA und PIPA!

Wikipedia Seite wegen SOPA und PIPA heruntergefahren.

Mit diesem Bild werden Besucher der englischen Wikipedia am heutigen 18. Januar 2012 begrüßt. Grund: Protest gegen die US-Gesetzesentwürfe SOPA (Stop Online Piracy Act) und PIPA (ProtectIP Act). Einen guten (englisch-sprachigen) Artikel hat die Electronic Frontier Foundation dazu verfasst: How PIPA and SOPA Violate White House Principles Supporting Free Speech and Innovation.

Irgendwie kommt mir das doch alles sehr bekannt vor.

16.Januar 2012

IDisposable, Finalizer, and SuppressFinalize in C# and C++/CLI

The .NET framework features an interface called IDisposable. It basically exists to allow freeing unmanaged resources (think: C++ pointers). In most cases, you won’t need IDisposable when writing C# code. There are some exceptions though, and it becomes more important when writing C++/CLI code.

The help page for IDisposable provides the code for IDisposable‘s default implementation pattern in C#. This article will explain each part of it step by step and also provide the equivalent C++/CLI code in each step.

15.Januar 2012

Facebook and You

Sehr böse ;)

Facebook and You

BTW, ich mag Facebook.

(via Geek & Poke)

11.Januar 2012

Sharing project properties in Visual C++

Everyone who has ever created and managed a C++ project in Visual Studio knows that there are hundreds of compiler switches and options to choose from. While setting the desired values for one project may be ok, it’s quite time-consuming and error-prone to do this for multiple projects. I’m currently working with a solution containing about 30 or so projects that share most of their project settings. I always wished there was a way to sync or share these common settings among the projects in the solution. Fortunately, there is: property sheets. They’re a bit hidden though, so I’ll explain how to use them in this article.

Note: This only applies to C++ and C++/CLI projects. .NET projects (C# and Visual Basic) don’t have that many options to be tweaked and (therefore?) can’t have shared settings.

Note 2: This article describes property sheets as they appear in Visual Studio 2010. They may work slightly different in other versions of Visual Studio.

9.Januar 2012

Passing native pointers across C++/CLI assembly boundaries

C++/CLI allows you to mix native C++ code with managed .NET code (which is extremly nice). Mixing such code also allows you to create methods in .NET class that take or return pointers to native (C++) classes. Unfortunately, this doesn’t work out of the box across assemblies (read: DLLs). If you define a .NET class in one assembly and this class has a method that returns a pointer, you may not be able to use this method from within another C++/CLI assembly.

This article describes the problem and shows solutions.

30.Dezember 2011

Eclipse and the JDK under Mac OS X Lion

Java is open-source, fortunately. Accessing its source code is, unfortunately, not so intuitive on Mac OS X Lion when using Eclipse. This article will guide you through the steps required to be able to view Java’s source code in Eclipse.

28.Dezember 2011

Assign DNS name to virtual machine (here: Parallels Desktop 7)

Assigning a DNS name to a virtual machine can be a convenient thing. Do this is not very complicated, it requires some technical skill though. This tutorial shows how to do this with a Ubuntu 11.10 Linux server running under Parallels Desktop 7 on Mac OS X Lion. The basic principals described in this article work as well for any other combination, but that’s beyond this article (and that’s where your technical skill comes into play).