Tuesday, November 8, 2011

Set a breakpoint in dependent library in XCode 4.2

In order to set a breakpoint in a dependent library and break at the main project, you will need first set the breakpoint in the library and then change the scope of the breakpoint to user.
Launch the main project will hit the breakpoint you just set in the library project.

Iphone simulator folder in Lion with Xcode 4.2

By default, the library folder under user is hidden in Lion with Xcode 4.2, so you will not be able to access the iPhone simulator folder shown below.

/Users/(your user name)/Library/Application Support/iPhone Simulator

To show the library folder, run the following command from terminal window:

chflags nohidden ~/Library/

Note the library folder must be the one under your name, not the one under root.

Saturday, November 5, 2011

Fresh installation of Lion on Mac without CD or USB stick

Lion has to be upgraded on Mac, however, you may want to have a fresh install of Lion to get rid of the old application or settings from the Snow Leopard. The following steps can be used to make a refresh Lion installation.
1. Upgrade Snow Leopard to Lion as Apple suggested from app store (paying for $29)
2. Reboot Mac while holding option key
3. Select the restore disk for starting
4. Select Disk Utility and erase the main hard disk drive. This may erase the old Snow Leopard.
5. Restore Lion, it will start a refresh Lion installation.

Cheers
Jonathan

Sunday, October 30, 2011

Property and Synthesize in ObjectC and Xcode

Property in ObjectC and xCode is quite different from what java or C# or C++ uses property. The following highlights the difference
1. What "@property float myValue;" does
When defining property myValue in header file, it says, there will be a myValue and setMyValue method available in implementation file. In addition, those two methods can be invoked using myObject.myValue to get and set.

Notice when property is defined, there is no data member involved, the value is totally controlled by myValue and setMyValue method

Update to now, everything is quite clear, and nothing is that different from C# or java.

2. What "@synthesize myValue;" does
@synthesize is totally new to java or c#. It does more harm then help to objectC. As program is not about simplifying of coding, it is about logic consistence. It is better to let developer explicitly specifies the expected behavior than magically doing so underneath.

So what @synthesize does as shown below?
head file:
@property float myValue;"

implementation file:
"@synthesize myValue;"

The above code silently create the imaged implementation of myValue and setMyValue for the myValue property. And it also silently create the data member to hold the myValue's data, so that the code can first set the value and then get the value back without defining a data member to store the value. Developers actually do not know where data is stored, they just know it is stored in somewhere.

Now let add a data member myValue in the header file, and see what magic will happen. As long as the data member's type and name match the property's type and name, then @synthesize will automatically associate the imaged implementation to the data member, so the data are actually stored in the new data member.

Up to now, things still look fine although not appreciated. It really starts to mess up when adding property method implementation as shown in the following code:
Header file
@interface Property : NSObject {
float myInsideValue;
}
@property float myValue;
-(float) myMethod:(float)m;
@end

Implementation file:
@implementation Property
@synthesize myValue;

- (float) myValue
{
return myInsideValue;
}

- (void) setMyValue:(float) v
{
myInsideValue =v;
}

-(float) myMethod:(float)m
{
myValue = m;
return myValue;
}
@end

The major problem is @synthesize silently adds a imagined data member when myValue is accessed inside the interface implementation file, so inside myMethod accessing myValue does not go through the property methods. While, when myValue is accessed outside the interface implementation file, myValue is accessed through property method. As the result, inside the implementation file, myValue's value is different from myInsideValue's value.

In order to avoid this kind of confusion, a simple rule is do not use property method and synthesize together, and it is preferred to use property method to be consistent with java or c#. If subclass for property is involved, it is much better to deal with property method than the "smart" syntheisze syntex.


3. Inside the class only use data member

4. property and subclass

Sunday, October 2, 2011

Upgrade the version of Blackberry persistent store class

When upgrading the version of Blackberry persistent store, like adding or removing a instance member in the persistent class, the saved persistent data will be automatically deleted by system.
To handle the version upgrading while storing the data in a single version instead of multiple versions of persistent classes, the application needs to keep the code of all older versions of persistent store in order to load the older data, and also upgrade the old version of data to latest version.

