多个工具集成,会造成很大风险,稍有不慎,就会造成问题。原来希望通过工具节约时间,提高生产效率,却因为不可预期的问题耽误时间。
在[cref 2717]中希望能提高开发的自动化,实现人员角色的分工,但是测试不彻底,android和maven是集成了,但是在使用eclipse和adt插件的时候又发现了问题:
- gen目录:adt不能生成gen目录,这样R类就无法生成;
- 手工做了一些配置,想映射到target中的对应目录下,也不完美,因为这样就不好用到adt插件了;
- 无法利用adt插件run android application了。
maven-android-plugin还不完善,虽然有电子文档,但是有的对不上,比如版本。 只好一个一个的看它wiki文档和下面的跟贴。
终于找到一个作者写的m2eclipse-android-integration,可以比较完美的实现这些工具的集成:
下面说说实现的步骤,这里用我的GolfDemo作为示例。
为什么要为android项目增加maven集成功能呢?这里我想到几个主要理由:
- 部署测试人员和开发人员的角色分离,让他们摆脱eclipse开发环境设置android sdk环境,直接在服务器上运行一个命令,然后下载它的apk包,安装到手机上;
- 开发人员和android market市场发布人员的角色分离,市场发布人员不知道什么是签名等等,也是在服务器端运行命令即可,需要输入密码,这个过程和开发人员隔离;
- 如果仅有上述两个理由,那么用android默认的ant脚本也可以了,还希望android项目需要的类库也自动解决依赖问题,那么就使用maven吧。
说一下集成maven的步骤。
firefox有mldonkey插件(参见使用mldonkey的firefox插件),这样,就可以在浏览verycd的时候,直接点击上面的ed2k连接,然后自动通过家里服务器(mldonkey server)通过电驴下载东西。
发现在chrome扩展中还没有好用的插件,有一个可能是国人写的,但是太简单了。我希望有一个和firefox插件类似的东西。
于是自己动手写了一个。目前还比较丑陋,但是已经可以类似firefox mldonkey插件那样工作了。
当点击ed2k链接后,会弹出小窗口提示已经加入下载。
在通过content script选取HTML框内容的示例中,展示了content script的基本功能。
又在该示例上做了一些测试工作,比如是否可以获取到javascript生成的内容,答案是没问题。那么如果是ajax加载的数据呢,也没有问题。因为,content script和网页自身的javascript代码共享dom对象,虽然它们之间不能互相调用。
源代码见:
http://easymorse.googlecode.com/svn/trunk/chrome.demo.dom.selector/
这里也有一个简单的ajax示例,用于测试是否可以得到ajax动态改变的页面内容。
不过,在用本示例的扩展抓取比如qq web邮箱中的信件条目的时候,失效了。分析了一下原因,是因为qq web邮箱,用的是iframe,扩展中编写的代码只针对当前页面对象中的节点,没有考虑iframe中的节点。
时间原因,没有尝试做抓取iframe中节点,但,基本思路应该是,迭代各个iframe元素,然后监听它下面的所有元素,当鼠标进入时做啥等等。
总结一下:
- content script可以和其他javascript通过共享DOM实现一些受限的交互;
- content script可以和backgroud页面通过Message实现通信。
在通过content script改变web页面中只是简单的增加灰色的边框,还不具有生产意义。这里提出一个需求,就是选取某个html框内的内容。那么需要让这个框是带灰色边框的,另外,双击这个框内区域,弹出警告对话框,并显示框内的html文本信息。类似这样:
google chrome extension可以改变页面,通过content script来实现。
写了个特别简单的代码,可以看到google搜索的结果,所有div都增加了1个像素点的边框。
这是一个很简单的示例,但是可以说明使用chrome extension的content script。
效果很简单,无论通过chrome浏览器打开什么网站,都会在页面加载完成后弹出一个警告对话框。如图:
这个插件很简单,首先需要创建一个目录,在任意地方。
blogo的问题是,xml无法正常在博客正文中显示。
测试一下ecto是否可行:
<?xml version=“1.0″ encoding=“utf-8″?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“fill_parent” android:layout_height=“wrap_content”>
<ImageView android:id=“@+id/image” android:src=“@drawable/d1″
android:layout_width=“wrap_content” android:layout_height=“wrap_content” />
<TextView android:id=“@+id/title” android:layout_width=“wrap_content”
android:layout_height=“wrap_content” />
</LinearLayout>
发现不但可行,而且显示格式还非常好。
而且支持中文。
如果是串行化(serialization)或者相反操作,可以使用xstream,参见android下通过xstream解析xml格式信息。而且很省事儿。
但是如果是解析xml数据,比如获取google weather api,就需要灵活的遍历xml节点和属性。
android SDK提供了xmlpull api,xmlpull和sax类似,是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因此xmlpull和sax都比较节约内存资源,不会象dom那样要把所有节点以对橡树的形式展现在内存中。
xmlpull比sax更简明,而且不需要扫描完整个流。
xmlpull的官方网址在:
使用起来很简单,比如google weather api获取数据类似这样:
http://easymorse.googlecode.com/svn/tags/android.xmlpull.google.weather-1.0/assets/weather.xml
现在比如只想获取current_conditions元素节点的信息,即只获取当前的天气信息。想要产生的效果类似这样:
代码:
private void setWeatherInfo(TextView textView)
throws XmlPullParserException, IOException {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = factory.newPullParser();
parser.setInput(this.getAssets().open(“weather.xml”), “UTF-8″);
for (int i = parser.getEventType(); i != XmlPullParser.END_DOCUMENT; i = parser
.next()) {
if (i == XmlPullParser.START_TAG
&& parser.getName().equals(“current_conditions”)) {
StringBuilder builder = new StringBuilder();
for (int j = parser.getEventType();; j = parser.next()) {
if (j == XmlPullParser.END_TAG
&& parser.getName().equals(“current_conditions”)) {
break;
}
if (j == XmlPullParser.START_TAG) {
if (parser.getName().equals(“temp_c”)) {
builder.append(“当前气温:”).append(
parser.getAttributeValue(0)).append(“摄氏度”);
}
if(parser.getName().equals(“wind_condition”)){
builder.append(“, “).append(parser.getAttributeValue(0));
}
}
}
textView.setText(builder.toString());
}
}
}
源代码:
http://easymorse.googlecode.com/svn/tags/android.xmlpull.google.weather-1.0/
在项目里面使用ListView,并要求ListView的条目中有图片显示,而且这个图片是通过网络动态获取的。
这时候,会发现ListView加载很慢,半天才显示出来,影响了用户的体验。
这是因为,使用了当前线程(绘制ui的线程)去下载图片。应该另外开辟线程异步下载图片。
实现的效果如下: