Subscribe via RSS
Select Language

BlackBerry API Hidden Gems (Part Two)

BlackBerry Development Advisor

Gems
 
In yesterday's BlackBerry API Hidden Gems post, I showed you some of my favorite classes and methods oft overlooked within BlackBerry® APIs. I've got a few more in store for you today, so let's get started!
 

IntVector 

In the net.rim.device.api.util package there are a bunch of collections for storing primitive Java types, such as ‘int’, ‘byte’, and ‘long’, which mirror the equivalent java.util classes.  Using these classes to store the primitive types is more efficient in both memory and time than storing wrapper objects in standard java.util collections.

My favourite example is IntVector.  IntVector has the same methods as java.util.Vector but stores primitive ‘int’ values instead of Object references.  Under the hood it uses an int[] array to store values instead of an Object[] array and therefore no conversions between ‘int’ and Integer are necessary.   This makes IntVector much better for storing ‘int’ values than java.util.Vector as it is both faster and uses less memory.  It is also fully synchronized, just like java.util.Vector.

Other adapted classes in net.rim.device.api.util include:
  • ByteVector and LongVector: similar to IntVector but for ‘byte’ and ‘long’ types.
  • IntHashtable, LongHashtable: adaptations of Hashtable that use primitive ‘int’ and ‘long’ values as the keys, and Objects as the values.
  • ToIntHashtable, ToLongHashtable: similar to IntHashtable and LongHashtable but uses Objects for the keys and ‘int’ and ‘long’ for the values.

Here is an example usage of IntVector to store a list of high scores, with the highest scores at the lowest indices.
 

public class HighScores {

private IntVector _scores;

public HighScores() {
_scores = new IntVector();
}

public void add(int score) {
if (_scores.contains(score)) {
return; // already there
}

boolean isAdded = false;
for (int i = 0; i < _scores.size(); i++) {
if (_scores.elementAt(i) < score) {
_scores.insertElementAt(score, i);
isAdded = true;
break;
}
}

if (!isAdded) {
_scores.addElement(score);
}

while (_scores.size() > 10) {
_scores.removeElementAt(_scores.size() - 1);
}
}

public int getHighScore() {
if (_scores.isEmpty()) {
return 0;
} else {
return _scores.elementAt(0);
}
}

public int[] getHighScores() {
int[] array = new int[_scores.size()];
_scores.copyInto(array);
return array;
}
}

 

Timer and TimerTask 

Like weak references, this next gem is also defined in CLDC but is mostly overlooked for its utility.  Suppose you want to perform background tasks in your application.  You can either use Application.invokeLater() or devise a grandiose background thread implementation that cleverly uses Java® synchronization primitives to efficiently perform background event dispatching.  The former consumes your application’s event thread, potentially causing UI lag, and the latter is just a lot of work.

I recommend whipping out Timer and TimerTask for background task processing.  Each Timer object has exactly one background thread which processes TimerTasks sequentially.  These tasks can be scheduled to occur immediately, after some delay, at a particular time, or repeatedly at a given interval.

The sample below shows how to use Timer and TimerTask to notify an object on a non-event thread about the user pressing the trackball.
 

public class MyScreen extends net.rim.device.api.ui.container.MainScreen {

private Timer _timer;

public MyScreen() {
this.setTitle("Timer Demo");
this._timer = new Timer();
}

public void onTrackballClick() {
System.out.println("Quit pressing the trackball!");
}

protected boolean navigationClick(int status, int time) {
this._timer.schedule(new ClickTask(), 0);
return super.navigationClick(status, time);
}

private class ClickTask extends TimerTask {
public void run() {
onTrackballClick();
}
}
}

 

There are many more hidden gems in the BlackBerry® SDK but just not enough time here to share them all.  I will be doing a talk on this topic at the 2009 BlackBerry Developer Conference and plan to talk about some hidden gems not mentioned here as well as some lesser-known cool features of the JDE itself.  If you have found any hidden gems of your own please comment on this post to share your great discovery with the world!  I’d love to know which APIs you find useful.
 
 

Comments
by Ashworth65ca on 08-13-2009 02:36 PM

I just found the TimerTask a few weeks ago, and it has been a big help within my application.  I would like to know understand the threading model better. I did not take any Java or OOP when I was in school it was all patch programming.  Any threading information would be very helpful also.

 

Another request I would like to make would be how to make the UI fields look nicer then the default.  I know you have to override the paint method, but are there any other hidden UI gems that could be shared?

 

Thanks, 

Justin

by BlackBerry Development Advisor on 08-13-2009 03:46 PM

Hi Justin,

 