The logic are as follows:
VersionKeyArray =
{
OlderVersionKey1;
OlderVersionKey2;
LatestVersionKey3;
}

CurrentVersionKey = VersionJeyArray.LatestVersionKey3;
while (currentVersionKey != NULL)
{
get stored persistent object;
if (persistent object != NULL )
{
if ( is not the latest version )
{
read the older version of persistent data
Convert to the new version, this may involves crossing multiple versions
persist the new version of data
delete the older version of data
break;
}
}
go to the next older version key
}

//when the code gets here, we know we have the latest version of data
process the load persistent data if it is not null

Tuesday, September 13, 2011

Variable length arguments for javascript method

When creating javascrip method, if the parameters passed by caller may be different by any reason, an easy solution is just defining the parameters to empty, then inside the javascript method, accessing the actual parameter from the implicit argument variable.
The arguments variable inside the called function is an array containing the values of all the arguments passed to the function by caller, as shown in the following example:
function test()
{
alert(arguments[1]);
}

test("0","1","2");

John

Missing closing script tag in html causes javascript runtime error: Object expected

An runtime error: Object expected was returned when testing a simple function in html page's onLoad method. It turns out the error is due to missing closing script tag included
[head]
[script src="testcase.js" /]
[script type="text/javascript"
function callme() {alert("hi");}
[/script]
[/head]
[body onload="callme()"]

After adding the closing tag as shown below, the javascript method callme works properly.

[head]
[script src="testcase.js"] [/script]
[script type="text/javascript"
function callme() {alert("hi");}
[/script]
[/head]
[body onload="callme()"]

John

Wednesday, June 15, 2011

Property Attribute for iphone App

The following are some attribute used for property definition:

[assign]
This attribute indicates the property uses assignment in the property’s setter. No release to be called to the old value, and no retain to be called on the new value.

[retain]
This attribute indicates the property calls release to the old value, and retain on the new value.

[copy]
This attribute indicates the property calls release to the old value, and then allocate and copy a new object to the new value. The copy operation will retain on the newly created object.

[nonatomic]
This attribute indicate that the property’s accessor methods are not thread safe.. So do not access this property from multi-threads

When the variable or data member needs to be released for iPhone

Basically, all variable and data members that is derived from NSObject needs to be explicitly release in iphone applications. When the variable or data member goes out of scope, the application or OS will not release it automatically, as all variable or data members are allocated in heap instead of stack. There is no concept of stack in objective C, so none of the variable or data member can be cleaned up automatically.

For local variable of NSObject in a method, releasing the variable before exiting the method.

For property, as the setter will release its current property value and retain the new value, so need to release the property value when the object instance is deallocated.

For instance variable, same as property, release the value when the object instance is deallocated

Certainly, if the variable or variable is changed in the middle, the old value needs to be released and the new value needs to be retained.

There are some exceptions due to compiler optimization, particularly for NSString objects, which may cause confusion to developers. For example, NSString object created with
[[NSString alloc] initWithString@"abc"] or [NSString StringWithString] has a retain count of 2147483647 instead of 1. The reason is the returned NSString just points to immutable constant NSString object passed in, which does not need to be released. However, NSString object created with [[NSString alloc] initWithUTF8String:"abc"] will need developer to release it. The IOS reference document does not mention anything about this kind of difference, and the only clue available is checking retainCount of the returned object.
In addition, based the memory management rules from Apple, release method should be called for [[NSString alloc] initWithString@"abc"], althoug we know actually it does nothing.

- You take ownership of an object if you create it using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.

- You use release or autorelease to relinquish ownership of an object. autorelease just means “send a release message in the future” (specifically: when the used autorelease pool receives a drain message—to understand when this will be, see “Autorelease Pools”).

Sunday, May 29, 2011

Static variable in C/C++

Thanks to the iPhone development platform, the C++ once again gets the notice of mobile developers. This post talks few issues about static keyword in c/c++.

1. Using static for variable in file scope
If the same named variable is defined in multiple files, compiler will report an error due to the duplicated definition. Adding static for the variable definition will make the variable's scope to the current file, so that they will not conflict with each other. Note, the static variable defined in each file has its own instance. Changing the static variable's value in one file will not affect another file's variable value.
If you want to share the same instance, using extern keywork.

2. Using static for variable in class scope
This is quite easy to understanding, since it is similar to .net or java. The variable belongs to the class instead of a particular class instance.

3. Using static for variable in method scope
The variable will be initialized once, and each time when the mothod gets called, the same instance will be used. It is more useful in c, as in c++, we can just define a class member to do the same thing.

In all cases, if adding const in the definition, then the variable can not be updated once it is initialized.

Jonathan

Saturday, April 16, 2011

Create view without InterfaceBuilder for iPhone

Although InterfaceBuilder is an important tool for iPhone development, the tool is not as intuitive to use as Visual Studio UI designer.
To help understand what interfacebuilder does, we can create the interface without using InterfaceBuilder, and then comparing the corresponding steps done by InterfaceBuilder.

Steps to add a ViewController without using InterfaceBuild:
1. Create a Window based iPhone application
2. Add a new UIViewController subclass in the project. Do not select "With XIB for user interface" checkbox
3. In the UIViewContollerSubclass' viewDidLoad method, create some UI elements and then add them into UIViewController.view collection by [self.view addSubview:uiElement] method.
4. In WindowAppDelegate.m didFinishLaunchingWithOptions method, create a instance of this new UIViewControllerSubClass instance, add it into appliation's main window with [window addSubview:uiViewControllerInstance.view].

Comparing with InterfaceBuilder to do the same thing, the following steps are required
1. If a UI sub class is created in the app for a ui element, like UIViewControllerSubClass, then the identity class of the UI element added in InterfaceBuilder needs to set the corresponding sub class with Identity Inspector.
2. For UIViewController object, use Attribute Inspector to set the NIB name to load the xib file, this associates the xib file with the UI control added in InterfaceBuilder.
3. Any IBOutlet property , or IBAction defined in .h file need to be associated with the corresponding ui element added in InterfaceBuilder.
4. File owner is the class that will load the xib file at runtime, for MainWindow.xib, it must be UIApplication classor its subclass. For UIViewController.xib, it must be a subclass of UIViewController class.

Jonathan

Wednesday, April 6, 2011

How to hide and show soft keyboard on iPhone simulator

When testing with iPhone simulator, occasionaly, you will need to show or hide the soft keyboard. To do so, go to IOS simulator's Hardware menu, and select "Simulator Hardware Keyboard" submenu, it will toggle the soft keyboard's state.


Jonathan

Sunday, April 3, 2011

Protocol in Objective C

Protocol in Objective C is quite similar to interface in java or .net, so there is not much to say about it.

To define a protocol in a class header as
@protocol MyProtocol
-(void) myfunction;
@end

The header file of the class that implements a protocol looks like the following, notice the syntax is quite similar to category but uses angle bracket instead of parenthesis.

@interface MyUserClass : NSObject .

Jonathan

Category in Objective C

Category in Objective C is a new concept to C++ developer. The catetory must associate with any existing class, even if the class implementation is not accessible to you. Note that a cateory can not declare additional instance variables for the class. It can only include instance methods.
While category is similar to subclass, the difference is with category, the new methods directly added into the original class without creating a new derived class.

The syntax is

Header file (name convention is "classname+categoryname.h"):
#interface "ClassName.h"

@interface ClassName (CategoryName )
- (int) categoryFunction;
@end


Implementation file (name convention is "classname+categoryname.m"):
#import "classnmae+categoryname.m"

@implementation ClassName (CategoryName )
- (int) categoryFunction {
return 0;
}
@end

Note another Objective C feature: Extension is like cateory but without an name, the extension methods must be implemented in the main @implementation block of the corresponding class. The extension example is shown below:
Header file ( "classname.h")
@interface ClassName ()
- (int) extensionFunction;
@end

implementation file ("classname.m")
@implementation classname

... class methods implementation

- (int) extensionFunction {
return 1;
}

@end

Jonathan

Sunday, March 27, 2011

Object inheritance with Javascript

Prototype can be used to define data member and function member to a object. It also is used to realize inheritance for javascript. In order to inherit an object from another object, we set the new the new function's prototype to the existing function as show below:
function base()
{ this.inbase = 2;}

base.prototype.inbaseProto = 3;
base.prototype.getint = function()
{
return 3;
}

derived.prototype = new base;
function derived()
{ this.inderived = 4;}

derived.prototype.inderivedProto = 5;

x = new derived;
s = x.getint();

alert(base.inbase + ', ' + x.inbaseProto + ', ' + x.inderived + ', ' + x.inderivedProto + ', ' + s );
The result is "2, 3, 4, 5, 3";

Jonathan

Use prototype to make javascript object oriented

Unlike other object oriented language, javascript does not support the common way of defining data member or function member. However, this can be supported in javascript by using prototype.
For javascript, when a function is defined, it automatcally gets a data member of prototype, which also has a constructor method by default- i.e the function itself. The constructor is used to create the instance of the object. If any data members or function members are defined on this prototype object, then all instances created by the function will automatically have those data members and function members defined, similar to other object oriented lanaguages, the code is shown below,
function f(){
}
f.prototype.datamember=3.14159;

// create the object method
function f2(o){
alert(o);
}
f.prototype.funcmember=f2;

Note for prebuild types, only object, image, string, data and array can have their prototype changed to add new data members and function members, which means you can extend new function into those prebuild types. With the following code, then all instance of object will have the newprop as 123.
Object.prototype.newprop = "123";

Note if a same named property is defined in both object instance itself and object propotype, then the object instance property will take priority.
Jonathan

Function object and this in javascript

Unlike other languages, function in javascript is an object same as other instance object. For example, if the following function is defined
function f(m,n) {
this.x = m;
this.y = n;
}

Then calling
var o1 = f;
Then the type of o is an object that represents the function. It is not a instance that is created by the f function.

Now let us see what happens if calling
var o2 = new f;
This time, the function serves as the construct to create a instance . The instance has two data member x, and y, whose values are not initialized. To set the data member values, calling
var o3 = new f(1, 2);

Now try to use the function in a different way as showing below
var o3 = f(2, 3);
This time, the function f is not used as a constructor, instead it is just a normal javascript method call, inside the function f, this pointer points to the window object of the current html page, and it just sets two new data members to the window object.

Another thing unique in javascript is, although any object instance can add new data members by just calling assigning operation as below
this.x = somevalue;

It can not do so to directly call a javascript funtion on an instance object. Instead, it must first assign the function to the instance's member before calling the function on it.
this.f = somefunction;
this.f();

By the way, the this point in javascript function call chain is not inherited. So if within a function A, the this points to instance Obj1, then calling function b from function A, within the function b, the this pointer is the global object, instead of Obj1. If you want to set the this pointer Obj1 to be function b's this pointer, then you must first assign function b as a member of Obj1, and then calling function as its member function. This also explains why we need to assign onclick attribute to a external function and then call onclick to keep the current html element as the external function's this object.

Friday, March 25, 2011

Relative or absolute path in URL

When a javascript method or html link refers to an element in the url, if the relative path is used, the path base is the current displaying html page. As a result, the target location will be different depending on the current displaying page's location. If the javascript method or html page refers to an element using absolute path format, then it is always based on the root folder of the virtual directory, and the target location is irrelevant to the current displaying page's location.

The format of absolute path starts with a single forward slash, avoiding using a back slash since some clients may not support it.

The format of relative path starts without any slash. If the relative path starts with '../', it will go to the parent folder of the current displaying page. However, if it already reaches the root folder of the virtual directory, then the root folder will be used to locate the target item.

Jonathan

Saturday, March 19, 2011

Show Dialog with onBackPressed and onPause method

onPause method in Android activity is for saving the UI state data, when onPause is called, the OS already puts the current activity in background and starts to render the target activity. So no any UI related operation (for example, showing a dialog box, etc.) should be put into onPause method.

If there is a need to do UI related operation, like prompting user to save the pending change or cancel the current operation, then those UI related operation should be put into menu handler or onBackPressed method.

Sunday, March 6, 2011

Showing Dialog in Android Application

First, different from other platforms, showing dialog in Android will not block the current execution. So that the code behind Dialog.show() will be executed immediately without waiting the dialog gets closed. As a result, anything that needs to be called after closing the dialog should be put into dialog's button handling method.

Second, there is not a single method that can be called to show a dialog. The simplest code to show a dialog box is as follows

Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("my title");
alertDialog.setMessage("my message.");
alertDialog.show();

Third, if you do not want user to cancel the dialog by selecting the back key, then call the following method before alertDialog.show();
alertDialog.setCancelable(false);

Finally, if you want user to select a yes/no option by clicking a button in the dialog box, two other methods should be called to set these button's text and callback methods. A full functioning dialog is showing below:

AlertDialog.Builder ad = new AlertDialog.Builder(myActivity.this);
ad.setTitle("my title");
ad.setMessage("my message");
ad.setPositiveButton("Yes", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int arg1) {
// do yes operation
}
});

