Tuesday 2 August 2011

Multiple Threads

Be careful !!!!

Computers with strong CPU and huge memory will cause programmers use multiple threads to speed their programs. Multiple thread is necessary.
  • put some calculation to the background
  • put an unsave thread to a separate thread 
Creating threads:

import java.lang.*;public class Counter extends Thread
{                     
        public void run()                      
        {             
        ....           
        }


}

or

import java.lang.*;
public class Counter implements Runnable
{
        Thread T;                       
        public void run()                      
        {                             
        ....           
        }
}

Be careful !!!

Be careful of your multiple threads!!!!   Sometimes, they may cause problem, especially in GUI.

Example:

When pop up a dialog box, and change the screen orientation, the screen will no respone. After review and chang some multiple threads, the bug is disappeared.




 Reason:

The dialog box will stop all the threads, some GUI threads also will stop. This causes the screen no respone.

Conclusion:

Use multiple threads is necessary, but be careful.

Friday 15 July 2011

Testing a BlackBerry device application

BerrySync is a project which involve into BlackBerry and Firefox Sync by using JAVA ME. For testing a BlackBerry application, RIM suggest:

  • Testing applications on a BlackBerry Smartphone Simulator
  • Testing applications on a BlackBerry device
  • Testing applications using the compiled .cod files



 Testing a BlackBerry device application (1) 
                                        -- Testing applications on a BlackBerry Smartphone Simulator

 After you develop and compile your application, you can test it on the BlackBerry® device. The most common first step is to set the BlackBerry® Java® Development Environment to use a BlackBerry® Smartphone Simulator. The BlackBerry Smartphone Simulator runs the same Java code as the BlackBerry devices, so the BlackBerry Smartphone Simulator provides an accurate environment for testing how applications will function on a BlackBerry device. The BlackBerry JDE includes current versions of the BlackBerry Smartphone Simulator. To download additional versions of the BlackBerry Smartphone Simulator, visit http://www.blackberry.com/developers/index.shtml.

http://www.cs.toronto.edu/~delara/courses/csc309/guide/rim/core.pdf  )


There is the instruction of "Setting up your machine" which made by my teammate Carlin Woshkulak Desautels.

Description

  1. Download BB Eclipse IDE:
  2. Download Simulators:
  3. Install Everything
  4. Install the BB 5.0 JRE
  5. Set up debug environments
  6. If the Project fails to package
    • Add the directory of jar.exe to the system build path
    • C:\Program Files (x86)\Java\jdk1.6.0_25\bin

  • In steps 1-4, the downloads require a blackberry developer account
  • In step 6, your systems java JDK must be 32-bit that is an example path of java 1.6.25
  •  In step 5, I will suggest to "Duplicate" a existing one, and then "Edit" it.

After setting up the machine, you can select your "BlackBerry Project", then click "Run on BlackBerry Simulator" or "Debug on BlackBerry Simulator". The result will shows on console. 


The BlackBerry Plug-in also has "Debug Perspective" available. The button locate on the top right corner.



Testing a BlackBerry device application (2) 
           --Testing applications on a BlackBerry device

After you test your application on the BlackBerry® Smartphone Simulator, you can install your application on a BlackBerry device. If your application uses signed APIs, you might need code signing keys. After you install the application on the BlackBerry device, you can open the application and test its functionality and performance.
For debugging purposes, you can attach your device to the BlackBerry® Integrated Development Environment and use the debugging tool to step through your application code. The BlackBerry IDE can be useful if you are trying to identify a network or Bluetooth® issue, or other issues that are difficult to simulate.



Register to use protected BlackBerry APIs

  1. Visit www.blackberry.com/JDEKeys and complete the registration form.
  2. Save the .csi file that Research In Motion sends to you. The .csi file contains a list of signatures and your registration information. If the BlackBerry® Signing Authority Tool administrator does not provide you with the .csi file or the Registration PIN and you are an ISV partner, contact your ISV Technical Partnership Manager. If you are not an ISV partner, send an email message to jde@rim.com.
  3. Double-click the .csi file to start the BlackBerry Signing Authority Tool .
  4. If a dialog box appears that states that a private key cannot be found, follow the instructions to create a new key pair file.
  5. In the Registration PIN field, type the PIN that RIM provided.
  6. In the Private Key Password field, type a password of at least eight characters. The private key password protects your private key. If you lose this password, you must register again with RIM. If this password is stolen, contact RIM immediately.
  7. Click Register.
  8. Click Exit.