The thread model on BlackBerry is more-or-less the same as Java code running on a desktop PC.  It is defined by the JVM and CLDC specifications and therefore follows the standard Java thread model.  You can launch a thread by creating an instance of java.lang.Thread and invoking its start() method.  Each BlackBerry application is limited in the number of threads it can have running at any given time, and if you hit that upper limit then start() will throw java.lang.OutOfMemoryError... but I've never reached the limit before!  Is there anything in particular you'd like to know about the BlackBerry threading model?

 

As for the UI, you are right that overriding paint() is one way to customize the look-and-feel of the user interface components, but it is very "low-level".  I don't often work with UI code so I don't know of many hidden gems there.  But for not-so-hidden features... In JDE 4.6.0 the package net.rim.device.api.ui.decor was added to allow an easy way to set the background and border of a field.  And in JDE 5.0.0 there have been a few improvements too.  The class net.rim.device.api.ui.FontManager was added and the existing Font API augmented to allow much more rich control over the text displayed on a UI.  Also, net.rim.device.api.ui.TransitionContext was added to provide nifty screen transistion (fade, slide, wipe, zoom).  I'm sure there are more changes coming down the pipe too!

 

Thanks for your comments.  I'll look into some UI hidden gems to incorporate into my presentation at DevCon.  I'm sure they're out there, just waiting to be found!  Anyone know of any?

 

--Denver

by Rafael Jesus(anon) on 08-16-2009 07:07 PM
How i do to sort a vector easy like vector.sort();
by BlackBerry Development Advisor on 08-17-2009 10:12 AM - last edited on 08-17-2009 10:13 AM

There are a couple of different solutions to sorting a Vector.

 

Solution 1: Copy into an Array

The first and most obvious solution is to copy the Vector's contents into an array, invoke Arrays.sort() on the array, and then copy the array back into the Vector.  Of course, this is somewhat wasteful because you have to create a temporary array and copy the elements in to and out of the array.  Here is one way to implement this method:

 

public static void sort(Vector vector, Comparator comparator) {
    synchronized (vector) {
        Object[] array = new Object[vector.size()];
        vector.copyInto(array);
        net.rim.device.api.util.Arrays.sort(array, comparator);
        for (int i = 0; i < array.length; i++) {
            vector.setElementAt(array[i], i);
        }
    }
}
 

Solution 2: Vector Subclass

To avoid the waste created in solution 1, you can instead create a subclass of Vector, which gives you access to the protected variable "elementData", and sort the elements in-place.  When using this solution, make sure to declare the sorting method "synchronized" in order for your Vector implementation to remain thread safe.  Here is a simple implementation of this solution:

 

public class MySortableVector extends Vector {
    public synchronized void sort(Comparator comparator) {
        net.rim.device.api.util.Arrays.sort(this.elementData, 0,
            this.elementCount, comparator);
    }
}

 

Solution 3: SimpleSortingVector

There is a RIM custom class that provides the functionality to sort a Vector: net.rim.device.api.util.SimpleSortingVector.  It is basically an implementation of solution 2 and provides the option to either sort the elements of the Vector as they are added or perform a sort on the Vector on demand.  There is also a class SimpleSortingIntVector which is the same as IntVector but sorts its elements like SimpleSortingVector.

 

Hope this helps.

 

--Denver

Message Edited by dconeybeare on 08-17-2009 10:13 AM
by Nazmul Idris(anon) on 08-17-2009 03:05 PM

Hi Denver

 

Great articles! I use Timers everywhere for background thread stuff, and it works great. I also use it for an GUI animation framework that I've created for all my ScreamingToaster apps for BlackBerry. 

 

Here's another class I find very useful - StringUtilities.stringToKeywords();. I use this all the time in custom lists that I create.

 

Another class that I've have to create myself is ArrayList. It's like Vector, but not synchronized. It's much more lightweight than using Vector, but much easier to use than direct array manipulation. I can share the code with this blog if there's an easy way to do so.

 

Thanks

Nazmul.

Post a Comment
Be sure to enter a unique name. You can't reuse a name that's already in use.
Be sure to enter a unique email address. You can't reuse an email address that's already in use.
Type the characters you see in the picture above.Type the words you hear.
About BlackBerry Developer's Blog
The Developer Relations team at RIM is focused upon providing solutions for all stages of the BlackBerry development lifecycle. The Developer’s Blog is a forum to share best practices, market insight and developer-engagement opportunities with the development community. The Developer’s Blog complements our existing outreach programs (BlackBerry Developer Conference and Developer Newsletter) while giving us an opportunity to share our personalities too!