ad.setNegativeButton("No", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int arg1) {
// do no operation
}
});

ad.setCancelable(true);
ad.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// do cancel operation
}
});

ad.show();


Note if you show two dialogs (that is, calling Dialog.show()) within a single method, then the second dialog will show on the top of the first one. Only after the second dialog gets dismissed, then the first one will become the active dialog.

Jonathan

ListView, ListAdapter, ListActivity in Android

ListView is derived from View class, so it can be used by Activity in the similar way as EditText or Button View. ListView is also derived from ViewGroup, so it has the ability to contain a list of view for the list item.
In order to show the list view, the only method that needs to be called is
setAdapter( ListAdapter adapter). The ListAdatper parameter provides the views for showing each list item.

ListAdapter class mentoned in setAdapter method is responsible to render list item. Its first responsibility is holding the data of list item, which is passed as paramter to its constructor. The second responsibility is returning a view for each item when asked by ListView classm, the layout resource of the item view is passed to it as another paramter in its constructor.

Now let us take a look at ListActivity, basically, it is a activity that has a listView in it. In order to show a list items, the only method needs to be called is setListAdapter(adapter) in the overrided onCreate method. The following is the simple code to show a string array in listActivity, it does not even require to define any layout resources.

public class MyListActivity extends ListActivity {
@Override
public void onCreate(Bundle data) {
super.onCreate(data);
ArrayList myString = new ArrayList();
myString.add("string1");
myString.add("string2");
myString.add("string3");
myString.add("string4");
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, myString);
setListAdapter(adapter);
}
}

