待实现的接口
public interface ImageCallback { void imageLoad(Drawable image,String imageUrl); }
回调接口的方法
//参数有一个实现回调接口的imageCallback对象 public Drawable loadDrawable(final String imageUrl,final ImageCallback imageCallback){ Log.i("AsyncLoadImage", "loadDrawable()"+imageUrl); //如果缓存中有则从缓存中取出来 if(imageCache.containsKey(imageUrl)){ SoftReference<Drawable> softReference = imageCache.get(imageUrl); if(softReference.get()!=null){//判断是否有drawable return softReference.get(); //有则返回 } } //使用线程池下载图片 executorService.submit(new Runnable(){ @Override public void run() { try { // final Drawable drawable = Drawable.createFromStream(new URL(/blog_article/imageUrl/index.html).openStream(), "image.jpg"); final Drawable drawable = getDrawableFormUrl(imageUrl); //调用获取数据的方法 imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));//将加载的图片放入到内存中 mHandler.post(new Runnable(){ @Override public void run() { //调用回调接口的方法,已由imageCallback实现! imageCallback.imageLoad(drawable,imageUrl);//接口回调 } }); } catch (Exception e) { throw new RuntimeException(); } } }); return null ; }
一个列表适配器的getview方法,已重写
@Override public View getView( int position, View convertView, ViewGroup parent) { Log.i(TAG, "getView()"); if(convertView == null){ //获取布局 convertView = LayoutInflater.from(cext).inflate(R.layout.item_image, null); //获取布局里面的ImageView组件 final ImageView imageView = (ImageView)convertView.findViewById(R.id.item_imageView); //获取当前的图片的url地址 final String url = urlList.get(position).getImageUrl(); //为图片设置一个tag 这个很重要这样的目的是为了控制每个ImageView组件都显示对应的图片 imageView.setTag(url); Log.i(TAG, "初始化"+(position)); //开始异步加载图片 //[color=red]实例化一个实现接口的对象,供上一段代码loadDrawable调用[/color] Drawable drawable = asyncLoadImage.loadDrawable(url, new AsyncLoadImage.ImageCallback(){ @Override public void imageLoad(Drawable image,String imageUrl) { //判断当前的url地址是否为当前组件的url地址 是则加载图片 if(imageUrl.equals(imageView.getTag())){ imageView.setImageDrawable(image); } } }); }else{ Log.i(TAG, "完成后的初始化"+(position)); final ImageView imageView = (ImageView)convertView.findViewById(R.id.item_imageView); final String url = urlList.get(position).getImageUrl(); imageView.setTag(url); Drawable drawable = asyncLoadImage.loadDrawable(url, new AsyncLoadImage.ImageCallback(){ @Override public void imageLoad(Drawable image,String imageUrl) { if(imageUrl.equals(imageView.getTag())){ imageView.setImageDrawable(image); } } }); } return convertView; }
手机震动可以是一种提醒或是替换铃声的事件,如果想要让手机乖乖的震动,需要创建Vibrator对象通过Vibrator方法来实现达到震动的模式,在Vibrator的构造方法中有四个参数前三个值是设置震动的大小,可以把数值改成一大一小这样就可以明显感觉到震动的差异,而最后一个值是震动的时间, Repeat=0时,震动会一直持续repeat=-1震动只会出现一轮,运动完毕后就不再震动
判断ToggleButton是否被开启。如果单击就是“ON”就会启动震动模式如果点击OFF就会关闭振动模式
先定义一个Activity
package cn.hwttnet.com.ui; import android.app.Activity; import android.app.Service; import android.os.Bundle; import android.os.Vibrator; import android.view.View; import android.view.View.OnClickListener; import android.widget.Toast; import android.widget.ToggleButton; public class EX05_06Activity extends Activity { private Vibrator vbt; private ToggleButton tb1, tb2, tb3; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); vbt = (Vibrator) getApplication().getSystemService( Service.VIBRATOR_SERVICE); final ToggleButton tb1 = (ToggleButton) findViewById(R.id.toggleButton1); final ToggleButton tb2 = (ToggleButton) findViewById(R.id.toggleButton2); final ToggleButton tb3 = (ToggleButton) findViewById(R.id.toggleButton3); //短震动 tb1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (tb1.isChecked()) { vbt.vibrate(new long[] { 100, 10, 100, 1000 }, -1); Toast.makeText(getApplicationContext(), "震动开启", Toast.LENGTH_LONG).show(); } else { vbt.cancel(); Toast.makeText(getApplicationContext(), "震动取消", Toast.LENGTH_LONG).show(); } } }); //长震动 tb2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (tb2.isChecked()) { vbt.vibrate(new long[] { 100, 100, 100, 1000 }, 0); Toast.makeText(getApplicationContext(), "震动开启", Toast.LENGTH_LONG).show(); } else { vbt.cancel(); Toast.makeText(getApplicationContext(), "震动取消", Toast.LENGTH_LONG).show(); } } }); //节奏震动 tb3.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (tb3.isChecked()) { vbt.vibrate(new long[] { 1000, 50, 1000, 50,1000 }, 0); Toast.makeText(getApplicationContext(), "震动开启", Toast.LENGTH_LONG).show(); } else { vbt.cancel(); Toast.makeText(getApplicationContext(), "震动取消", Toast.LENGTH_LONG).show(); } } }); } }
定义一个main.xml
<?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="fill_parent" android:orientation="vertical" > <TableLayout android:id="@+id/tableLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:collapseColumns="3" android:stretchColumns="1" > <TableRow android:id="@+id/tablerow1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" > <ToggleButton android:id="@+id/toggleButton1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="短震动" /> </TableRow> <TableRow android:id="@+id/tablerow2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" > <ToggleButton android:id="@+id/toggleButton2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="长震动" /> </TableRow> <TableRow android:id="@+id/tablerow3" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" > <ToggleButton android:id="@+id/toggleButton3" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="节奏震动" /> </TableRow> </TableLayout> </LinearLayout>
然后震动事件必须允许android .permission.VIBARTE权限
<uses-permission android:name="android.permission.VIBRATE"/>
试着把震动的大小做多变化的改变在long[]里面多做一些变化
tb3.vibrate(new long[]{10000,500,10000,500,10000,500,10000},0);
近年来Android、IPone手机以燎原之势迅速普及,WP7也对火热的智能手机市场呈现跃跃欲试之态,随之而来的便是移动互联网市场的风起云涌,移动应用开发炙手可热,谁都想来分得移动应用开发的一杯羹,但是不同的手机品牌不同的手机系统,如何缩短开发时间,减少开发流程,快速开发出能够适配多种平台的应用?这成为摆在众多开发者面前的一道难题,也成为移动化开发快速发展的内驱力。国内的移动化厂家,在狼烟四起的年代,都有着或多或少的动作。国内做移动化的厂家,代表性的除了老牌的烽火星空、数字天堂,后起之秀APPcan,还有新生的MM应用引擎即MM App Engine。
作为在移动开发市场上才刚刚崭露头角的工具,MM App Engine面临着内忧外患,外有Phonegap的强大攻势,内有老牌的烽火星空、数字天堂,后起之秀APPCan带来的生存压力,或许以实力和特色突围,才能在强敌林立的江湖,中闯出一方天地。下面我们一起来分析比较一下MM App Engine和AppCan这两大独具特色和发展潜力的移动应用开发平台。
1.身世之谜探究
MM App Engine其实是中国移动近期推出的面向开发者的应用运行托管系统,它是基于HTML5跨平台技术和在线托管服务的生态系统,支持跨平台移动应用开发,提供应用托管服务以及各类数据云服务,为开发者提供一站式应用开发、调试、部署支持和应用管理。
APPCan则是国内领先的专注于移动互联网的高新技术企业正益无线强力推出的供专业的移动互联网应用支撑平台,包括移动应用开发平台和企业移动整体,它同样支持跨平台移动应用开发,实现对移动应用全生命周期(Full LifeCycle)的支持和管理。
从专业性而言,APPCan是正益无线的强势产品,集合公司全力推进,应该说已经先行一步,而MM App Engine系出名门——中国移动,综合实力不容小觑,或许后发制人也不足为奇。综合考虑,APPCan赢得一分。
2.技术要求之对比
MM App Engine提供使用符合HTML5标准跨浏览器UI组件,包括:导航条、按钮、下拉列表、复选款,让开发者通过对各种元素的选择,方便灵活的开发移动应用。开发者可以傻瓜式的拖曳即可开发移动应用,开发门槛极低。
AppCan开发跨平台应用需要懂得HTML+JS+CSS相关知识,同时对AppCan提供的API接口有所掌握,如果你没有相当的技术功底,几乎无法开发出一款实用的应用。
从这个角度来说,MM App Engine对于开发者的技术要求更低,适用于更广大开发的群体。
3.开发流程之角逐
MM App Engine提供基于Eclipse的应用开发及部署工具,即需要下载安装开发环境,并确保Eclipse版本不低于3.6,JDK版本不低于1.5。MM App Engine包括统一开发环境,提供Java/PHP语言应用的代码编写、运行、测试环境,并提供应用代码检查功能,拥有本地模拟环境,提供云服务RDS/分布式缓存本地模拟和测试环境,同时,便捷的“一键部署”工具,应用一键部署到云端托管环境,方便开发者对应用快速安装和部署。简言之,分为四个步骤创建应用、应用开发,快速部署、立即访问,步骤清晰有条理。
AppCan开发流程与MM App Engine类似,首先要在AppCan网站上面下载开发工具AppCan-SDK,AppCan SDK是专为开发者提供的全方位的集成调试环境,之后再安装(首次安装SDK,安装完成后必须重启,并且对SDK有一定要求,需支持win xp SP3以上系统、WIN7。如电脑以前安装过JRE系统,请确保JRE为1.6或以上版本)。安装之后需要先学习AppCan-SDK,之后才可以开始应用开发。
二者的原理都是基于集成开发环境,开发流程类似,不分伯仲。
4.生态链条的完备情况对比
MM App Engine为开发者提供了从应用开发、管理、维护推广一系列完整的服务,它不但有先进的跨平台开发技术,同时有着安全和成本极低的云托管平台,对接了中国移动的MM商城,借助该商城强大的号召力,直接获益。开发者从部署开发到应用推广,可以完全享受MM App Engine提供的一条龙服务。
AppCan提供给开发者开发功能和基本的应用管理,帮助开发者了解应用下载情况,对于开发者后期的维护和推广服务还处于深入探讨阶段。
毫无疑问,这个回合,MM App Engine获得了当仁不让的领先。
5.工具扩展性之争
MM App Engine支持各类代码开发,同时支持跨平台,适用于互联网应用各主流环境。
AppCan平台支持代码开发,也无大限制。
这局,二者依旧平手。
总言之,MM App Engine与AppCan各有优缺点,经过5个回合的角逐较量,二者两次平手,而其余三回合,MM App Engine凭借着微弱的优势,小胜AppCan。其实二者都是为了克服手机平台差异性,缩短开发时间,减少开发流程,压缩开发成本,帮助开发者快速开发出能够适配多种平台的应用,降低移动应用开发的一道门槛。希望两个产品完善不足的地方,越来越棒,提供更好的开发平台,造福更多的开发者。
<!--EndFragment-->