Thursday, July 9, 2009

APIs in J2ME

General APIs
The core APIs are defined by the underlying Connected Limited Device Configuration.

javax.microedition.io

Contains the Java ME-specific classes used for I/O operations.

javax.microedition.lcdui

Contains the Java ME-specific classes used for the GUI. LCDUI has a simple screen based approach where a single Displayable is always active at a time in the application user interface. LCDUI API provides a small set of displayables common in mobile device user interfaces: List, Alert, TextBox, Form and Canvas. For all displayables the device MIDP implementation has control over the presentation and layout of the displayable. Canvas is a low-level graphics surface for which an application has full control over what is rendered to it, although normally some space is reserved for system areas like screen title and indicators common in mobile device UIs. Since MIDP 2.0, Canvas also supports a full-screen mode that allows to make full screen graphics, which is especially useful for games.
LCDUI also has quite unique approach of abstract operations, called Commands. The placement of commands added to a displayable is completely up to the device implementation of this toolkit. The application programmer uses API specified command types to indicate the usage or purpose of the command in application user interface. Common types are BACK, EXIT, ITEM, SCREEN. The idea of the command abstraction is to make applications more portable between various different mobile device. Application developers should use the command types properly to indicate the purpose of an operation, and device implementation then places the operation to the common location for a given type in device's specific user interface style. This may be e.g. a specific key, like "a back navigation key" for BACK commands or button on screen.
The term LCDUI was actually a joke in JCP Expert Group that created it. It has not been opened up in the MIDP specifications but stands for Limited Capability Device User Interface. The joke was that no-one else really knows what it stands for. Then later the Programming Wireless Devices with the Java 2 Platform, Micro Edition book gave this term out.
Other common definitions have appeared. "Liquid Crystal Display User Interface" would reflect the fact that mobile phones normally use LCD displays; however, the API is not specifically tailored to this particular display technology. It is also said that "LCD UI" stands for "lowest common denominator" due to the fact the specific UI has simplest possible design.

javax.microedition.rms

Provides a form of persistent storage for Java ME. It's like a database for the mobile device.
"Record Store"(class) is used to store the Data: RecordEnumeration(Interface) , RecordComparator(Interface), RecordFilter(Interface), are used to apply user queries for sorting,filtering the data of all the data present; and comparison of contents of two or more RecordStores is done by these Interfaces.Data is stored and must be retrieved from the RecordStore using a ByteArray.(i.e; data is stored in Bytes(string.getBytes() and stored in ByteArray Byte a[])

javax.microedition.midlet

Contains the base classes for Java ME applications.

Specialized APIs added in MIDP 2.0

MIDP 2.0 saw the introduction of gaming and multimedia APIs and some optional packages.

javax.microedition.media

Contains the base classes of the multimedia playback. These are approximately a subset of the JSR 135 Java Mobile Media API.

javax.microedition.lcdui.game

A gaming API aimed at simple 2D sprite based games.

javax.microedition.pki

Authenticate APIs for secure connections.

Optional JSRs

The following JSRs are not part of MIDP (1.0 or 2.0) but provide extra functionalities on some handsets. However, there is no guarantee that a MIDP2.0 handset implement such APIs

javax.microedition.messaging

Wireless messaging API (optional), for sending SMS and MMS messages.

javax.microedition.pim

Personal information management API (optional), access the device's Address Book , to-do List, Calendar.

javax.microedition.io.file

The File Connection Optional Package (FCOP) is one of two optional packages defined by JSR 75 through the Java Community Process. The FileConnection API specified in JSR 75 gives access to the local file systems on devices like PDA. In order to overcome security issues MIDlet needs to include requested file permission in its JAD file under MIDLet-Permission property.

Development Tools

There are several different ways to create MIDP applications: Code can be written in a plain text editor, or you can use a more advanced IDE such as NetBeans, IntelliJ (with bundled Java ME plugin), or Eclipse (with plugins such as EclipseME) which has a user interface for graphically laying out any forms you create, as well as providing many other advanced features not available in a simple text editor.

Noteworthy Limitations of MIDP 1.0

  • MIDP 1.0 has no active rendering APIs
  • MIDP 1.0 has no support for direct access to image pixels (RGB data)
  • MIDP 1.0 has no support for full screen mode
  • MIDP 1.0 has no support for audio
  • MIDP 1.0 requires only HTTP support
  • MIDP 1.0 cannot query key status (although key events are supported)
  • The specifications are not always clear, leading to differences in implementations
  • Some limitations may be avoided by using a vendor-specific API or MIDP 2.0, which obviously reduces the portability of the application

Spruce Up Your Table Views

Setting the background color of your table view is very easy.  All you need to do is set the backgroundColor property to the color you want to see.  For example, I have created a table view here in the app delegate and simply set the background property from here:
UITableViewController *tvc = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
tvc.view.backgroundColor = [UIColor redColor];
    
[window addSubview:tvc.view];
    
[window makeKeyAndVisible];
If you are using sub-classing, you may also rather set this property in the initWithStyle.
You can use also an image as your background to really spice things up.
Here is that code:
UIView *backgroundView = [[UIView alloc] initWithFrame: window.frame];
backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"TableViewBackground.png"]];
[window addSubview:backgroundView];
[backgroundView release];
    