About the Author
  • Adam is a product manager at RIM in the platform product management team. Adam’s focus and responsibility is on setting the strategy and direction of the BlackBerry web platform, including the web developer tooling products. He is also responsible for RIM’s involvement with the Eclipse Foundation and the Pulsar project. Adam hopes this blog will allow him to share his knowledge, viewpoint and passion for BlackBerry, but is really interested in what capabilities the community feels should be added to the web platform and tooling to create even more compelling web applications and content.
  • Adam is an Application Development Consultant with the Developer Relations Team at RIM. As a member of the Developer Relations Team, Adam manages the technical relationship with ISVs who specialize in producing applications based on web technologies. Adam's development background consists of a degree in Computer Science and work in web development for both the insurance and technical support industries.
  • I joined Research In Motion in 2005 working with Independent Software Vendors (ISVs) who specialize in Bluetooth, GPS, multimedia, and gaming. As a senior member of the Developer Relations Team it's my mandate to not only support the application development efforts for a number of ISVs, but it's also to act as a voice at RIM for third party application developers. Like RIM, my roots are in the enterprise world, but over the past couple of years I've quickly adapted to the consumer space, and that's where I spend most of my time today.
  • Chris has been at RIM since 2001 and runs R&D for the BlackBerry Development Platform. Practically speaking, this means day-to-day he is busy harnassing the innovative power of a talented group of RIM engineers to serve the needs of the BlackBerry Developer community.
  • Denver is a software developer at RIM, working on the BlackBerry Java APIs. Denver has been working at RIM for 4 years and started in automated testing of the APIs, making the switch to development in 2008. He enjoys programming, and finds developing for BlackBerry especially interesting. Denver also enjoys writing and sharing his development experiences, and hopes his posts will be useful and informative to other developers out there.
  • With more than a half-decade of experience in the wireless industry, Douglas “tr0n” Soltys has chronicled the evolution of mobile culture in both the consumer and enterprise space. Prior to joining RIM, Douglas manned the helm of wireless weblogs QuicklyBored and BlackBerry Cool. When not blogging about all things BlackBerry®, Douglas can be found extolling the virtues of Strunk and White. He uses a BlackBerry® Bold™.
  • As Manager, Developer Programs at Research In Motion (RIM), Ian and his team are responsible for the design and delivery of programs and services for BlackBerry developers – including support tools and resources, recognition, advocacy, go-to-market, and regional programs. Ian is passionate about making sure that BlackBerry developers have everything they need in order to be successful from the inception of an idea to app deployment or commercialization. Prior to joining Developer Relations, Ian was a Product Manager for various BlackBerry solutions including the BlackBerry Java Development Environment, BlackBerry Maps, and BlackBerry Mobile Voice System.
  • Kamen is a Senior Architect, Strategic Initiatives, and started at RIM in 2001 with already established expertise in development for the BlackBerry platform and other mobile devices. Since then Kamen has been part of both device and server-side design and development activities - helping to evolve the BlackBerry development environment. As part of the Strategic Initiatives group he is now involved in looking for new ways to bring additional value to third party developers.
  • Mike Kirkup is the Director for the Developer Relations program at Research In Motion (RIM), which is responsible for managing the technical relationships and programs for RIM’s developer community worldwide. Mike and his team work with RIM’s developer community to provide support and guidance as developers work to integrate their applications to the BlackBerry platform. Mike joined RIM in 2001 as a Security Software Developer in RIM’s Wireless Security Group. As part of the Wireless Securty group, Mike contributed to the development of the BlackBerry Cryptography API, S/MIME and PGP implementations. Mike holds a Masters of Management Science and a Bachelor of Mathematics from the University of Waterloo.
  • When he’s not out riding the waves off the sunny eastern coast of Australia, you’re likely to find Neil at his desk answering emails, taking calls, or cutting code in his role of Application Developer Consultant for RIM. As a member of the Developer Relations team Neil spends a great deal of time working with Independent Software Vendors (ISVs) in Australia and New Zealand helping them get the most out of the BlackBerry platform, and also working behind the scenes to ensure everything is “most excellent” for all developers. Neil’s been developing for the BlackBerry for five years and prior to joining RIM ran a successful BlackBerry software company. He also likes hats.
  • Prosanta is a member of the BlackBerry Developer Relations team specializing in Web Development. Prosanta’s focus is on developing out the web platform and tools associated with web development while supporting the development efforts of a number of Independent Software Vendors. Prior to joining RIM, Prosanta had worked on numerous web portals for major multinational firms writing both front and backend code.
  • Tim is the Development Manager for BlackBerry development tooling. This includes Java, Web and also Theme creation tools. He is always hanging out in the development forums trying to help out where he can and to bring your feedback into the next releases of BlackBerry tooling. You’ll also see Tim presenting various topics at the BlackBerry Developer Conference and Wireless Enterprise Symposium so be sure to stop by and say hi. Just don’t start talking about cars or Batman or you won’t be able to get rid of him.
  • I work on the Developer Relations team at RIM, with a focus on enterprise applications for Sales Force Automation, Health Care, Public Safety and Real Estate. I started on the team at the beginning of 2007.
Categories