Install signing key:
  • After completing the registration from, RIM will send 3 .csi files which separated in 3 e-mails with the instruction.
  • Follow the instruction to install the signing key.

Install BlackBerry desktop software:

Load on BlackBerry device:
  • In Package Explorer View, Right-click your "BlackBerry Project" > Click BlackBerry > Sign with Signature Tool
  • In Package Explorer View, Right-click your "BlackBerry Project" > Click BlackBerry > Load Project(s) on Device

Debug on BlackBerry device:
  • In BlackBerry Plug-in, BlackBerry > Debug As > BlackBerry Device

Friday 8 July 2011

BlackBerry Network Communication

There are 3 ways to make a network connection in BlackBerry.











Code Examples:

V6.0
 Reference:  http://docs.blackberry.com/en/developers/deliverables/21129/BlackBerry_Java_SDK-Development_Guide--1327377-1108115628-001-6.0-US.pdf


import net.rim.device.api.io.URI;
import net.rim.device.api.io.messaging.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.system.Application;
import java.io.*;
public class NetworkSample extends UiApplication
{
public static void main(String[] args)
{
NetworkSample app = new NetworkSample();
app.enterEventDispatcher();
}
public NetworkSample()
{
pushScreen(new NonBlockingSenderSample());
}
}
class NonBlockingSenderSample extends MainScreen
implements FieldChangeListener
{
ButtonField _btnNonBlock = new ButtonField(Field.FIELD_HCENTER);
private static UiApplication _app = UiApplication.getUiApplication();
public NonBlockingSenderSample()
{
_btnNonBlock.setChangeListener(this);
_btnNonBlock.setLabel("Fetch page");
add(_btnNonBlock);
}

public void fieldChanged(Field button, int unused)
{
if(button == _btnNonBlock)
{
NonBlockingSenderDestination destination = null;
try
{
//URI uri = URI.create("http://www.blackberry.com");
URI uri = URI.create("https://auth.services.mozilla.com/user/1.0/nprm3itjzzndm2bh2tmtmzbanfkw4mwh/node/weave"); 
 
NBSDMsgListener responseListener = new NBSDMsgListener();
destination = (NonBlockingSenderDestination)
DestinationFactory.getSenderDestination
("CommAPISample", uri);
if (destination == null)
{
destination =
DestinationFactory.createNonBlockingSenderDestination
(new Context("CommAPISample"), uri, responseListener);
}
// Send message to retrieve the response
destination.send();
}
catch(Exception e)
{
// process the error
}
}
}
}
class NBSDMsgListener implements MessageListener
{
public void onMessage(Destination dest, Message msg)
{
String payload = null;
if (msg instanceof ByteMessage)
{
ByteMessage reply = (ByteMessage) msg;
payload = (String) reply.getStringPayload();
} else if(msg instanceof StreamMessage)
{
StreamMessage reply = (StreamMessage) msg;
InputStream is = reply.getStreamPayload();
byte[] data = null;
try {
data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
} catch (IOException e) {
}
if(data != null)
{
payload = new String(data);
}
}
if(payload!=null)
{
synchronized(Application.getEventLock())
{
UiApplication.getUiApplication().pushScreen

(new HTTPOutputScreen(payload));
}
}
}
public void onMessageCancelled(Destination arg0, int arg1)
{
// process message cancelled notification
}
public void onMessageFailed(Destination arg0, MessageFailureException arg1)
{
// process message failed notification
}
}
class HTTPOutputScreen extends MainScreen
{
RichTextField _rtfOutput = new RichTextField();
public HTTPOutputScreen(String message)
{
_rtfOutput.setText("Retrieving data. Please wait...");
add(_rtfOutput);
showContents(message);
}
// After the data has been retrieved, display it
public void showContents(final String result) {
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
_rtfOutput.setText(result);
}
});
}
}

v5.0
Reference:  http://docs.blackberry.com/en/developers/deliverables/21129/BlackBerry_Java_SDK-Development_Guide--1327377-1108115628-001-6.0-US.pdf

Notes: 
Comment out: creating network transport list part.
Reason: 1) In this part, TcpCellularOptions.isDefaultAPNSet() belongs to jre 6.0 API

              2) There is a default list available.