Jonathan

Fix Link Error When Viewing Android Offline Document

After installing Android offline document for Android SDK API 11 and opening index.html from Windows File explorer, clicking any link (like Reference or SDK) on the index page will cause an error. The reason is the link automatically adds the root driver again in the new address, so the target address becomes an invalid one as showing below.
C:\C:\Program Files (x86)\Android\android-sdk-windows\docs\reference\android\text\util\package-summary.html

A quick fix is creating a virtual directory in IIS and point it to the android document folder, and then open index.html from the virtual directory as below, then everything works as supposed.
http://localhost/androiddoc/index.html

Jonathan

Tuesday, March 1, 2011

Use FLAG_ACTIVITY_NEW_TASK flag when starting activity

When calling startActivity, the new activity will live in the same screen stack (context) as the caller. Sometime, the caller may not have an activity context, for instance, starting an activity from Broadcastreceive.onReceive() method, or starting an activity from a service. In these cases, call startActivity will cause an exception of "Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK", since the new activity does not have a context to live in.

To fix the issue, setting FLAG_ACTIVITY_NEW_TASK to the intent as follows, then a new context will be created for the new activity.

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);


Jonathan

Sunday, February 27, 2011

Difference between pressing HOME and Back key for Android activity

After you start an activity, if HOME key is pressed, then the current activity is stopped and its task goes into the background. The system retains the state of the activity - i.e. onSaveInstanceState will be called. If the user later resumes the task by selecting the launcher icon that began the task again, the task comes to the foreground and resumes the activity at the top of the stack.