yourTableViewController = [[ATableViewController alloc] initWithStyle:UITableViewStyleGrouped];
yourTableViewController.view.backgroundColor = [UIColor clearColor];
[window addSubview:yourTableViewController.view];
    
[window makeKeyAndVisible];
 
This one takes a little more code - essentially you are putting an image into a view, inserting that into the app window and then setting the background to a transparent color. 
Simply setting the background color of the table view to the image would produce artifacts.  
That is it!  I hope that this tip will add some more pizazz to your apps!
As you can see, the this array is sorted. There you have it!

How To Add A Nice Background Image To Your Grouped Table View

Are you tired of your table views having the standard, boring, gray and white striped background?
Adding a nice image or pattern to your table views is one way of putting a little extra gloss to your UI. This is important, because gloss sells… However, if you have tried to do this yourself you already know that simply inserting an image into your table view will produce ugly artifacts.

What you need to do is create a view with your background image and add that view to your app’s window. Then you must set the table view’s background color to “clearColor”.
Here is how you would do that from the app delegate:
UIView *backgroundView = [[UIView alloc] initWithFrame: window.frame];
backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"TableViewBackground.png"]];
[window addSubview:backgroundView];
[backgroundView release];
yourTableViewController = [[ATableViewController alloc] initWithStyle:UITableViewStyleGrouped];
yourTableViewController.view.backgroundColor = [UIColor clearColor];
[window addSubview:yourTableViewController.view];
[window makeKeyAndVisible];
yourTableViewController is declared at the top level of the app delegate and ATableViewController is a subclass of UITableViewController that simply displays the rows and sections in the example.

Thursday, June 25, 2009

iPhone SDK dismiss the keyboard


Set the delegate on the text field that will bring up the keyboard. Add the following selector to the object that you set to be the delegate.

The controller's interface code
#import
@interface MyViewController : UIViewController {
IBOutlet UITextField *textField;
}
@property (nonatomic, retain) UITextField *textField;
@end
And the controller's implementation code
#import "MyViewController.h" 
@implementation MyViewController 
@synthesize textField;
-(BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == textField) {
[textField resignFirstResponder];
}
return YES;
}
@end

Thursday, June 11, 2009

Converting a J2ME MIDlet to a BlackBerry COD

Converting a J2ME MIDlet to a .COD involves the following steps:

  1. Download and install the RIM Java Development Environment
  2. Download and install Java SDK
  3. Copy the jad & jar files in question to the /bin/ directory of your BlackBerry JDE installation
  4. From the command line (make sure you are in the bin directory of your RIM JDE installation) type:
rapc import=“$your_JDE_dir\lib\net_rim_api.jar" codename=$your_app -midlet jad=$your_app.jad $your_app.jar
Where,
$your_JDE_dir  - is the directory of your RIM JDE installation,
$your_app          - is the name of the MIDlet you're trying to convert $your_app.jad        - is the name of the MIDlet descriptor and
$your_app.jar     - is the name of the MIDlet jar file
  1. The following files are generated:
$your_app.debug
$your_app.cod
  1. $your_app.cod is used to load the application onto the BlackBerry 
 To load the application onto the BlackBerry Simulator:
  • Launch the BlackBerry Device Simulator by selecting Start => Research In Motion => BlackBerry JDE => Device Simulator.
  • Once the simulator is loaded, install the .cod file by selecting File => Load Java Program and load the $YOUR_APP.cod from $JDE/bin/
  • On the BlackBerry Simulator desktop find your application and launch it. 

Android Application Lifecycle

