Chasing an mobile web vision

闯荡在移动互联网的世界中

2007年7月21日 #

移动互联网时代--Android上的一个例子

我们来演示一个获取联系人,并用网页展现出来的简单例子。

 首先,我们在eclipse环境中创建一个Android project,我们的Activity名称是com.example.RIAExample,并且修改界面的layout文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation
="vertical"
    android:layout_width
="fill_parent"
    android:layout_height
="fill_parent"
    
>
<WebView android:id="@+id/web"
 android:layout_width
="fill_parent" android:layout_height="fill_parent">
</WebView>
</LinearLayout>

可以看到,界面中仅仅包含一个WebView控件。

 接下来,创建一个简单的java类来描述一个联系人的信息,它包含联系人姓名和号码。

 

package com.example;

import java.util.Vector;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;

public class RIAExample extends Activity {
    
    
private WebView web;
    
    
//模拟号码簿
    private Vector<Person> phonebook = new Vector<Person>();
    
/** Called when the activity is first created. */
    @Override
    
public void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
this.initContacts();
        web 
= (WebView)this.findViewById(R.id.web);
        web.getSettings().setJavaScriptEnabled(
true);//开启javascript设置,否则WebView不执行js脚本
        web.addJavascriptInterface(this"phonebook");//把RIAExample的一个实例添加到js的全局对象window中,
                                                        
//这样就可以使用window.phonebook来调用它的方法
        web.loadUrl("file:///android_asset/phonebook.html");//加载网页
     
    }

    
    
/**
     * 该方法将在js脚本中,通过window.phonebook.getContacts()进行调用
     * 返回的JavaArrayJSWrapper对象可以使得在js中访问Java数组
     * 
@return
     
*/

    
public JavaArrayJSWrapper getContacts(){
        System.out.println(
"fetching contacts data");
        Person[] a 
= new Person[this.phonebook.size()];
        a 
= this.phonebook.toArray(a);
        
return new JavaArrayJSWrapper(a);
    
    }

    
    
/**
     * 初始化电话号码簿
     
*/

    
public void initContacts(){
        Person p 
= new Person();
        p.name 
= "Perter";
        p.phone_number 
= "8888888";
        phonebook.add(p);
        p 
= new Person();
        p.name 
= "Jack";
        p.phone_number 
= "777777";
        phonebook.add(p);
       
    }

    
    
/**
     * 通过window.phonebook.debugout来输出js调试信息。
     * 
@param info
     
*/

    
public void debugout(String info){
        
        System.out.println(info);
    }

}

下面是html文件,它非常简单。
<html>
    
<head>
        
<script type="text/javascript" src="fetchcontacts.js"/>
</head>
<body>
    
<div id = "contacts">
        
<p> this is a demo </p>
    
</div>
</body>
</html>

而主角就是我们的javascript脚本fetchcontacts.js
window.onload= function(){
    window.phonebook.debugout(
"inside js onload");//调用RIAExample.debugout
    var persons = window.phonebook.getContacts();//调用RIAExample.getContacts()
    if(persons){//persons实际上是JavaArrayJSWrapper对象
        window.phonebook.debugout(persons.length() + " of contact entries are fetched");
        
var contactsE = document.getElementById("contacts");
        
var i = 0
        
while(i < persons.length()){//persons.length()调用JavaArrayJSWrapper.length()方法
            
            pnode 
= document.createElement("p");
            tnode 
= document.createTextNode("name : " + persons.get(i).getName() + " number : " + persons.get(i).getNumber());//persons.get(i)获得Person对象,然后在js里面直接调用getName()和getNumber()获取姓名和号码
            pnode.appendChild(tnode);
            contactsE.appendChild(pnode);
            i 
++;
        }

    }
else{
        window.phonebook.debugout(
"persons is undefined");
    }

    
}


 例子很简单,我加了注释希望有助大家理解,其他我就不深入解释了。
我把例子的源代码放上来,你可以下来试一试。

RIADemo

这个例子说明通过WebView.addJavascriptInterface方法,我们可以扩展JavaScript的API,获取Android的数据。这样,JS的粉丝就可以使用Dojo,JQuery,Prototy等这些知名的js框架来搭建android应用程序来展现它们很酷很玄的效果!但是,目前addJavascriptInterface还不够灵活强大,为什么呢?敬请关注第四篇“what next?”


posted @ 2009-03-14 16:16 勤劳的蜜蜂 阅读(5464) | 评论 (6)编辑 收藏

移动互联网时代--忽如一夜春风来,web花开各终端