However, if BACK key is pressed, the current activity is popped from the stack and destroyed. The assmuption is the activity is done and will not be used again. So the system does not retain the activity's state - i.e. onSaveInstanceState will not be called.

Jonathan

Automatically format the java source file for Android Eclipse

Eclipse java project, Ctrl + Shift + F can be used to automatically format the source file.
You can also first select the lines in source file and then use Ctrl+I to only format the selected lines.
Another option is automatically formatting the source file when saving the file. To configure this, go to Windows->Preference->Java->Editor->Save Action, and enable the option of "Format All Lines".
This will save a lot of time to manually format the code and also make it more readable.

Other useful short cut keys:
Ctrl+Shift+E: showing the list of all opened editor,
Ctrl+Shift+F6: navigateing to previous editor
Ctrl+F6: navigating to next editor
Ctrl+/: comment and uncomment all selected lines.
Jonathan

Wednesday, February 23, 2011

Andoid Activity Life Cycle - onSaveInstanceState and onRestoreInstanceState

onSaveInstanceState and onRestoreInstanceState are two methods involved in Android Activity life cycle. There are several factors deciding when they will be called.

First, the data bundle mananged by these two methods are only valid within a single application running session. So if the application exits and restarts, then OnRestoreInstance will not be called, since no data are available. For the same reason, null is passed as parameter for onCreate method when onCreated is called in the first time.
MyActivity onCreate (null)
MyActivity onStart
MyActivity onResume

