Product Review: Motorola E815

I meant to write about this a long time ago, but fortunately I think this is still relevant. Back in August 2005, after much research and a failed attempt at using T-Mobile, I switched to Verizon and the Motorola E815. My basic requirements were as follows:

* Bluetooth that I could sync up with my Mac (phone numbers and calendar items)
* Good text messaging capabilities
* Good reception in my apartment here in San Francisco
* Decent battery life
* Clamshell form factor

I’m happy to report that the Motorola E815 has accomplished all this and then some.

Reception
After much research I discovered that the reception of the Motorola E815 was seemingly unparalleled. In practice this has proven to be quite true. I almost always have a full set of bars, and I can’t remember the last time I had a problem with reception. I believe this is for two reasons:

* The E815 just gets really good reception
* The CDMA network Verizon is built on is technically superior to other networks.

Bluetooth Sync

Syncing calendar and phone book items with a Mac is a snap using bluetooth. It works exactly as expected.

Bluetooth file transfer

This is a sore point with Verizon. Verizon seems to want to make a few extra bucks off of us by forcing you into using their ‘service’ to get pictures off the phone or use custom ring tones. The way they force you into using their service is by disabling the bluetooth file transfer feature. Lame! Fortunately, some smart people figured out how to hack the phone to re-enable the file transfer feature. It’s pretty risky, so you’re taking your chances if you implement this hack, but I’m glad I did it. Now I’m able to put any mp3 I want on the phone as a ring tone. (Got me some chill Toots & the Maytals as my alarm instead of some annoying ringer)

Also after the hack, I can easily transfer photos off of the phone via bluetooth. Pretty sweet, but it sucks that you have to jump through hoops to make this work.

Use your phone as a modem

Another nifty feature is the ability to use the Motorola E815 as a modem. Today I was taking CalTrain to San Mateo to meet up with my partner Clint , and on the way down I was able to use the E815 as a connection to the internet. The really cool thing was that I was able to connect from my PowerBook to the phone wirelessly over bluetooth. While the train was moving, I was able to surf the web, check my email, IM with Clint, and even ssh into our production server to check on some server logs. I’m not sure what the speed is, but I think it’s a bit slower than DSL, yet certainly fast enough to make the experience acceptable. Don’t forget to turn on DUN (Dial up Networking) to enable this feature. (It’s easy to do) I found some decent instructions on how to do all this here.

Bluetooth headset

I’m going to have to write another whole post on pairing the most excellent Plantronics Voyager 510 Bluetooth Headset with the E815. Suffice to say, I know of at least 3 friends of mine that have gotten this headset after trying mine out. I was very skeptical that a bluetooth headset would perform very well, but this one does the trick, and when paired with the E815, a handsfree experience with no wires is very much a reality.

Is there anything wrong with this phone?

Yes, I’m a big fan of this phone, but I do have a few minor gripes. The form factor of this phone is a little less sturdy than some comparable models…. nothing to shake your confidence too much, but it does lack the really tight hinge feel that some phones have. Another thing that bugged me when I first got the phone was the size. The Motorola E815 is a bit on the big side compared to other clamshell phones. The size thing probably bugged me the most about this phone when I first got it, but after using it a while I’m ok with the size… it actually is easier for me to hold since I have big hands.

In summary, I’m a big fan of the Motorola E815 and wouldn’t hesitate to recommend this phone to anyone. Most importantly, the reception of the phone is fantastic. It’s got great features, and the price isn’t bad now that it’s been out for a while…. Amazon has some pretty good deals on the phone, too, with an excellent rebate.

Replaced my car with ZipCar

I’ve been trying out ZipCar for a few months, and have been happy enough with the service that I went ahead and sold my car. After much careful thought, I came to the conclusion that ZipCar was going to save me time and money, and allow me to drive newer cars on a regular basis. Perhaps most importantly, I wont be tempted to hop in the car for those short optional trips, reducing carbon emissions into the environment.

  • I was paying $65/month for car insurance. Now I pay about the same amount for ZipCar each month.
  • I was paying about $1000/year maintaining my nearly 9 year old car. With ZipCar, that expense goes away, and I get to drive nifty new cars like the fun Mini Cooper and the environmentally friendly Prius.
  • With ZipCar, gas is included in the price of the rental.
  • I used to have to look for parking on the street for my car, but ZipCar vehicles have reserved spaces 5-10 minutes from my apartment

Admittedly, ZipCar probably doesn’t work for everyone, but if you think it might work for you, it’s worth checking out.

New event syntax in OpenLaszlo

If you follow OpenLaszlo news closely, you may have noticed that a new event syntax is available in OpenLaszlo 3.2 which makes specifying and handing your own events more straightforward. I think the folks at Laszlo Systems made a smart move in adopting the new syntax as it is more intuitive, and will reduce confusion for new developers.

