UK Developer Blog Signing Out
Wednesday, June 08, 2011
Labels: UK Developer Blog
Wednesday, June 08, 2011
Labels: UK Developer Blog
Tuesday, February 10, 2009
Labels: UK Developer Blog
One of my favourite uses of Google Maps is a feature called My Maps, which allows users to create customised maps - for example, a map of my favourite London pubs. My Maps can contain many different kinds of information, from as simple placemark to a media-rich mashup of embedded images and videos. These maps also have specific URLs that can be shared with other users - so I can invite my friends to add their favourite pubs to my London pubs map too.
The other day, I was making a map to share with some other Googlers and found that I needed to duplicate the MyMap I had already created. I needed to split some of the content into two separate maps. I asked around and no one seemed to know how to do it, though it seemed there ought to be an easy solution. After a few trials, I found a simple way to do it. It wasn't rocket science, but may be handy for you at some point especially given the simplest solutions are often the hardest to find! Here is the work-around I found:
Monday, February 02, 2009
Labels: geomob, UK Developer Blog
Hard to believe, but Thursday night was only the second meeting of the London Geo/Mobile Developers Meetup Group. With 60 UK developers in attendance, the organiser (Christopher Osborne) put together another really fun and compelling event.
Tuesday, January 20, 2009
Labels: android, UK Developer Blog
In my career as a software engineer, I have encountered plenty of example code. As a Google Developer Advocate for Android, part of my job involves creating example code for illustrating certain concepts and APIs.
Most of the time, people will take a snippet of example code and bend it to their will until it no longer resembles the original. But that's the whole point: the sample code has served its purpose. It has illustrated some key concept and hopefully helped someone build some great software.
Last week I met with a developer who was working on a prototype application for a potential client of his. In the course of our discussion, he told me that he has been continuing to use some example code I provided him with, as-is, without modification. This of course made me very happy, but more importantly, made me think that perhaps this code might also be useful to other Android developers out there.
WARNING: This is about to get a bit technical, if you or your children grow faint at the sight of code, please stop reading now.
The tricky problem of multithreaded programming with a Graphical User Interface (GUI)
Every GUI widget framework I have ever encountered has been single-threaded (usually called "the main thread" or "the gui thread.") Learning how best to use other threads and have them "play nicely" with your widget framework of choice can be tricky. The main problem with most widget frameworks (including Android) is that you can't call methods on widget objects if your code is running in a non-GUI thread.
Horrible crimes against code that I have committed in the past
Way back in the 90's I was wrestling with the Swing UI framework. I was trying to write applications that used a "background" thread to do some long running thing. This included some horribly hacky things, like putting Thread.sleep() statements in my code at certain places until it kinda-sorta worked (the really frustrating thing about calling UI methods from non-GUI threads is that sometimes it does actually work!)
That was until I learned about
javax.swing.SwingUtilities.invokeLater(Runnable thingToDo)You can call the
invokeLater()method from any non-GUI thread and it will invoke your
thingToDo.run()method in the context of the UI thread, which means that your Runnable object can do things like update a progress bar etc.
android.os.Handlerclass does the same thing. The way you use it is slightly different, though. If you create an android.os.Handler object in the context of the GUI thread (in the onCreate() method of an activity, for example) then you can use that handler instance in the context of another thread in order to do your UI work.
public interface GUITask {
void executeNonGuiTask() throws Exception;
void after_execute();
void onFailure(Throwable t);
}
public class TaskQueue {
private LinkedList<Runnabl> tasks;
private Thread thread;
private boolean running;
private Runnable internalRunnable;
private class InternalRunnable implements Runnable {
public void run() {
internalRun();
}
}
public TaskQueue() {
tasks = new LinkedList«Runnable»();
internalRunnable = new InternalRunnable();
}
public void start() {
if (!running) {
thread = new Thread(internalRunnable);
thread.setDaemon(true);
running = true;
thread.start();
}
}
public void stop() {
running = false;
}
public void addTask(Runnable task) {
synchronized(tasks) {
tasks.addFirst(task);
tasks.notify(); // notify any waiting threads
}
}
private Runnable getNextTask() {
synchronized(tasks) {
if (tasks.isEmpty()) {
try {
tasks.wait();
} catch (InterruptedException e) {
Log.e("androidx", "Task interrupted", e);
stop();
}
}
return tasks.removeLast();
}
}
private void internalRun() {
while(running) {
Runnable task = getNextTask();
try {
task.run();
} catch (Throwable t) {
Log.e("androidx", "Task threw an exception", t);
}
}
}
}
import android.os.Handler;
import android.os.Message;
import androidx.LogX;
public class GUITaskQueue {
private static final int HANDLE_EXCEPTION = 0x1337;
private static final int HANDLE_AFTER_EXECUTE = 0x1338;
private TaskQueue taskQ;
private Handler handler;
private static GUITaskQueue singleton;
public static GUITaskQueue getInstance() {
if (singleton == null) {
singleton = new GUITaskQueue();
singleton.start();
}
return singleton;
}
private GUITaskQueue() {
taskQ = new TaskQueue();
handler = new MyHandler();
}
public void start() {
taskQ.start();
}
public void stop() {
taskQ.stop();
}
public void addTask(GUITask task) {
taskQ.addTask(new GUITaskAdapter(task));
}
/**
* Adds a task with an associated progress indicator. The indicator's showProgressIndicator() gets
* called immediately then the hideProgressIndicator() gets called before the GUITask's
* handle_exception() or after_execute() method gets called.
*/
public void addTask(ProgressIndicator progressIndicator, GUITask task) {
if (progressIndicator == null) {
addTask(task);
} else {
addTask(new GUITaskWithProgress(task, progressIndicator));
}
}
private static class GUITaskWithProgress implements GUITask {
private GUITask delegate;
private ProgressIndicator progressIndicator;
GUITaskWithProgress(GUITask _delegate, ProgressIndicator _progressIndicator) {
delegate = _delegate;
progressIndicator = _progressIndicator;
progressIndicator.showProgressIndicator();
}
public void executeNonGuiTask() throws Exception {
delegate.executeNonGuiTask();
}
public void onFailure(Throwable t) {
progressIndicator.hideProgressIndicator();
delegate.onFailure(t);
}
public void after_execute() {
progressIndicator.hideProgressIndicator();
delegate.after_execute();
}
};
private static class GUITaskWithSomething{
GUITask guiTask;
T something;
GUITaskWithSomething(GUITask _guiTask, T _something) {
guiTask = _guiTask;
something = _something;
}
}
private void postMessage(int what, Object thingToPost) {
Message msg = new Message();
msg.obj = thingToPost;
msg.what = what;
handler.sendMessage(msg);
}
private void postException(GUITask task, Throwable t) {
postMessage(HANDLE_EXCEPTION, new GUITaskWithSomething(task, t));
}
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLE_EXCEPTION:
GUITaskWithSomethingthingie = (GUITaskWithSomething ) msg.obj;
thingie.guiTask.onFailure(thingie.something);
break;
case HANDLE_AFTER_EXECUTE:
GUITask task = (GUITask) msg.obj;
try {
task.after_execute();
} catch (Throwable t) {
LogX.e(t);
}
break;
}
super.handleMessage(msg);
}
}
private class GUITaskAdapter implements Runnable {
private GUITask task;
GUITaskAdapter(GUITask _task) {
task = _task;
}
public void run() {
try {
task.executeNonGuiTask();
postMessage(HANDLE_AFTER_EXECUTE, task);
} catch (Throwable t) {
postException(task, t);
}
}
}
}
Thursday, January 15, 2009
Labels: android, UK Developer Blog
Last week we held a 2 day Android hack session here in the Google London office (January 7th and 8th to be exact). Google supplied the space, the wifi, the cookies and most importantly, the coffee!
We had technical people from various companies show up and join in on the fun. It was a pretty relaxed event, more in the style of an "unconference." We had a few presentations about particular aspects of the Android SDK that people might not otherwise know about. Then we spent the remainder of the time hunched over our laptops, exchanging information and trying to avoid spilling the coffee.
I was lucky enough to sit next to a graphic artist from last.fm who created an awesome icon for a blogger app I'm writing that will allow Bloggers to blog from their G1 (big thanks Matt Brown!)
If you own a G1, I've posted an incomplete version of my Android blogger app in the Android Market under Applications | Social | A-Blogger otherwise stay tuned to this blog and I'll share the source code once it is relatively complete (software is never fully complete though, is it?)
My Blogger app was written entirely using publicly documented APIs, if you're a software developer, you can check out the Blogger API at http://code.google.com/apis/blogger/docs/2.0/developers_guide_protocol.html and code your own app!
One tip I thought I'd share with all those Eclipse users out there, if you download the Android source from http://source.android.com/ and look for 'View.java.' Copy that file to
/sdks/android-sdk-mac_x86-1.0_r2/sources/android/view/View.java (assuming your Android SDK has been installed at "/sdks" on your computer) and the next time you are in Eclipse
working on your Android app, you can "control-click" (or "apple-click") on the word 'View' where you see "extends View" in your code and Eclipse will open up View.java. (word to the wise, the View.java that is opened will probably be slightly newer or slightly older than the version that was used to build android.jar in the SDK, but I have found that incredibly useful anyway)
All in all it was a pretty fun event. At the end of the second day, a few of us went to the pub around the corner ("The Victoria") and had quite a few laughs and discussed the general awesomeness of The Peep Show (being a transplanted Canadian, I only just discovered this wonderful TV show over the holidays). We are hoping to have lots more informal hack sessions this year and hope to see you there. Stay tuned for info on upcoming events.
Mike Jennings
Android Developer Advocate
Wednesday, December 03, 2008
Labels: developer meetup, UK Developer Blog
On a dark November evening, there were some dazzling minds at work at the first meeting of #Geomob (aka the London Geo/Mobile Developers Meetup Group) which we were delighted to host here at the Google London office. The group was put together by a freelance developer, Christopher Osborne, who came along to our Google Developer Day at Wembley back in September.
The evening kicked off with half an hour of chatting with friends old and new. Following the informal beginning, we heard three thought-provoking talks by Gary Gale (Head of UK Engineering, Yahoo! Geo Technologies) who spoke about Yahoo! Fire Eagle, Nick Black, left, (Founder, Cloudmade) who discussed "Five Things Online Maps Can't (Yet) Do", and finally Andrew Grill (Mobile Advertising Evangelist and owner of the London Calling blog), who gave his thoughts on Mobile Advertising Trends.
All three speakers prompted lively discussions which highlighted the huge amount of activity and interest in the Geo/Mobile space (and how much of it's happening right here in London!).
Monday, November 17, 2008
Labels: UK Developer Blog
It's been two exciting months for the OpenSocial community in Europe with lots of announcements at the Google Developer Days in London, Paris, Munich, Madrid, Milan, Prague, Moscow and Tel-Aviv (wow, that's a lot of nice cities!)
As a reminder, OpenSocial is a set of common APIs for building social applications that provide a common infrastructure for the social web. Using OpenSocial, both developers and websites can focus resources on their unique features rather than on dealing with different types of plumbing. Taking into account the most recent OpenSocial container announcements, developers will be able to access more than 600 million users who are part of OpenSocial-enabled networks.
In London, Netlog, the European social networking site, announced the availability of their application platform to more than 35 million members, and Hyves announced their launch to 7M members in the Netherlands.
"I think I can speak for all of us when I say that the Developer Day showed the momentum of OpenSocial and the committment of various containers and developers to make it a success. Being able to discuss the future of OpenSocial, both formally and informally, is another good reason for being there the next time as well ;-)" Yme Bosma, Hyves
In Paris, Viadeo, the European professional social network, released their public sandbox and already made some good contacts to get some interest apps running on it. Netlog opened their on-the-fly translation tool to apps developers, a very easy way to translate your social app to more than 20 languages.
"Viadeo is very proud to be part of the Opensocial adventure and looks forward to seeing in the next months the first professional applications to be added to its existing features, thanks to the Opensocial APIs…" Ariel Messas, Viadeo
Buddy Poke OpenSocial app running on Netlog French site (translated in French)
In Munich, four containers were on stage, with the local player Lokalisten opening their sandbox. XING, the European social network, presented their plans to launch OpenSocial support in the first half of 2009. Netlog and Viadeo also attended to reach out to the German developer community.
“Our aim was to give developers a feeling why OpenSocial in a professional social network such as XING will be different from OpenSocial as one may know it on other social networks. At the Google Developer Day we gained a lot of positive feedback on this, got to know many talented developers, and discussed some excellent new ideas of OpenSocial applications that bring value to business people worldwide.” Matthias Haesel, XING
There was certainly a lot of interest in OpenSocial at Developer Day in Madrid. The best attended codelabs were those focusing on OpenSocial, and I presented at the Orientation for start-ups session to over 100 developers!
In Prague and Moscow, I was amazed by the quality of the developers, the pertinence of their questions, and their interest in building social applications. Seznam announced their commitment to Opensocial at Developer Day in Prague, planning an implementation beginning of 2009 in their community services Lide.cz and Spoluzaci.cz. However, their sessions must have been quite productive because directly following them, Seznam told us they would be implementing OpenSocial as quickly as possible!
Lastly, our friends at Mail.ru were on stage at Developer Day in Moscow to present their OpenSocial implementation (already available to their 35M members), and from what I understood (I don't speak Russian!), it was a massive success. If everything goes well, they should have many new social apps coming for their social network after the GDD.
If you missed the Developer Day sessions, you can read the slides here :
It's really great to see that a year after its launch, OpenSocial is successful in Europe. See you all at the next Developer Days or at the next OpenSocial hackathon!
Limvirak Chea
New Business Development Manager, Google EMEA
©2008 Google - Privacy Policy - Terms of Service