In Android, the applications are run as a separate Linux process. So the application lifecycle is closely related to the process lifecycle. The application process lifecycle is handled by the system depending on the current system memory state.
In case of low memory, the Android system kills some less important process. The process importance is decided depending on the state of the process components.
The process types depending on the importance are as follows (from most important to least important):
1. Foreground process: A foreground process is the application process with which the user is currently interacting. The process is considered to be foreground if its Activity is at the top of the Activity stack (its onResume() has been called) or BroadcastReceiver is currently running (onReceive() method is currently getting executed) or its Service is executing callback functions like onCreate(), onStart() or onDestroy() methods.
2. Visible Process: A visible process is the process which has an Activity visible to the user (its onPause() method has been called).
3. Service Process: Service process contains a Service for which startService method is called and the service is running.
4. Background Process: The background process does not have any visible activities to the user. (Activity onStop() method has been called).
5. Empty Process: Empty process is the one that does not have any active application components. These processes are kept on for caching purpose.
It is important that application developers understand lifecycle of the application process. Not using these correctly can result in the system killing the application’s process while it is doing important work.

Thursday, May 28, 2009

The For-Each Loop in Objective-C

Loops are the gears of a
programming language, they help move the program to the next step. 
A For-Each loop is generally used when you
want your program to do something to a collection of objects.
For example, this For-Each loop prints out each string in an
array of strings:

    //For each loop
    //Create an array and add elements to it
    NSMutableArray *anArray = [[NSMutableArray alloc] init];
    [anArray addObject:@"Element 1"];
    [anArray addObject:@"Element 2"];
    [anArray addObject:@"Element 3"];
   
    //Use a for each loop to iterate through the array
    for (NSString *s in anArray) {
        NSLog(s);
    }
   
    //Release the array
    [anArray release];


  That is it!

Wednesday, May 27, 2009

For Loop in Objective-C

Loops are the gears of a programming language.

They help move the program to the next step. A For loop is generally used when you want your program to repeat an action a set number of times. 

Here is the syntax for the For Loop:
 
    for (int y = 0; y < 3; y++) {
        NSLog(@"y = %i", y);
    }
 
 
That is it!

Thursday, May 14, 2009

Sorting An Array in Objective-C

Arrays are structures used to hold a list of objects. Sometimes
though you may want to sort the order that the elements appear.

Doing this is actually pretty simple once you know how,
essentially you will be using the NSArray sortedArrayUsingSelector
method.

For example, if you create an array like so

NSMutableArray *anArray = [[NSMutableArray alloc] init];
[anArray addObject:@"B"];
[anArray addObject:@"A"];
[anArray addObject:@"C"];
and then write out the contents of the array to the log using a
foreach loop the results will look like this:

[Session started at 2009-03-25 16:57:55 -0400.]
2009-03-25 16:57:58.647 SortigArray[3403:20b] B
2009-03-25 16:57:58.648 SortigArray[3403:20b] A
2009-03-25 16:57:58.649 SortigArray[3403:20b] C

Obviously, the contents of the array stay in the same order in
which they were inserted.

What you could do is create another array, sorted, using the
sortedArrayUsingSelector method of NSArray. Here is how:
NSArray *sortedArray = [anArray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
The odd (for some anyway) piece of this code is the
@selector(caseInsensitiveCompare:) component of the code. This is
a method passed to the function that instructions NSArray on how
to sort the array.

At any rate, if you run through the array as before and print out
the results to the log you will get this:

[Session started at 2009-03-25 17:07:18 -0400.]
2009-03-25 17:07:21.832 SortigArray[3537:20b] A
2009-03-25 17:07:21.833 SortigArray[3537:20b] B
2009-03-25 17:07:21.834 SortigArray[3537:20b] C

As you can see, the this array is sorted. There you have it!

Thursday, May 7, 2009

Adding Background Colors and Images to Your Table Views

Setting the background color of your table view is very easy.
All you need to do is set the backgroundColor property to the
color you want to see. For example, I have created a table view
here in the app delegate and simply set the background
property from here:

UITableViewController *tvc = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped]; tvc.view.backgroundColor = [UIColor redColor]; [window addSubview:tvc.view]; [window makeKeyAndVisible];
If you are using sub-classing, you may also rather set this property in the initWithStyle.

You can use also an image as your background to really spice things up.

Here is that code:

UIView *backgroundView = [[UIView alloc] initWithFrame: window.frame]; backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"TableViewBackground.png"]]; [window addSubview:backgroundView]; [backgroundView release];
yourTableViewController = [[ATableViewController alloc] initWithStyle:UITableViewStyleGrouped]; yourTableViewController.view.backgroundColor = [UIColor clearColor]; [window addSubview:yourTableViewController.view]; [window makeKeyAndVisible];

