Thursday, March 7, 2013

Dynamic Menu Items in XCode 4 Interface Builder

I'm working on an OS X application, and I wanted to make a menu that dynamically changes one of the items when the user presses the ⌥ (alt) option key, like how Finder does in its "Go" menu.
Finder's Go menu showing the ⌥ dynamic menu item.
Searching the web pointed me to this article on developer.apple.com, and then to NSMenuItem where the details are described under -setAlternate:.

Here's how to make a dynamic menu item:

  1. Edit your menu in its .xib file in XCode's Interface Builder.
  2. Make two menu items, one after the other. The first is the normally visible one, and the second is the alternate choice.
  3. For the second menu item, edit the properties. Enable the "Alternate" checkbox, and then click in the "Key Equivalent" field and press the Option key.
Menu Item properties in Interface Builder
That's it. Hook the menu up in your code, setting the target for each item to call their corresponding selectors accordingly.  Read the guide to Menus on the Apple site to learn more.

When you run your application, and the menu appears, you will see the first menu item until you press the modifier key (option, for example).  The menu will swap the first menu item with the second.

Wednesday, April 20, 2011

Android Thread Pool Leak - Process, AsyncTask, or ScheduledThreadPoolExecutor?

I recently tracked down a thread leak in Net Ping.

It was the ScheduledThreadPoolExecutor.

To execute pings, the app uses these thread resources: AsyncTask, Process, and a ScheduledThreadPoolExecutor.

The AsyncTask is used to run the ping on a non-UI thread. Pinging can often take too long to complete on a UI thread, and anything that blocks the UI thread for five seconds will display the ANR (Application Not Responsive) error to the user.

The Process is how the ping is executed. Since Android restricts the network driver's capabilities to prevent normal, non-rooted apps from opening a socket for pinging, we need to use the native OS's ping command, which has the sticky bit set. The OS's ping command runs as the administrator, and is granted unrestricted access to the network device.

The ScheduledThreadPoolExecutor is used to time the responses coming back from the ping execution. Sometimes, ping may block for a very long time, particularly if there are intermittent network errors. The thread executor is used to spawn Runnables that will kill a hung, unresponsive ping process.

In the case of Net Ping, the AsyncTask starts up to five threads, and resuses those threads on subsequent ping operations. No leaks observed with AsyncTask.

The Process doesn't actually start a new thread in the context of the app. When using a Process object, it's important to call destroy() on it to ensure that the external process is terminated, and any related streams are closed.

Finally, we get to where the leak occurred: after the ScheduledThreadPoolExecutor object no longer had any references to it, it would not terminate the threads that were idle and waiting for work that could never possibly come. The fix was to call shutdownNow() followed by awaitTermination() just before the executor object goes out of scope, and we lose the last reference to it.

Net Ping version 1.7 has this fix, and is available in the Android Market. Enjoy!

Thursday, March 3, 2011

Net Ping and installing to the SD Card

Lately, I've been running out of internal memory on my Android phone, and I've gotten hooked on moving everything over to the SD card that I can. Net Ping version 1.5 doesn't allow installation on the SD card, which is the default behavior for apps.

Making the change to the app is very simple, according to the developer documentation:

To allow the system to install your application on the external storage, modify your manifest file to include the android:installLocation attribute in the <manifest> element, with a value of either "preferExternal" or "auto".

(See Install Location for Android Apps.)

This setting is ignored by the earliest versions of Android, which makes it backwards compatible.

I'll be publishing the SD card installable version of Net Ping soon.

To check out the Net Ping app, you can find it on the Android Market.

Sunday, February 20, 2011

Troubles Pinging IPv6 with Android

As of Android 2.3, pinging IPv6 is not going to work. Well, at least not yet. Net Ping works by calling on the underlying 'ping' command in Android to do the heavy lifting.  Any non-rooted ping application on Android will have this problem.

In Android's ping source code (ping.c), there is a strict limitation to using IPv4 addresses. At this point, the address is limited to 4 bytes (IPv4).

ping.c, Line 1805: memcpy(&whereto.sin_addr, hp->h_addr, 4);

I can understand why they neglected to include IPv6. Check out line 2.

ping..c, Line 2: * Copyright (c) 1989 The Regents of the University of California.

This file doesn't seem to have been changed much since 1989.

This doesn't mean that pinging IPv6 is impossible, but it does present a significant challenge. One possibility is that I could contribute a ping.c update to include IPv6 to Android.

So Net Ping today will try IPv6 pinging. And with version 1.5, it will display a special error message when it detects that ping doesn't work with IPv6.  With luck, when the day comes that IPv6 starts working so will Net Ping.

Thanks again for using Net Ping!

Wednesday, February 9, 2011

Net Ping is 5000

Net Ping has reached the 5,000 - 10,000 download category!

Anyway, I'm considering making some improvements to Net Ping, based on user feedback.

1. Don't stop pinging if the network connection is lost (for non-continuous ping).  This is a great observation, and an oversight on my part.  Continuous mode pinging doesn't stop, so why should the non-continuous mode stop on connectivity drops?

2. Add a time stamp to the ping lines.  I can do that.  This is a lower priority improvement as I will add this in when I have some other optional ways to alter the output of the pings ready to publish to everyone.

Thanks for using Net Ping!

Wednesday, February 2, 2011

Net Ping's rapid update to version 1.4

I published an update to Net Ping in a mere 24 hours from the previous update.  I was reluctant to publish an update so soon, but I discovered a bug that I thought warranted a fix ASAP.  
While I was publishing the update, I went ahead and fixed a problem with the Settings screen.  In version 1.3, the small-print text (known as the summary to developers), was blank whenever a user first started up Net Ping.  Altering a setting would bring back that little descriptive line of text.  Well, I found out what I had done wrong in 1.3, and now, all's well in 1.4. 
NEW FEATURE:
  1. Optional continuous mode: Pinging is continues until the app is dismissed, and pinging resumes when you reopen the app. (1.3)
BUG FIXES:


  1. Fixed a Force Close problem when the stopping ping from the menu. (1.3)
  2. Setting descriptions are now correct when you run Net Ping for the first time. In 1.3, they were inadvertently blank. (1.4)
  3. When network connectivity is lost, and you are using the continuous ping, Net Ping will wait at least one second before pinging again. (1.4)  This was the reason for the immediate update.

Sunday, January 30, 2011

Net Ping updated to let you ping continuously

The update is finished, and now Net Ping will let you ping a host continuously.

In the Settings, tick the box, and that will put the app in continuous mode.

Ping is only running while the app is visible on your phone.  If you switch to a different app or go to the home screen, the ping is paused.  The primary reason for this new behavior is because of the activity cycle (see a different blog entry here).  In short, if ping isn't paused, you could lose control of the ping when you come back to the app.

Enjoy the update!