Second, onSaveInstanceState is always called before onPause method when starting to deactivate or close the Activity.
MyActivity onSaveInstanceState
MyActivity onPause

Third, in the same application session, onRestoreInstance will only be called if onDestroy has been called before it. Or in other word, onCreate is called before it.
MyActivity onSaveInstanceState
MyActivity onPause
MyActivity onStop
MyActivity onDestroy
MyActivity onCreate (obj)
MyActivity onStart
MyActivity onRestoreInstanceState
MyActivity onResume

A sample of full cycle looks as below:

MyActivity onCreate
MyActivity onStart
MyActivity onResume
MyActivity onSaveInstanceState
MyActivity onPause
MyActivity onStop
MyActivity onDestroy

MyActivity onCreate
MyActivity onStart
MyActivity onRestoreInstanceState
MyActivity onResume
MyActivity onSaveInstanceState
MyActivity onPause
MyActivity onStop
MyActivity onDestroy

Usually, onRestoreInstanceState will not be called since most of time the activity is still alive after it is stopped, as shown below:

MyActivity onCreate
MyActivity onStart
MyActivity onRestoreInstanceState
MyActivity onResume
MyActivity onSaveInstanceState
MyActivity onPause
MyActivity onStop
MyActivity onRestart
MyActivity onStart
MyActivity onResume


There are two ways to force the activity to be destroyed immediately.

The first way is changing the orientation of the simulator, it will force all activities to be destroyed and then created again. Another way is enabling Immediately destroy activities from dev tool's development settings page.

Jonathan

Tuesday, February 22, 2011

How to change the orientation on Android simulator

During the testing of event handler of onConfigurationChanged, you will need to change the simulator's orientation.