This one takes a little more code - essentially you are putting an image into a view, inserting that into the
app window and then setting the background to a transparent color. Simply setting the background
color of the table view to the image would produce artifacts.

That is it! I hope that this tip will add some more pizazz to your apps!

Monday, April 27, 2009

General Coding Tips

Avoid the Object.getClass() Method

Avoid using the Object.getClass() method, because it is not efficient and it produces garbage (the Class object) that is never collected. Also avoid using the example.class literal. Behind the scenes, this generates Class.forName(“Example”).

Writing Efficient Loops

You should always factor loop invariant code out of a loop, as in the following example:

    for(int i = 0; i < >
...

}

This code results in vector.size() getting called each time through the loop, which is inefficient. If your container is likely to have more than one element, it is much faster to assign the size to a local variable. In addition, this example using pre-increment (++i) results in smaller code than post-increment (i++). The optimized code appears below:

     int size = vector.size();
for(int i = 0; i < style=""> ...
}

Alternatively, if the order in which you iterate over items is not important, you can iterate backward. Iterating backward avoids the extra local on the stack, and the comparison is also faster, as the following example illustrates:

for(int i = vector.size() - 1; i >= 0; --i) {

...

}



Optimizing Subexpressions

If you ever use the same expression twice, do not rely on the compiler to optimize it for you. Use a local variable, as in the following example:

one(i + 1); two(i + 1); // Avoid
int tmp = i + 1; 
one(tmp); 
two(tmp); // Prefer

Avoid java.util.Enumeration
Avoid using java.util.Enumeration unless you are using it to hide data (in other words, returning an Enumeration of data rather than the data itself). The following example shows a typical use of an Enumeration:

for (Enumeration e = v.elements(); e.hasMoreElements();) {
   o = e.nextElement();
   ...
}

Asking a vector or hash table for an Enumeration object creates unnecessary garbage and is slow. Instead, you can iterate over the elements yourself, as in this example:

for(int i = v.size() - 1; i >=0; --i) {
   o = v.elementAt(i);
   ...
}

If the vector might be modified by another thread, you must synchronize the iteration:

synchronized(v) {
   for(int i = v.size() - 1; i >=0; --i) {
      o = v.elementAt(i);
      ...
   }
}

In Java 2 Platform, Standard Edition (J2SE), you would use an Iterator for this, but Iterators are not available in Java 2 Platform, Micro Edition (J2ME).

Returning null
If you are writing a public method that returns an object, it should never return null unless the following occurs:

  • a null is expected during normal program operation.
  • the javadoc @return parameter states that null is a possible return value.

If a null is not normally expected, then the method should throw an appropriate exception, which forces the caller to deal with the problem explicitly. The caller is not expected to check for a null return value, unless the documentation specifies otherwise.

Passing null into Methods
Do not pass null parameters into an API method unless the API Reference documentation explicitly states that the method supports them.

Passing null into a Constructor
To avoid ambiguity when passing a null into a constructor, you should use this form:

new someObject ((Object)null);

A class can have two or more constructors, such as SomeObject(String) and SomeObject(Object), where passing in a null does not identify which constructor to use. As a result, the compiler reports an error. Not all supported constructors necessarily appear in the API Reference documentation, because some constructors are for internal use only. By casting the null to the appropriate object, you indicate precisely which constructor the compiler should use. This practice also ensures forward compatibility if later releases of the API add new constructors.

Optimizing Division Operations
Division operations are slow on the BlackBerry Wireless Handheld because its processor does not have a hardware divide instruction. When you write code that divides a positive number by two, you should use “shift right by one” instead. The following example illustrates this:

midpoint = width / 2; //avoid this
int = width >> 1; //prefer this

This does not work for negative values. Only use “shift right” (>>) when you know you are dealing with a positive value. It does not work for negative values.

Managing Garbage Collection
Avoid calling System.gc() to perform garbage collection. On a full handheld, this could take two seconds. Let the virtual machine (VM) collect garbage automatically.


Casting Using instanceof
It is more efficient to use instanceof instead of classCastException to evaluate whether a cast succeeds. Here is an example of using a try/catch block to catch the classCastException:

try {
   (String)x.whatever();
} catch(ClassCastException e) {
   // something else
}

Alternatively, you can use instanceof operator:

if(x instanceof String) {
   (String)x.whatever();
} else {
   // something else
}