Curiously, the only documentation I found describing the new syntax was in this feature proposal, and in the nightly builds of the reference guide and the developers guide. Somehow the new syntax is missing from the shipping 3.2 docs.

In a nutshell the syntax is:

  • <event name="onMyEvent"/> – Declare an event
  • <handler name="onMyEvent">
    //some code here to handle event
    </handler>
  • onMyEvent.sendEvent() – notify event listeners that the event fired

Kudos to the OpenLaszlo folks for continuing to evolve the language.

Let’s spend some money on life instead of death

Let’s pretend you just got elected as president of the USA and it’s budget time. As president, you have to decide how to spend money in the most effective way possible. There are a lot of factors that go into deciding what to spend your money on such as effect on the economy, constituent priorities, etc. In this case, let’s focus on a fundamental aspect of what government should be doing: protecting the people it serves.

Given the following evidence (please don’t click on the links until you read through the whole post):
1) Almost 700,000 people die from this each year
2) Over 500,000 people die from this each year
3) 90,000 people die a year because of this
4) 40,000 people die a year because of this
5) 2752 people died from this in 2001

You’ve got $200 Billion to spend. Where do you spend it? On the stuff that’s causing the most death, right?

This is, of course, a bit of a trick question. The causes of death are as follows: (ok, you can click on the links now)

1) 700,000 – Heart Disease
2) 500,000 – Cancer
3) 90,000 – Death from resistant germs
4) 40,000 – Car accidents
5) 2752 – September 11th terror attacks

I may be a peace-nik from San Francisco, but it just seems wacky to me that we’ll be spending close to $400 Billion dollars in Iraq in the name of fighting terrorism when the reality is that WAY more people are dying from car accidents, Heart Disease, Cancer, etc. For comparrison, The CDC (where money is spent to research/fight health issues like heart disease) had a budget of less than $10 Billion in 2005.

Maybe we need a reality check on our nation’s priorities?

Example of published Gliffy diagram

Clint has been working his butt off on Gliffy while I’ve been doing some consulting work to pay the bills. One of the nifty features in the new version of Gliffy is the publishing feature. Here is a sample (click to enlarge):

If I make a change to this flow chart using the Gliffy diagram editor, the change will instantly be reflected in this blog posting with no additional effort.

Tips for using lazy & resize replication in OpenLaszlo

Here’s the scenario: I want to display 500 items in a scrolling list, but using regular replication causes 500 views to become instantiated, which can take a loooong time. Lazy & resize replication helps out by only instantiating the views that the users can see. Lazy replication then manages copying the relevant data to views that scroll into the clipped area. The dev guide explains the purpose quite well:

“The lazy replication manager creates only enough replicated views necessary to display the data, so there is not a view for each data node. This enables the display of very large datasets.”

