Site Sponsors:
Easy Backgrounds for Android 
I have developed a great respect for the developers of the Android Graphics Framework. Why? Because it is obvious that the developers like to use their classes, themselves.

It's Ragu!


Indeed, from doing complex things like affine transforms, to even simple things like measuring a Canvas or a Bitmap, Android has the data we need, when-we-need-it. -From splits to splines, it all seems to be "in there"! (The Company that makes Ragu Spaghetti Sauce had a commercial a few years back - many take the expression it's ragu to mean ''it's in there''!)

Vista


Such was thee case of having what we needed "in there" when we set our paws to spruce-up a little ditty we wrote for the Android Marketplace. When it came time to spread a tile image all over a background, we had what we needed. -So much so that we feel confident that what we wrote will be able to work across hand-held devices of infinite screen size. All because members are ragu, where & when they should be... and more:

public void draw(Canvas can) {
if (bmpBack != null) {
PixelCellMap map = new PixelCellMap(can.getWidth(), can.getHeight(), bmpBack.getWidth(), bmpBack.getHeight());
int iCells = map.getCellCount();
for (int ss = 0; ss < iCells; ss++) {
Point pt = map.getActual(ss);
can.drawBitmap(bmpBack, pt.x, pt.y, paintPaper);
}
} else {
can.drawColor(paintPaper.getColor());
}
}

Note that the PixelCellMap class is part of a forthcoming Open Source Toolkit. One we are creating for cross-platform Android / Swing / AWT portability. -If you want to learn more about it (the code-named for the graphical part of the framework is Vista (sorry - but that moniker just made the most sense at the moment)), then give us a holler.


[ add comment ] ( 2066 views )   |  permalink  |  related link
Android, Eclipse & Ubuntu 

We Love NetBeans


My friends and I learned how to develop software for Android on NetBeans. -While far from the usual path taken to Android 'Nerdvanna, since we have started training on Android, we have been increasingly reverting back to bad habits. We have been using Eclipse.





Why dread teaching with Eclipse you might ask? -Because we have seen far too many students blow-away a weeks' weight of work while using it. --While admittedly just about all student ''disasters'' center around students tweaking their files and / or settings outside of the IDE (NEVER mess with anything in the workspace folders directly -bugs can sleep until a re-boot -even backups can fail to fix the problem!) --I'm just sayin' ... once burned, is twice shy... Ten time so roasted in front of a classroom could make even Johnny Carson a 'tad neurotic.

Yet in as much as only we old timers expect to treat files as stand-alone, given that the IDE is presently the opiate of the masses, what cannot be cured, must be endured. -After all, according to "Jafar's Golden Rule" - the customer is always right. ;-)





Not Galileo?


Certainly the first place to stop for a great overview of the Android SDK installation process - in general - would be at the Android Site.

Once we find ourselves merrily 'skipping down the Eclipse road to the emerald 'droid habitation, students are often keen to use a customized distro like Galileo.





While jump-start distros are great if you can start there from-scratch, most clients like to integrate the SDK into their existing tool-chain. Hence the need to document the integration process, ourselves. It makes a great how-to.