Using instanceof is faster. The only time you should use the try/catch block is when the failure of the cast is an exceptional circumstance. The BlackBerry Java Development Environment (JDE) compiler and the VM are optimized to perform only one class check in the first block of code. This is true of any code in which the cast is run immediately following a branch determined by an instanceof check. Always perform the cast immediately after the branch so that the optimization can be performed.

Using Longs for Unique Identifiers
You should use longs rather than strings for unique constants, such as globally unique identifiers (GUIDs), hash table keys, and state/context identifiers. So that unique identifiers remain unique across all third-party application developers, you should use randomly generated keys based on a hash of some string. In the input string, you should include enough information to make it unique.

Memory Management tip

Dealing with memory on the iPhone is one of the most difficult
challenges that you will face as a new iPhone developer. Today,
I am going to show you a very simple tip that will help you
debug the memory problems that you are like to face.

One thing that you have to worry about with memory management is
the "retain count" of an object. The retain count is how the
system keeps track of the memory used by an object. If an
object's retain count is zero and your attempt to access it
your app will crash; if you do not make sure the retain
count of your object is 0 when the object goes out of focus you
will have a memory leak.

Clearly, it is important to be able to find out what the current
retain count of an object is. Here is how you can do this:

NSLog([NSString stringWithFormat:@"Retain Count:%i", [someObject retainCount]]);
This writes out the current retain count to the log. The
important function is [someObject retainCount].

Friday, April 24, 2009

Strings in iPhone

The iPhone uses a special class called "NSString" to handle strings. Here is an example of a common use of NSString.
NSString *myString = @"This is my string";
You can use an NSString object in the alert that you learned about last week. Here is how you would use the NSString object "myString" in an alert:
NSString *myString = @"This is my string";

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"UIAlertView"
message:myString
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
Notice that the "message" argument of the alert you created above uses the NSString object as an argument. Another thing you will be doing with strings is combining strings to make new ones.
For instance, if I had two strings - a first and a last name - and I wanted to create a new string for a full name I could do something like this:
NSString *firstName = @"Matt";
NSString *lastName = @"Campbell";
NSString *fullName = [NSString stringWithFormat:@"My name is %@ %@",
firstName, lastName];

If you were to put fullName into an alert it would say "My name is Matt Campbell". How the stringWithFormat function works is that you give it a string with special symbols in it. The function will replace the symbols with the strings in give it as the next arguments to the function.
Note that when you are using the alert object you need to follow the "alloc, use, release" pattern while the NSString only requires you to use the function after which you may safely forget about it.
This has something to do with the memory management features of the iPhone. Essentially, when you use an object's "alloc" you need to "release" at some point in the future. NSString does not use an alloc in this instance so it does not need to be released while UIAlert does. More details about memory management will be discussed in this mailing list in the future.

Alert box in iPhone

An alert box is a quick way to communicate to your users. Alert boxes look like a rounded square with a message and a button on it. You may put this code into your project to get an alert box:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"UIAlertView"
message:@"Hi There!" delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles: nil];

[alert show];
[alert release];

As you can see from the code above, square brackets are the order of the day in Objective-C, the iPhone programming language. For now, note that text that comes right after the word "message:". This is where you control what the alert box presents to the user.
Finally, notice the overall pattern of using objects in Objective-C: alloc, "do stuff", release. This is something that you will be using often in your iPhone programming.

Looping in Objective-C

Looping in Objective-C

Loops are the gears of programming: it is what makes the code take action.  The two loops I use most often is the for loop (to do a predefined number of steps) and what is usually called a foreach loop (to move though a list of objects).

//This loop simply repeats an action
//a set amount of times:
for (int i=0; i<=3; i++)
    NSLog([NSString stringWithFormat:@"i=%i", i]);
  
//Create an array of strings for the next example:
NSMutableArray *bunchOfThings = [[NSMutableArray alloc] init];
[bunchOfThings addObject:@"Zero"];
[bunchOfThings addObject:@"One"];
[bunchOfThings addObject:@"Two"];
[bunchOfThings addObject:@"Three"];
  
//This is sometimes called a "for each" loop
//Using this list will repeat actions for each
//object in a list.
//Hint: you can use this for any type of list of
//objects so if you have list of custom defined
//objects this is an easy way to work with them all
//at one time.
for(NSString *s in bunchOfThings)
    NSLog([NSString stringWithFormat:@"s=%@", s]);
  
//The array must be released since it was alloc/init earlier.
[bunchOfThings release];


That is it!