Actually, it is quite simple to do so, first setting the current active window to Android simlator, and then press the key of Ctrl+F11 on your desktop computer (not the android simulator's key pad).

Jonathan

Monday, February 21, 2011

Install Windows Phone 7 Developing Tool on Windows Server 2008

By default, only Vista and Windows 7 are supported for the Windows Phone 7 development tools. In order to install it on Windows Server 2008, the following steps are required:
1. download Windows Phone Developer tool from
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce&displaylang=en

2. extrace the downloaded file by running a console command: vm_web.exe /x

3. Edit extracted file baseline.dat, by looking for section named [gencomp7788]
Changing the value InstallOnLHS from 1 to 0
Changing the value InstallOnWin7Server from 1 to 0

4. Save the udpated baseline.dat

5. Run setup.exe /web

6. Download and install Windows phone developer Tool Janunary 2011 Update from
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=49b9d0c5-6597-4313-912a-f0cca9c7d277&displaylang=en


Jonathan

Subclass Application class for Android project

In order to handle several system events, like low memory, configuration change, you will need to subclass from Android Application class. Note that only creating a derived Application class and adding it into the project are not enough. You also need to update the project's manifest file to specify the derived class full name in Application node's name attribute, as shown below:

MyApplication sub class:
public class MyApplication extends Application {
public static final String MyAppTag = "MyAppTag";

@Override
public final void onCreate() {
Log.v(MyAppTag, "MyAppliation onCreate");
super.onCreate();
}
}

Updated AndroidManifest.xml:

android:label="@string/app_name"
android:name="MyApplication"
android:description="@string/app_desc"


Jonathan

Sunday, February 20, 2011

Write and view debug output from Eclipse for Android

Sooner or later, you will need the debug output to help you in Android development. The old System.out.println still works, but you need to view the output from Android LogCat instead of Eclipse Console window. To open and view the output of LogCat, open Eclipse menu of Window->Show View->Others->Android->LogCat.
However, although the debug output is available in LogCat, there are quite a lot of other debug output, which really makes it difficult to find the log you are interested. To handle the issue, Log class should be used to write the debug output, since Log class provides a way to specify a log tag for each log entry, and you can filter the entries in LogCat by log tag.

public class myActivity extends Activity {
public static final String MyActivityTag = "MyActivityTag";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.v(MyActivityTag, "MyActivity onCreate");

super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Note you can add multiple log filter by clicking the '+' icon in Log Cat view. For each log filter, a separate log output tab page will be created for showing the log entries belonging to this log tag.

Jonathan

Saturday, February 19, 2011

Reference Android Resource

There are two way to refer a Android resource - from code and from xml resource file.

To refer resource in code, the format is R.Calss.ResourceName. The following are some usage sample.
setcontentview(R.layout.main)

Resources myResources = getResources();
CharSequence styledText = myResources.getText(R.string.stop_message);

To refer resource as attribute in xml, the format is
"@[packagename:]Class/ResourceName" as showing in the following example:



android:text="@string/stop_message" android:textColor="@color/opaque_blue" />


Usually, you do not need to include the package name, unless you need to refer a system defined resource. The following sample referrs to system color darker_gray
android:textColor="@android:color/darker_gray" />

In rare occasion, you may also see a ? in the format as following sample
android:textColor="?android:textColor"

? means using the current textColor defined for the view, so the actual color can only be decided at runtime.

Jonathan

Android Resource ID Format

When defining resource for Android, the format of resource id attribute looks like android:id="@+id/item01"

The '@' at the beginning of the string is just a delimiter, and indicates that the following string is an ID resource.

The '+' means that this is a new resource id that must be created and added to the resource R file. However if the same resource ID are defined more than once, only one ID is included in R file.

The 'id/item01' is the class and data member name included in the generated R class. The resource can be referred as R.id.item01. The class name is required, so just define 'item01' is invalid. If the resource id is defined as android:id="@+idd/ddd/item01", then the generated R file only includes R.idd.ddd as the reource id.

Do not mix resource id with resource name. Resource name is used to identify a resource. Some resource includes a list of items, like menu items in a menu resource, so resource id can be used to identify a particular item in the list.

Jonathan

Friday, January 28, 2011

DependencyProperty in SilverLight/WPF

Unlike usual .Net property, DependencyProperty is defined as static member for a class. The dependencyProperty is not used to store the data as instance members, instead it is used to indicate that the class understands the defined depenency property, so knows how to use this DependencyProperty.

Usually, the class also defines the get/set wrap accessors for the DependencyProperty, they are instance members, since they use the DependencyProperty as key to read and set the data from the hashtable that stores all dependency values.

Note once a DependencyProperty is defined in a class, the value for this property can be set/get to any classes that derived from DependencyObject, not only the class defines it. For example Grid.ColumnProperty in Grid class can be set to a TextField instance. However, only Grid class knows how to apply this property when laying out the TextField. The TextField just stores the value into its DependencyProperty hash table, and never knows what this property really means. In this sense, the DependencyProperty is also called as AttachedProperty.

Jonathan

Sunday, January 2, 2011

adb.exe in Android SDK not installed on Windows Server 2008 (64 bit)

When installing Android SDK to Windows Server 2008 (64 bit), adb.exe does not get installed in platform-tools folder, it seems Windows server 2008 is not a supported platform, although it is unlikely there is any difference between Win Server 2008 (64 bit) and Windows 7 (64 bit) in term of eclipse for android support.

A workaround is copying the whole platform-tools folder from Windows 7 to Windows server 2008. And then set the Android sdk location again from Eclipse Windows->Preference menu, and all function works just fine.

Jonathan