This is great because instantiating views is expensive, and we don’t want to make any more of them than we need to. This efficiency gain comes with a price of added complexity however. Here are some tips to hopefully make your experience with lazy & resize replication a little less painful:

  • $path references don’t reliably update in lazily replicated views. Don’t waste your time using them. Use applyData() instead (more on applyData below)
  • Make sure all visual elements that might change in your replicated view are based on the data. Instead of using attributes in the view to keep track of visual information, use attributes in the dataset instead (eg this.datapath.setNodeAttribue(‘someKey’,’someValue’). You’ll probably want to use applyData() as a hook into making visual adjustments as needed.
  • applyData() is called in a replicated view whenever the data in that view changes. With lazily replicated views, applyData() is called on replicated views as the user scrolls so that data can be copied into the new LzView that just scrolled into the clipped area. Make sure that the datapath specified on the replicated view points to data that will definitely be there…. otherwise applyData() wont get fired.
  • As a workaround to the $path problem, grab any data that you need from the dataset when applyData() is fired. (e.g. this.datapath.getNodeAttribute(‘somedata’))
  • Make sure to use the dataselectionmanager if you want the user to be able to select more than a single replicated item at a time.
  • A replication manager only gets created if the datapath matches multiple nodes the first time. If there is any chance at all that you’ll match a single node, you should first set the datapath to point to a fake dataset that contains 2 or more nodes to ensure a replication manager will be created. (See the example code below)
  • You can use the fake dataset trick described above to instantiate some views upon applciation startup. This will ensure that a user doesn’t have to wait for those views to be instantiated when the real data comes in.
  • If you updated something in the dataset, and your change isn’t being reflected in the replicated views, you can try calling this.cloneManager.runXPath() from a replicated view as a last resort.

Here’s some example code that covers most of what I’ve talked about above:

<canvas>

    <!-- Let's say this is my real dataset.  It could be
         loaded from the server, but we'll make it local
         for this example -->
    <dataset name="people">
        <people>
            <person name="chrisk" sex="m"/>
            <person name="lyla" sex="f"/>
            <person name="clint" sex="m"/>
            <person name="renais" sex="f"/>
            <person name="ron" sex="m"/>
            <person name="terry" sex="f"/>
            <person name="debi" sex="f"/>
            <person name="luke" sex="m"/>
            <person name="jason" sex="m"/>
            <person name="eileen" sex="f"/>
            <person name="henry" sex="m"/>
            <person name="nik nik" sex="f"/>
            <person name="kel" sex="m"/>
            <person name="hu?" sex="f"/>
        </people>
    </dataset>

    <button text="Replcte views!">
        <method event="onclick">
            replicatedParent.datapath.setXPath('people:/people');
        </method>
    </button>

    <view width="100" height="100" clip="true">
        <!-- use this dataset to ensure a
             replciation manager is created, and also
             create some views on applciation startup
             so that the user doesn't have to
             wait when they request the data  -->
        <dataset name="fakeData">
            <people>
                <person/> <person/> <person/> <person/> <person/> <person/>
            </people>
        </dataset>

        <view id="replicatedParent"
              datapath="local:parent.fakeData:/pepople">
            <text>
                <datapath xpath="person/@name"
                          replication="lazy"/>

                    <!-- Is called when a user scrolls the data into view -->
                    <method name="applyData" args="_d">
                        super.applyData(_d);

                        if( this.datapath.getNodeAttribute('sex') == 'm' ) {
                            this.setBGColor(0xCACAFF);
                        } else {
                            this.setBGColor(0xFFCACA);
                        }
                    </method>
            </text>
        </view>
        <scrollbar/>
    </view>
    <simplelayout axis="y"/>
</canvas>

My Top Laszlo Performance Tips

A customer recently asked if I had a list of Laszlo coding, performance, & style tips. I didn’t, so I thought I’d start by creating a list of performance tips. Anyway, here’s my list (in no particular order)

  • When using constraints, use $once{} as often as possible – Constraints are a great time saver, but they come at a cost. Normal constraints have to have their events registered when the application starts up, so if you have a lot of constraints, this can slow things down. If you don’t need the constraint to update after application startup, use $once{} for an incremental performance improvement.
  • Use short variable names – I believe this was more of an issue with older versions of the Flash player, so I’m not sure how relevant this is, but it is my understanding that because of the nature of Javascript, long variable names actually have a negative performance impact. If you look at any of the Laszlo run time source code, you’ll see most of the variable names are VERY short, to the point that it makes the code hard to read.
  • Use pooling and lazy replication for replicated views as often as possible – Take advantage of the hard work Adam put into making these features work. Pooling reuses previously replicated views, improving the rendering time when a datapath is updated. Lazy replication only replicates the visible views, hence saving lots of time in the event you have a scrolling list of say hundreds of replicated nodes. You’ll likely need to tweak your code to get these two features to work, but the performance gain you get is totally worth it.
  • Minimize the number of views used – Views are expensive to instantiate, so do what you can to minimize the number of views generated. Focus on classes that are constructed often via replication or other means. For example, in our diagram editor every shape contains ‘connection points’ which are represented by little ‘+’ symbols. Originally, we created the ‘+’ with two views (one horizontal, and one vertical). By using a single asset for the ‘+’ symbol, we cut the number of constructed views down substantially for each shape, yielding faster diagram load times.
  • Load images at run-time – If you don’t need to display an image right away, consider loading the image at run time to reduce the initial application download size.
  • Delay instantiation – Delay instantiation on any views that wont be shown right away to improve start-up performance. For example pop up windows, drop down menus, etc.
  • Use local variables when possible – I think this is another issue that is less important with the newer Flash players, but probably worth looking into. Apparently accessing global variables can be slow, so you’re better off creating a local reference to the global variable if you are going to access it a bunch in a loop.
  • Using Debug.write() can slow things down even when the debugger is off – If you want to be fancy, you could do something like if( $debug) Debug.write(‘some message’); The compiler is smart enough to remove the $debug statements kind of like a pre-processor.

Did I miss anything? Feel free to clue me in, and I’ll add to the list here.

Help us find Jerry Tang

Jerry Tang Missing Pic

Jerry Tang, a good friend and co-worker, has been missing since Tuesday. Jerry last spoke to his wife Tuesday morning as he left his Cole Valley home to go for a walk. He may have been seen near Fell/Stanyan at the entrance to Golden Gate Park on Wednesday morning. Jerry is 6’1″, about 160 pounds, and is believed to be wearing a dark blue jacket and blue jeans, and may possibly have a light blue umbrella.

For more information, please visit this link