-Of course, if you need to install the ADK for another reason ('distro blows up on Windows, etc...) then we will assume a 'from scratch' here, too.

The Step-By-Step


So, beginning from step zero, we must jump to:

Step #1 - Get It


You will need:

(1) A Java Run-Time Environment (JRE).

Eclipse is a Java Application. It needs a JRE. So if not already installed, then you can get the JRE from Java.com. Stick with version 1.6 or greater.

Assuming that the JRE installed okay, you might - or might not - want to use Sun's SDK. Eclipse has its own.

Note to OS X Users: If you do not have Java 1.6 available, consider installing Ubuntu under Oracle's Virtual Box -You can get that here. --In fact, if you use more than one machine - be it a laptop at home, or a desktop at work - then everyone should install Android on Ubuntu using Virtual Box Software. Why? Because if you don't mind spending $99 for a pocket drive, then using a virtual machine is a great way to backup, as well as transplant gigabytes of work-in-progress from one place, to another.

(2) You will need a copy of Eclipse - we got mine from The Eclipse Site.

(3) You will also need The Android SDK - The archive is at the Android Download Page.

Step #2 - Installing Eclipse


Setting up Eclipse has always been easy: Once Java has been installed, all we need do is to open the Eclipse archive. After open, we can just drag, drop, and click on the eclipse file, in the eclipse folder.



Note: If Eclipse complains about not being able to find your Java, then note that some versions of Ubuntu have an extremely quirky problem with setting up your path... -Our pristine, updated, and properly-patched install-base on a 32 bit Lucid Lynx VM was one such version. -After too much howling frustration, after updating the path in $HOME/.profile we discovered that all we had to do was to re-boot for $PATH to 'take' to a new shell session... -Who knew?

Step #3 - The ADK


The Android SDK (ADK) is also a queer thing: While you just drag and drop it to install much like Eclipse, once we have done so, we need to run the SDK Management Tool before we can use the download to do much of anything:



See the README in the top ADK folder for instructions on how to see:



-Note that you will probably not want to install as many packages as depicted above -We do a lot of experiments with other platforms, so we installed 1.5, 2.2, 3.2 and 4.0. --When in doubt, 1.5 is the way to go if you have old hardware laying around. -That said however, 2.1 is probably what most folks will want to work with.

Step #4 - The ADK Plug-in Under Eclipse


Google has the poop here. It worked well.

Note that during the install that you will have to browse to select the location where you dropped the ADK (Step #3) proper. Because we also used the tools on NetBeans, we kept that ADK Folder next to - rather than inside of - the eclipse folder.

I was a bit surprised this time to see the plug-in re-download all of the platforms we had selected in Step #3, as well as to suggest the use of the 2.1 Platform. After being prompted, we installed Version 2.1, as well.

Ten dialogs & promptings later, here is what we saw:



Here is the log:


[2011-11-11 15:37:19 - SDK Manager] Fetching https://dl-ssl.google.com/android/repository/addons_list-1.xml
[2011-11-11 15:37:20 - SDK Manager] Validate XML
[2011-11-11 15:37:20 - SDK Manager] Parse XML
[2011-11-11 15:37:20 - SDK Manager] Fetched Add-ons List successfully
[2011-11-11 15:37:20 - SDK Manager] Fetching URL: https://dl-ssl.google.com/android/repository/repository-5.xml
[2011-11-11 15:37:21 - SDK Manager] Validate XML: https://dl-ssl.google.com/android/repository/repository-5.xml
[2011-11-11 15:37:21 - SDK Manager] Parse XML: https://dl-ssl.google.com/android/repository/repository-5.xml
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 1.1, API 2, revision 1 (Obsolete)
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 1.5, API 3, revision 4
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 1.6, API 4, revision 3
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 2.0, API 5, revision 1 (Obsolete)
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 2.0.1, API 6, revision 1 (Obsolete)
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 2.1, API 7, revision 3
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 2.2, API 8, revision 3
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 2.3.1, API 9, revision 2 (Obsolete)
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 2.3.3, API 10, revision 2
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 3.0, API 11, revision 2
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 3.1, API 12, revision 3
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 3.2, API 13, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found SDK Platform Android 4.0, API 14, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found ARM EABI v7a System Image, Android API 14, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Samples for SDK API 7, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Samples for SDK API 8, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Samples for SDK API 9, revision 1 (Obsolete)
[2011-11-11 15:37:21 - SDK Manager] Found Samples for SDK API 10, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Samples for SDK API 11, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Samples for SDK API 12, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Samples for SDK API 13, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Samples for SDK API 14, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Android SDK Platform-tools, revision 9
[2011-11-11 15:37:21 - SDK Manager] Found Android SDK Tools, revision 15
[2011-11-11 15:37:21 - SDK Manager] Found Documentation for Android SDK, API 14, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Android Support package, revision 4
[2011-11-11 15:37:21 - SDK Manager] Fetching URL: https://dl-ssl.google.com/android/repository/addon.xml
[2011-11-11 15:37:21 - SDK Manager] Validate XML: https://dl-ssl.google.com/android/repository/addon.xml
[2011-11-11 15:37:21 - SDK Manager] Parse XML: https://dl-ssl.google.com/android/repository/addon.xml
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 3, revision 3
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 4, revision 2
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 5, revision 1 (Obsolete)
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 6, revision 1 (Obsolete)
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 7, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 8, revision 2
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 9, revision 2 (Obsolete)
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 10, revision 2
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 11, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 12, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 13, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Google APIs by Google Inc., Android API 14, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Google TV by Google Inc., Android API 12, revision 2
[2011-11-11 15:37:21 - SDK Manager] Found Google Market Licensing package, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Google USB Driver package, revision 4
[2011-11-11 15:37:21 - SDK Manager] Found Google Market Billing package, revision 1
[2011-11-11 15:37:21 - SDK Manager] Found Google Admob Ads Sdk package, revision 3
[2011-11-11 15:37:21 - SDK Manager] Found Google Webdriver package, revision 1
[2011-11-11 15:37:21 - SDK Manager] Fetching URL: http://www.echobykyocera.com/download/e ... sitory.xml
[2011-11-11 15:37:22 - SDK Manager] Validate XML: http://www.echobykyocera.com/download/e ... sitory.xml
[2011-11-11 15:37:22 - SDK Manager] Parse XML: http://www.echobykyocera.com/download/e ... sitory.xml
[2011-11-11 15:37:22 - SDK Manager] Found Dual Screen APIs by KYOCERA Corporation, Android API 8, revision 1
[2011-11-11 15:37:22 - SDK Manager] Found Dual Screen APIs by KYOCERA Corporation, Android API 10, revision 1
[2011-11-11 15:37:22 - SDK Manager] Fetching URL: http://developer.lgmobile.com/sdk/andro ... sitory.xml
[2011-11-11 15:37:23 - SDK Manager] Validate XML: http://developer.lgmobile.com/sdk/andro ... sitory.xml
[2011-11-11 15:37:23 - SDK Manager] Parse XML: http://developer.lgmobile.com/sdk/andro ... sitory.xml
[2011-11-11 15:37:23 - SDK Manager] Found Real3D by LGE, Android API 8, revision 1
[2011-11-11 15:37:23 - SDK Manager] Fetching URL: http://innovator.samsungmobile.com/andr ... sitory.xml
[2011-11-11 15:37:24 - SDK Manager] Validate XML: http://innovator.samsungmobile.com/andr ... sitory.xml
[2011-11-11 15:37:24 - SDK Manager] Parse XML: http://innovator.samsungmobile.com/andr ... sitory.xml
[2011-11-11 15:37:24 - SDK Manager] Found GALAXY Tab by Samsung Electronics., Android API 8, revision 1
[2011-11-11 15:37:24 - SDK Manager] Fetching URL: http://developer.sonyericsson.com/edk/a ... sitory.xml
[2011-11-11 15:37:25 - SDK Manager] Validate XML: http://developer.sonyericsson.com/edk/a ... sitory.xml
[2011-11-11 15:37:25 - SDK Manager] Parse XML: http://developer.sonyericsson.com/edk/a ... sitory.xml
[2011-11-11 15:37:25 - SDK Manager] Found EDK 1.1 by Sony Ericsson Mobile Communications AB, Android API 10, revision 1
[2011-11-11 15:37:25 - SDK Manager] Done loading packages.
[2011-11-11 15:38:26 - SDK Manager] Preparing to install archives
[2011-11-11 15:38:26 - SDK Manager] Downloading Android SDK Tools, revision 15
[2011-11-11 15:39:07 - SDK Manager] Installing Android SDK Tools, revision 15
[2011-11-11 15:39:09 - SDK Manager] Installed Android SDK Tools, revision 15
[2011-11-11 15:39:09 - SDK Manager] Downloading Android SDK Platform-tools, revision 9
[2011-11-11 15:39:25 - SDK Manager] Installing Android SDK Platform-tools, revision 9
[2011-11-11 15:39:25 - SDK Manager] 'adb kill-server' succeeded.
[2011-11-11 15:39:26 - SDK Manager] Installed Android SDK Platform-tools, revision 9
[2011-11-11 15:39:26 - SDK Manager] Downloading SDK Platform Android 4.0, API 14, revision 1
[2011-11-11 15:40:37 - SDK Manager] Installing SDK Platform Android 4.0, API 14, revision 1
[2011-11-11 15:40:42 - SDK Manager] Installed SDK Platform Android 4.0, API 14, revision 1
[2011-11-11 15:40:42 - SDK Manager] Downloading SDK Platform Android 2.1, API 7, revision 3
[2011-11-11 15:43:04 - SDK Manager] Installing SDK Platform Android 2.1, API 7, revision 3
[2011-11-11 15:43:08 - SDK Manager] Installed SDK Platform Android 2.1, API 7, revision 3
[2011-11-11 15:43:33 - SDK Manager] 'adb kill-server' succeeded.
[2011-11-11 15:43:36 - SDK Manager] ADB: * daemon not running. starting it now on port 5037 *
[2011-11-11 15:43:36 - SDK Manager] 'adb start-server' succeeded.
[2011-11-11 15:43:36 - SDK Manager] Done. 4 packages installed.
[2011-11-11 15:43:36 - SDK Manager] ADB: * daemon started successfully *


Conclusion


Having used Helios (Eclipse 3.6), we must say that the Indigo install (Eclipse 3.7) went a lot smoother. Unlike the last time however, we installed it-all on a Virtual Box; With absolutely no trial-and-error, this same 32-bit Ubuntu Operating System image ran just fine on OS X, Windows XP, 64-bit Windows 7, and 64-bit Ubuntu.





Because we now have a VM ready to help jump-start every student project from-scratch, perhaps the best reason for this blog entry is to remind myself of what others might expect. -Since we have saved a few copies of the virtual image, we will probably not have to repeat the above process for a good deal longer than human-memory should be required to recollect such a mismatched hodge of geeky-wonderment.

Enjoy!

-R.A. Nagy



[ add comment ] ( 3057 views )   |  permalink
Java Threads in Android 

Android Threads


Those looking to port threads to Google's Android Operating System are often frustrated: While the classic thread classes are there, using threads in your application can cause some pretty tough-to-debug problems.

Indeed, while 'googling around the 'net, one is often told not to use threads. We are told that using a Handler is better.

While using handlers is sage advice for supporting small lightweight duties, sometimes you just want to use a little thread, anyway. Indeed, as processors, battery, and RAM become less and less of an issue in our pockets, many lean-and-mean anti-thread discussions sound much like the CGA -v- VGA display-support discussions we had at Informix while writing Wingz in the early 1990's. When all is said and done, it seems that - at the moment - most technical limitations simply fade away...

The best reason why most use an honest-to-goodenss thread on android is to do heavier number crunching. By doing computer-intensive work away from the main user experience, we all know that things simply work better. (Even in user interfaces it seems, nobody likes a jerk! ;-)

Thread Hangups


Typically, one is crunching data for a reason: To eventually display something interesting. For this reason, one of the first head-scratchers we encounter when using a thread in an Android App is how it can completely trash an application. In fact, the most certain way to lock your 'App occurs whenever another Android Thread touches the GUI API in any way, shape, or form.

Consider the following:


import java.util.Timer;
import java.util.TimerTask;

public class TimeTicker extends TimerTask {

Date date = new Date();
Date dateLast = new Date();
private boolean bRunning = false;

@Override
public void run() {
dateLast = date;
date = DateX.GetToday();
if (bRunning) {
mainActivity.setDialogResult(DateX.FormatRfc822Date(date), iId);
}
}
}


In this example, our standard Java TimerTask implementation is running every second (not heavy-weight, I know - but it is the classical "hello world" example in the timer world.) Whenever we want it to send a timer event, it will do so using the setDialogResult() of mainActivity.

All well and good.

Once inside of mainActivity, we can easily update a few basic elements. When we try to invalidate the drawable surface to show the update however (a GUI function) at the time of this writing, things will go boom:


public void setDialogResult(String sResult, int iId) {
switch (iId) {
case BUTTON_MARK:
{
this.vtBanner.sText = sResult;
this.invalidate(); // BOOM!
}
break;
// ...
}
}


Maddeningly, until we understand Android's thread model, the reason things suddenly go south is not readily apparent. Indeed, if we use an Android Dialog Activity, things work just fine!

By way of example, the following View.OnClickListener will update the GUI via that same setDialogResult() member function, just as easy as expected:


public void onClick(View arg0) {
dialog.bOkay = bSetValue;
this.dialog.dismiss();
if (bSetValue) {
Editable eString = dialog.editTextName.getText();
mainActivity.setDialogResult(eString.toString(), iId);
}
}


It can even Toast!


public void setDialogResult(String sResult, int iId) {
switch (iId) {
case BUTTON_NEXT:
{
// Toast t = Toast.makeText(this.getContext(), sResult, 600);
// t.show();
this.vtBanner.sText = sResult;
this.invalidate(); // Works Fine!
}
break;
}
}


Why can one listener-laden Activity manage the Canvas, while even the lightest Thread, cannot?

One Thread to Draw Them All


Believe it or not, the reason why one class is blessed and another is cursed is simple: In the above example, even though the code is written as part of the main Activity class, our TimerTask is still effectively executing the code. Unfortunately, the timer running the TimerTask is not part of the main activity thread. It is another thread.

The Dialog, however, is a completely different case. Because Android Dialogs are Views, they will all share the same, common, execution thread.

Insidious, no? ( Surely knowledge is power !-)

Fortunately, the Android Framework 'wizards foresaw our dilemma: By allowing us to enqueue certain whole-life methods on-the-stack, the problem of having a non-GUI thread manage a GUI-Thread's ... uh ... gui ... is very well supported, indeed:


public void setDialogResult(String sResult, int iId) {
switch (iId) {
case BUTTON_MARK:
{
this.vtBanner.sText = sResult;
this.postInvalidate(); // Another Thread = NOT thread safe!
}
break;
case BUTTON_NEXT:
{
this.vtBanner.sText = sResult;
this.invalidate(); // Another Activity = Same GUI Thread
}
break;
}
}


-We simply need to be sure that non-GUI threads never use GUI access routines directly. -It is a thread safety thing. (i.e. Even relatively speaking, providing millions of synchronizing gatekeeper operations would slow everything down. The logic here is that it is better to make the developers work a little, than to make the computer work-a-lot. (yea, that logic sounds a lot like another ancient (1970!) pro-assembly-language argument to be sure... but we like Java, C++, and C# anyway. Computers got a whole lot faster, cheaper, and better!))

Want to discuss the slow death of java.util.Vector, anyone? (--me neither :)

Executive Summary


To conclude, when it comes to using Java's classic timers & threads, we can indeed do so ... even on Android - with relative impunity. Nevertheless, when doing so we must remember to always manage those secondary threads carefully. No mater what mechanism we may cobble-together to update Android's display, we must always be sure to access that Android UI only from the main user-interface-thread!

For more information on threading and thread-related issues, you can read more under the painless threading topic on the Android Developer's Site.

[ add comment ] ( 3299 views )   |  permalink

| 1 |