自从Apple在safari上使用webkit并移植到iphone后,webkit就仿佛是获得了选秀第一名似的,吸引了众多眼球。
其实,我最早听说webkit是在iphone出来前一两年,当时有报道说Nokia正在采用webkit为它下一代的Symbian平台做一个引擎,而且还有专门的社区,但比较封闭,很难进入那个圈子,让人一点感觉没有。不过,至少说明Nokia很早就盯上这一块了。
iphone发布后,Apple似乎就接管webkit了,从此,webkit社区就有了巨大变化。Apple把能开放的东西都放到了webkit社区里面,速度还相当的快(用Apple自己的话说,他们贡献了81%的力量,看看webkit社区的主力开发人员,有多少来自Apple!)现在,我们时不时的可以看到webkit的更新,比如对html5的跟进,css的特效等新功能!其中不得不重点提出的是2008年6月2日,webkit社区发布了高性能javascript引擎SquirrelFish!9月3日google chrome发布,采用了V8 javascript引擎,号称比SquirrelFish还快,两个礼拜后webkit就发布了SquirrelFish Extreme给予正面还击。巨头们牟足了劲争先把javascript引擎油门踩到底!我不想猜测他们卖力的真正原因,但是,我觉得随着移动终端能力加强,javascript大面积攻进终端已经指日可待了,iphone和android已经实现了。
这期间,由于Apple的快速组合拳,Nokia经营的webkit专区很快就倒闭了。但他并没有放弃对webkit的投入,2008年1月28日Nokia宣布收购了Trolltech公司。现在Trolltech lab作为Nokia的代表仍然活跃在webkit社区之中。就前两天,他们还在http://planet.webkit.org/发布了一篇标题极其引人的博文“Creating a Google chat client in 15 minutes”,为QWebView做了一把广告,相信qt的粉丝肯定不会错过。而本月初发布的qt4.5中,明确指出qt加强了对webkit诸如SquirrelFish等新功能的整合。那么就让我们期待一下Nokia的新款机器吧。
到此,我们已经看到Google, Apple, Nokia, Palm等移动终端的领头羊们所采取的行动,然而,不要忘记软件厂商!Adobe就是杰出的代表。作为RIA的强烈倡导者,他也选择把webkit整合到其AIR平台,你可以想象这个webkit+flash的威力有多强大!而Adobe发起的openscreen项目,更是表明了他要在RIA上争夺王位的野心!
好了,不啰嗦那么多了,总之呢,webkit已经成为移动互联网这出大戏的主角了,回归到我在上一篇中提到的主题,让我们来研究一下android.webkit.WebView的功能,来看android上的RIA。
敬请关注下一篇--使用WebView的小例子。

posted @ 2009-03-10 22:39 勤劳的蜜蜂 阅读(2267) | 评论 (0)编辑 收藏

移动互联网时代的终端--暂时遗忘OSGi,让我们去品味一杯android磨出的移动互联网咖啡吧

1年多前,揣着在移动终端推广OSGi的梦想,我离开了原来的公司,来到了一个自认为更利于osgi的地方,在我看来osgi拥有eRCP这样的粉丝,应该会给它在移动终端上提供广阔的舞台。然而半路杀出个程咬金,google android!第一次见到它时,我不相信osgi会输,于是就废寝忘食的研究它,结果我没有进行太多的抵抗,很快就被Android收编了。我得承认它在某些关键的因素,确实比osgi更适合移动终端。对此,我只能感叹google开源的伟大,以及摒弃jcp的雷厉风行!但是,更为重要的是,在移动互联网时代即将到来的时刻,Android为我们打开了一扇方便之门,这到底为何?

通过对Android的(java)源码进行扫描后,我看到了像jsr211,MVM这些老朋友的影子,嗯,我可不想再炒这些旧饭了。还有啥?网上热炒android用了webkit作为其浏览器的引擎,和iphone的safari使用的引擎一样,这个东西应该不错,因为我一直觉得eRCP没有很好的web控件,使得它在移动平台上逊色不少,于是我翻到了android.webkit这个java包,wow! Google给webkit封装了很多java的接口,这真是java开发人员的福气,(听说很多java开发人员对sun的javafx期待度最高的就是一个传说中的JWebView控件,但是不知道出来没,算了,我懒得查证了,因为俺现在不想浪费太多在sun java上,呵呵),不过我觉得这更是广大互联网应用开发人员的福气!想想!用html + css + javascript就能编写android的类似电话簿,日历甚至手机桌面的应用,这难道不让您浮想联翩吗?所以,如果说Android为移动终端进入互联网开了一扇门,那么android.webkit.WebView就是这扇门的金钥匙,而webkit就是通向互联网的康庄大道!

其实android的webview是一个极端复杂的控件,而我个人认为它是可以实现现在热炒的RIA/webos等概念的基石!虽然我进入这个领域不长,但觉得它非常有意思,很有前途,所以我打算写一个系列,分享对它的理解,强烈欢迎各位高手指点!