import net.rim.device.api.io.transport.*;
import net.rim.device.api.io.transport.options.*;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.util.Arrays;
import java.io.*;
import javax.microedition.io.*;
public class NetworkSample extends UiApplication
{
public static void main(String[] args)
{
NetworkSample app = new NetworkSample();
app.enterEventDispatcher();
}
public NetworkSample()
{
new HTTPConnectionSetup();
}
}
class HTTPConnectionSetup
{
ConnectionFactory _factory = new ConnectionFactory();
public HTTPConnectionSetup()
{
/*****************************************************************************
Comment out: creating network transport list 
 *****************************************************************************
// Create preference ordered list of transports
int[] _intTransports =
{ TransportInfo.TRANSPORT_TCP_WIFI,
TransportInfo.TRANSPORT_WAP2,
TransportInfo.TRANSPORT_TCP_CELLULAR
};
// Remove any transports that are not (currently) available
for(int i = 0; i < _intTransports.length ; i++)
{
int transport = _intTransports[i];
if(!TransportInfo.isTransportTypeAvailable(transport)
|| !TransportInfo.hasSufficientCoverage(transport))
{

Arrays.removeAt(_intTransports, i);
}
}
// Set options for TCP Cellular transport
TcpCellularOptions tcpOptions = new TcpCellularOptions();
if(!TcpCellularOptions.isDefaultAPNSet())
{
tcpOptions.setApn("My APN");
tcpOptions.setTunnelAuthUsername("user");
tcpOptions.setTunnelAuthPassword("password");
}
// Set ConnectionFactory options
if(_intTransports.length > 0)
{
_factory.setPreferredTransportTypes(_intTransports);
}
_factory.setTransportTypeOptions(TransportInfo.TRANSPORT_TCP_CELLULAR,
tcpOptions);
_factory.setAttemptsLimit(5);

*****************************************************************************/
 
 
// Open a connection on a new thread
Thread t = new Thread(new Runnable()
{
public void run()
{
//ConnectionDescriptor cd = _factory.getConnection("http://www.blackberry.com");
ConnectionDescriptor cd = _factory.getConnection("https://auth.services.mozilla.com/user/1.0/nprm3itjzzndm2bh2tmtmzbanfkw4mwh/node/weave");
// If connection was successful, fetch and show the content from
// the web server
if(cd != null)
{
Connection c = cd.getConnection();
displayContent(c);
}
}
});
t.start();
}
private void displayContent(final Connection conn)
{
// When the connection thread completes, show the data from the web server
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
UiApplication.getUiApplication().pushScreen(new HTTPOutputScreen(conn));
}
});
}
}
class HTTPOutputScreen extends MainScreen
{
RichTextField _rtfOutput = new RichTextField();
public HTTPOutputScreen(Connection conn)
{
// Create a container for the data, and put it on the screen
_rtfOutput.setText("Retrieving data. Please wait...");

add(_rtfOutput);
// Retrieve the data from the web server, using the connection, on a
// separate thread
ContentReaderThread t = new ContentReaderThread(conn);
t.start();
}
// After the data has been retrieved, display it
public void showContents(final String result)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
_rtfOutput.setText(result);
}
});
}
private final class ContentReaderThread extends Thread
{
private Connection _connection;
ContentReaderThread(Connection conn)
{
_connection = conn;
}
public void run()
{
String result = "";
OutputStream os = null;
InputStream is = null;
try
{
// Send HTTP GET to the server
OutputConnection outputConn = (OutputConnection) _connection;
os = outputConn.openOutputStream();
String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n";
os.write(getCommand.getBytes());
os.flush();
// Get InputConnection and read the server's response
InputConnection inputConn = (InputConnection) _connection;
is = inputConn.openInputStream();
byte[] data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
result = new String(data);
// is.close();
}
catch(Exception e)
{
result = "ERROR fetching content: " + e.toString();
}
finally
{
// Close OutputStream
if(os != null)
{
try
{
os.close();

}
catch(IOException e)
{
}
}
// Close InputStream
if(is != null)
{
try
{
is.close();
}
catch(IOException e)
{
}
}
// Close Connection
try
{
_connection.close();
}
catch(IOException ioe)
{
}
}
// Show the response received from the web server, or an error message
showContents(result);
}
}
}


v4.0
Reference:  http://docs.blackberry.com/en/developers/deliverables/21129/BlackBerry_Java_SDK-Development_Guide--1327377-1108115628-001-6.0-US.pdf


 .........

Thursday 30 June 2011

35 Useful Test Cases for Testing User Interfaces


  1. Required Fields
    If the screen requires data entry on a specific field, designers should identify the required fields with a red asterisk and generate a friendly warning if the data is left blank.
  2. Data Type Errors
    If the screen contains dates, numeric, currency or other specific data types, ensure that only valid data can be entered.
  3. Field Widths
    If the screen contains text boxes that allow data entry, ensure that the width of data entered does not exceed the width of the table field (e.g. a title that is limited to 100 characters in the database should not allow more than 100 characters to be entered from the user interface).
  4. Onscreen Instructions
    Any screen that is not self-explanatory to the casual user should contain onscreen instructions that aid the user.
  5. Keep Onscreen Instructions Brief
    While onscreen instructions are great, keep the wording informative, in layman’s terms, but concise.
  6. Progress Bars
    If the screen takes more than 5 seconds to render results, it should contain a progress bar so that the user understands the processing is continuing.
  7. Same Document Opened Multiple Times
    If the application opens the same document multiple times, it should append a unique number to the open document to keep one document from overwriting another. For example, if the application opens a document named Minutes.txt and it opens the same document for the same user again, consider having it append the time to the document or sequentially number it (Minutes2.txt or Minutes_032321.txt).
  8. Cosmetic Inconsistencies
    The screen look, feel, and design should match the other screens in your application. Creating and using a style guide is a great way to ensure consistency throughout your application.
  9. Abbreviation Inconsistencies
    If the screens contain abbreviations (e.g. Nbr for number, Amt for amount, etc), the abbreviations should be consistent for all screens in your application. Again, the style guide is key for ensuring this.
  10. Save Confirmations
    If the screen allows changing of data without saving, it should prompt users to save if they move to another record or screen.
  11. Delete Confirmations
    If a person deletes an item, it is a good idea to confirm the delete. However, if the user interface allows deleting several records in a row, in some cases developers should consider allowing them to ignore the confirmation as it might get frustrating to click the confirmation over and over again.
  12. Type Ahead
    If the user interface uses combo boxes (drop down lists), be sure to include type ahead (if there are hundreds of items in a list, users should be able to skip to the first item that begins with that letter when they type in the first letter).
  13. Grammar and Spelling
    Ensure the test cases look for grammar or spelling errors.
  14. Table Scrolling
    If the application lists information in table format and the data in the table extends past one page, the scrolling should scroll the data but leave the table headers in tact.
  15. Error Logging
    If fatal errors occur as users use your application, ensure that the applications writes those errors to a log file, event viewer, or a database table for later review. Log the routine the error was in, the person logged on, and the date/time of the error.
  16. Error Messages
    Ensure that error messages are informative, grammatically correct, and not condescending.
  17. Shortcuts
    If the application allows short cut keys (like CTRL+S to save), test each shortcut to ensure it works in all different browsers (if the application is web based).
  18. Invalid Choices
    Do not include instructions for choices not available at the time. For example, if a screen cannot be printed due to the state of the data, the screen should not have a Print button.
  19. Invalid Menu Items
    Do not show menu items that are not available for the context users are currently in.
  20. Dialog Box Consistency
    Use a style guide to document what choices are available for dialog boxes. Designers should not have Save/Cancel dialog on one screen and an OK/Cancel on another. This is inconsistent.
  21. Screen Font Type
    Ensure that the screen font family matches from screen to screen. Mismatching fonts within the same sentence and overuse of different fonts can detract from the professionalism of your software user interface.
  22. Screen Font Sizes
    Ensure that the screen font sizes match from screen to screen. A good user interface will have an accompanying style guide that explicitly defines the font type and size for headers, body text, footers, etc.
  23. Colors
    Ensure that screens do not use different color sets as to cause an inconsistent and poorly thought-out user interface design. Your style guide should define header colors, body background colors, footer colors, etc.
  24. Icons
    Ensure that icons are consistent throughout your application by using a common icon set. For example, a BACK link that contains an icon next to it should not have a different icon on one screen versus another. Avoid free clip-art icons, opt for professionally designed icons that complement the overall look and feel of your screen design.
  25. Narrative Text
    Having narrative text (screen instructions) is a great way to communicate how to use a specific screen. Ensure that narrative text appears at the same location on the screen on all screens.
  26. Brevity
    Ensure that narrative text, error messages and other instructions are presented in laymen’s terms but are brief and to-the-point.
  27. Dialog Box Consistency
    Use a style guide to document what choices are available for dialog boxes. You should have not have Save/Cancel dialog on one screen and an OK/Cancel on another, this is inconsistent.
  28. Links
    If your application has links on the screen (e.g. Save as Spreadsheet, Export, Print, Email, etc.), ensure that the links have consistent spacing between them and other links, that the links appear in the same order from screen to screen, and that the color of the links are consistent.
  29. Menus
    If your application has menu items, ensure that menu items that are not applicable for the specific screen are disabled and the order in which each menu item appears is consistent from screen to screen.
  30. Buttons
    If your application has buttons (e.g. Submit, OK, Cancel, etc), ensure that the buttons appear in a consistent order from screen to screen (e.g. Submit then Cancel).
  31. Abbreviation Inconsistencies
    If your screens contain abbreviations (e.g. Nbr for number, Amt for amount, etc), the abbreviations should be consistent for all screens in your application. Again, the style guide is key for ensuring this.
  32. Delete Confirmations
    It is a good practice to ask the user to confirm before deleting an item. Create test cases to ensure that all delete operations require the confirmation. Taking this a step further, it would also be great to allow clients to turn off specific confirmations if they decide to do this.
  33. Save Confirmations
    It is good practice to ask the user to confirm an update if updates are made and they navigate to another item before explicitly saving. Create test cases to ensure that all record movement operations require the confirmation when updates are made. Taking this a step further, it would also be great to allow clients to turn off specific confirmations if they decide to do this.
  34. Grammar and Spelling
    Ensure that you have test cases that look for grammar or spelling errors.
  35. Shortcuts
    If your application allows short cut keys (like CTRL+S to save), ensure that all screens allow using of the consistent shortcuts.

BlackBerry Persistent Store Demo

BlackBerry? Persistent Store:

Class and Demo code:

Class: BerrySyncPersistentStore?.java

package BerrySync?.data;

import net.rim.device.api.system.PersistentObject?;
import net.rim.device.api.system.PersistentStore?;

public class BerrySyncPersistentStore? {

*

Static Utility Functions

*
public static void SaveData?(long _key, Object _data) throws Exception {

Create a persistent data store
PersistentObject? _store;
_store = PersistentStore?.getPersistentObject(_key);



Store Persistent data
synchronized(_store){

_store.setContents(_data);
_store.commit();

}



}




public static Object LoadData?(long _key) throws Exception {

Create a persistent data store
PersistentObject? _store;
_store = PersistentStore?.getPersistentObject(_key);



Retrieve persistent data
Object _data;
synchronized(_store) {

_data = (Object)_store.getContents();



}
return _data;

}


}

Class: Record.java

package BerrySync?.data;

import net.rim.device.api.crypto.AESKey;
import net.rim.device.api.crypto.InitializationVector?;
import net.rim.device.api.util.Persistable;

public class Record implements Persistable{

public String _data;
public String _payload;
public String _collection;
public String _id;
public String _modified;
public int _ttl;
public int _sortIndex;
public AESKey _key;
public InitializationVector? _iv;

}

Demo code: in FetchScreen?.java

Private inner classes

*
final private class SaveOB implements FieldChangeListener? {

public void fieldChanged(Field field, int context) {

try {

Record _data = new Record();
_data._data = "data 1";
_data._id = "id 1";



long _key = 0x4ee5665b495a4912L;
BerrySyncPersistentStore?.SaveData?(_key, _data);



_storeArea.setText("Save Object" + " | " + _data._data + " | " + _data._id);

}
catch(Exception e) {

_networkArea.setText(e.toString());

}

}

}

final private class LoadOB implements FieldChangeListener? {

public void fieldChanged(Field field, int context) {

try {

long _key = 0x4ee5665b495a4912L;
Record _data = (Record)BerrySyncPersistentStore?.LoadData?(_key);
if (_data == null) {

_storeArea.setText("Load Object" + _data);

}else{

_storeArea.setText("Load Object" + " | " + _data._data + " | " + _data._id);

}

}
catch(Exception e) {

_networkArea.setText(e.toString());

}

}

}