怎么开始说呢?不知道大家有没有注意,年初Palm公司在CES上palm pre的基于webkit的webos惊艳之秀,十足掉起了大家的胃口,这是我听到第一个冠以webos的移动终端,这是不是意味着目前由palm来唱这个webos的独角戏呢?答案当然不是,其实很多终端厂家以及平台厂商很早就率领大部队兵临webos的城下了,相信很快一场硝烟弥漫的战争就要开始了......

欲知端的,敬请关注移本系列第二篇--忽如一夜春风来,web花开各终端

posted @ 2009-03-09 22:53 勤劳的蜜蜂 阅读(3406) | 评论 (7)编辑 收藏

OSGi介绍(七)bundle和service(续)

接上一篇的例子,为了更具体一点,我们考虑这样的case,
假设房地产开发商construction A采纳了规划公司design A的方案,打算建造公寓类型的房子CityApartment
然后客户A买了一套房子

用ooa方式分析这个case,
我抽象这几个实体:规划公司,图纸类型,开发商,房子,买房人
然后描述这几件事情:开发商选择设计图纸,盖楼然后销售;买房人根据图纸买房并使用房子

下面是我用java语言来简单描述它:

design A 公司

package design.a;
interface Apartment {
..
//方法省略先
}

 

开发商construction A

package construction.a

import design.a.*;//开发商要按照图纸盖楼

class CityApartment implements Apartment {
.
//方法省略先
}


class Construction implements BundleActivator{

}



客户 costumer A

package customer.a

import design.a.*;//客户要按照图纸选择房子

class Customer implements BundleActivator {
.
//方法省略先
}



然后我们把他们分别做成bundle
Bundle A : design A
其manifest中这样描述

BundleSymbolicName: design A
Export
-Package: design.a


Bundle B : construction A
其manifest中这样描述

BundleSymbolicName: construction A
Import
-Package: design.a
Bundle
-Activator: construction.a.Construction


Bundle C : customer C
其manifest中这样描述

BundleSymbolicName: customer C
Import
-Package: design.a
Bundle
-Activator: customer.c.Customer



这样,装入到framework后,framework就会把BundlB和C与BundleA关联起来,正好描述开发商A选择design A的图纸,客户A也不得不选择design A的图纸啦
可是,单从这里,我们看不出来,开发商和客户拿同一份图纸干什么。那我们得必须在BundleB和C的实现里面写点东西来说明。

这里给出开发商construction.a.Construction的伪代码:

class Construction implements BundleActivator {

 
public void start(BundleContext context){
  CityApartment apartment 
= null;
  Hashtable properties 
= null;
  
for(int i = 0; i < 100; i ++){
   properties 
= new Hashtable();
   properties.put(
"price",new Integer(1000 + i*5));//开发商为房子定价
   apartment = new CityApartment();//一套房子盖好
   
//把房子按照公寓注册出去并打广告,等待客户来购买,framework就相当于一个售楼处兼房屋中介
   context.registerService(Apartment.class.getName()/*公寓类型*/,apartment/*房子作为服务对象*/,properties/*与房子相关的附带信息*/);
   
  }

  
//这样开发商一共注册一百套房子
 }

}



而客户的代码可以如下:

class Customer implements BundleActivator {
 
public void start(BundleContext context){
  Apartment apartment 
= null;
  ServiceReference ref 
= context.getServiceReference(Apartment.class.getName,"(price=1050)");//先签署购房合同,而且指明选择Apartment类型,价格为1050的房子。
  apartment = (Apartment)context.getService(ref);//然后买到房子
  
//买房人就可以使用房子apartment对象进行日常生活了
 }

}


这样,我们就很清楚的看出,Design A为Construction A和Customer A提供了共同的Apartment定义,才使得他们有交易的可能。于此同时,Construction A和Customer A之间的耦合是非常松的,因为,如果有另外一个开发商onstruction B加入进来也构造了Apartment的对象,Customer就可以通过改变选择条件,轻易的获得B的房子,而客户本身不关心房子是A还是B盖的,这个是典型的面向对象的多态应用。

总的说来,Bundle在framework的帮助下,使得其他bundle使用其类型定义成为可能。service就是在这些共享的类型定义基础上产生的具体对象,而使用这些service对象的bundle,必然也是对应共享类型的使用者。
这种类型共享,在osgi里面叫做"class space". framework运行时通过关联bundle之间的类型定义,可以构成一个或多个"class space",而某个bundle在framework里面,只能处在一个"class space"里面,不能同时出现在多个"class space"中。
怎么理解这个话呢?请看下一篇,外星人入侵了。

 

posted @ 2007-07-21 22:28 勤劳的蜜蜂 阅读(1702) | 评论 (1)编辑 收藏