当冯英从她的包包里拿出刚买的粉色夏普双旋盖手机并赞不绝口,一场原本以工作沟通为主题的聚餐马上变成了一场手机讨论会。在场的另一位女性朋友表示,她正有同样的购买计划,只是在白色和粉色之间犹豫,第三位女性朋友虽然对上述两人的追捧态度感到惊讶不已,却也暗中开始对这款手机强烈关注。
三年前,日系手机抱憾全线败退中国手机,如今,夏普手机只身挺入虎穴,虽然不少人为夏普捏了把汗,夏普却还做得风生水起,并很快形成了一批自己的追随者。
当手机已经成为再普通不过的消费品,甚至已经成为“快消品”,当拍照、音乐都成为每款手机的基本功能,还有什么原因能让我们心甘情愿地为手机掏空我们的口袋?可能每个人都有自己的原因,但其中对利润产生决定作用的,竟然是——设计。
设计价值几何?
怎样才算得上一个成功的手机设计?摩托罗拉手机总设计师吉姆·维克斯认为,一部手机必须创新独特,即消费者在三米之外就能够辨认出来。
手机外观的重要性到底有多少?诺基亚首席设计师Alastair Curtis指出,手机的最初吸引力就来自于外观,它可以焕发消费者的购买热情,所以设计一直是诺基亚管理层重点关注的对象,同时也是诺基亚成功的保障。“诺基亚的目标就是要设计让人一见钟情的手机。”他说。
实际上,iPhone(手机上网)的大获成功让传统手机行业都为之震惊。iPhone仅凭借1%左右的市场占有率就拿下了全行业20%的利润。除了运营模式的颠覆之外,iPhone全触摸屏等突破性的设计本身确实功不可没。
在iPhone之后,各个品牌都开始纷纷模仿,并推出iPhone的类似产品就是一个证明。事后看来,这些产品仍然卖的不错。即使是中国的魅族M8,这个“看上去”跟iPhone完全相同的国产手机产品,尽管“内核”完全不同,上市2个月仍然拿出了销量10万的好成绩。
在国产手机行业,“山寨”是一个不得不提到的词汇。所谓山寨是指完全模仿成功机型设计的“白牌”国产手机。特别是联发科MTK平台的出现,让更多想进入手机行业的人轻松拿到了门票,MTK平台只解决了手机的内部构造问题,外观设计却一直是国产手机的软肋。
其实从功能上看,很多“山寨”手机不仅不逊于这些正牌手机,甚至还能略为领先。
但核心设计能力的欠缺让山寨手机只能选择模仿,模仿的产品最终只能进攻低价产品,获取低附加值。山寨手机已经在国产手机中占据半壁江山,竞争力却始终岌岌可危。
手机企业的困境
如今随着金融危机的来袭和手机市场低迷,越来越多的手机企业开始寻找出路。
到2009年第二季度,索尼爱立信的出货量为1380万部,比去年同期减少43%,销售额为16.84亿元,同比下滑40%,亏损达到3.7亿欧元。
索尼爱立信全球副总裁Matthew Costello8月底对CBN记者表示,造成亏损的一个重要原因是过度依赖功能手机(Feature Phone)。 波音博彩评价:http://www.bbin.ws
尽管索尼在拍照和音乐项目上功能强大,但在过去几年发展中,拍照和音乐已经成为手机的基本配置之一,200万像素和300万像素究竟有多大区别其实在消费者看来并不那么明显,音质的细微差别更是只有音乐发烧友才能分辨得清楚。
现在已经有越来越多的手机企业开始陷入困境。2009年第二季度,占全球手机销量38%的诺基亚净销售额同比下滑25%至99亿美元,手机销量同比下滑15%至1.032亿部。净利润下滑高达66%,达到3.8亿欧元,而在第一季度利润下滑超过90%。
诺基亚都事已至此,其他的手机企业变得更加落寞。除了三星和LG正在因为其他手机企业份额的下滑而从中获益之外,摩托罗拉看上去“狼狈不堪”。从2007年开始至今,摩托罗拉已经跌出了全球前三大手机企业,并且连年巨额亏损。
当然,国产手机企业更“惨不忍睹”。从2006年开始,国产手机企业陷入集体亏损,曾经的国产老大波导、夏新甚至接近退市边缘,2008年,后起之秀联想移动也因为亏损而从联想集团剥离,并且退出了新一代国产手机老大的宝座。
不止一家国产手机都在抱怨,手机行业的“好时代”已经过去了,从几年前50%以上的利润率到2006、2007年的20%,再到如今不到10%,诺基亚手机与服务业务部门过去两个季度的利润率仅为4.3%,手机行业正在彻头彻尾地变成低利润的制造业的一分子。
设计成“救兵”?
几乎所有手机企业都在疑惑和思考的是:当手机的拍照功能从30万像素上升到100万、200万、300万、500万、800万;当所有的手机都可以听音乐,相当多数的手机都可以具备GPS导航,技术进步还能在多大程度上挑动消费者的神经? 真人娱乐场:http://www.65bet.com/forum-82-1.html
TCL通讯CEO杨兴平在接受CBN记者采访时表示,TCL等国产手机要实现复兴,不是在技术上做文章,而是要做“能打动人”的手机。
LG手机设计师车康熙有类似的观点:在技术相同的条件下,今后决定产品成败的主要因素还将是设计。但他所谓的设计不仅是外观、线条和色彩等基本元素,还包括消费者使用和情感体验。 波音博彩平台:http://www.65bet.com/forum-81-1.html
在他看来,在消费者与手机、MP3等随身数码产品越来越“分不开”的今天,消费者与电子产品之间的关系已经变得越来越“亲密”,随身数码产品和品牌的设计已经不能单纯地停留在表面功夫,还必须能够与消费者建立一种伴侣式的“亲密感”,使产品和品牌成为消费者的“心灵挚友”。 博彩技巧:http://www.65bet.com/forum-30-1.html
“包括手机在内的消费电子产品已经完成了由功能为主向设计为主变革。谁能率先建立这种‘亲密感’客户价值,谁就能走在市场发展的前端,获得市场拥戴。”实际上,LG近几年走的这样的路线,虽然就技术和硬件水平而言,并无特别突出之处,但LG的设计一直较受欢迎,这也帮助LG迅速进入了世界前三大手机厂商之列。
仔细研究夏普目前在中国市场推出的几款产品,不管是拍照还是GPS,都是我们耳熟能详的功能,但相比同类产品,夏普仍然能卖出三四千元的价格,除了依靠更成熟的显示屏材料和技术之外,比如折叠旋盖的设计,以及更符合亚洲人喜好的颜色处理确实让很多消费者眼前一亮。
调研机构GFK针对国内手机市场4月27~5月3日统计数据显示,在高于4000元单价的手机市场中,三星仅一款排名第四,诺基亚名列第二,而夏普拿下了一、三名。
不过,易观国际手机分析师王留生也指出,在有好的设计之外,还必须有品牌基础,有稳固的渠道政策和成熟的市场推广策略才能保证最终市场的成功。毕竟像iPhone那种从内到外的颠覆性创新,短期内哪个手机企业能出其右呢?
文章出处:http://gundumw100.iteye.com/blog/1067414
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
◆Params 启动任务执行的输入参数,比如HTTP请求的URL。
◆Progress 后台任务执行的百分比。
◆Result 后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
下面是AsyncTask异步获取已安装程序列表的例子:
public class Screen1 extends Activity{ private static final String tag="Screen1"; private ListView listview; private Context mContext; private List<ResolveInfo> list; private AppAdapter adapter; private PackageManager pm; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); //给Activity注册界面进度条功能 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.screen_1); mContext = this; list=new ArrayList<ResolveInfo>(); pm = mContext.getPackageManager(); listview = (ListView)findViewById(R.id.listview); adapter = new AppAdapter(mContext); listview.setAdapter(adapter); listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub Log.i(tag, "---------------onItemClick-----------------"); ResolveInfo info=list.get(position); String packageName = info.activityInfo.packageName; String className = info.activityInfo.name; Intent intent = new Intent(); intent.setClassName(packageName, className); startActivity(intent); } }); new MyTask().execute(); } class AppAdapter extends BaseAdapter{ Context context; AppAdapter(Context context){ this.context=context; } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub if(convertView==null){ LayoutInflater inflater=getLayoutInflater().from(context); convertView=inflater.inflate(R.layout.simple_item_2, null); } ImageView iv=(ImageView)convertView.findViewById(R.id.icon); TextView tv=(TextView)convertView.findViewById(R.id.text); ResolveInfo info=list.get(position); iv.setBackgroundDrawable(info.activityInfo.loadIcon(pm)); tv.setText(info.activityInfo.loadLabel(pm)); return convertView; } } class MyTask extends AsyncTask<String, Integer, String>{ @Override protected void onPreExecute() { setProgressBarIndeterminateVisibility(true); showProgress(); } @Override protected void onPostExecute(String param) { setProgressBarIndeterminateVisibility(false); adapter.notifyDataSetChanged(); closeProgress(); } @Override protected void onCancelled() { // TODO Auto-generated method stub super.onCancelled(); } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); } @Override protected String doInBackground(String... params) { // TODO Auto-generated method stub // 获取已经安装程序列表 Intent intent = new Intent(Intent.ACTION_MAIN, null); intent.addCategory(Intent.CATEGORY_LAUNCHER); list = pm.queryIntentActivities(intent, 0); Collections.sort(list, new ResolveInfo.DisplayNameComparator(pm)); return null; } } private Dialog dialog; protected void showProgress() { if(dialog == null) { dialog = new Dialog(this, R.style.Theme_TransparentDialog); // dialog.setContentView(R.layout.progress_dialog); dialog.setContentView(new ProgressBar(this)); dialog.setCancelable(true); dialog.show(); } } // protected void closeProgress() { if(dialog != null) { dialog.cancel(); dialog = null; } } public boolean isShowing(){ if(dialog != null) { return dialog.isShowing(); } return false; } }
simple_item_2.xml
<?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" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="应用列表" /> <ListView android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
Android得到系统已安装应用程序包列表方法 自定义ListView显示 PackageManager的使用
AyncTask 实战 模拟GridView 动态更新效果
http://www.ophonesdn.com/article/show/80
文章出处:http://gundumw100.iteye.com/blog/1071424 (附件请去原帖下载)
在Java中通过Observable类和Observer接口实现了观察者模式。一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得到通知,就可以进行相应的工作。例如在文档/视图结构中,文档被修改了,视图就会得到通知。
java.util.Observable中有两个方法对Observer特别重要,一个是setChange()方法用来设置一个内部标志位注明数据发生了变化;一个是notifyObservers()方法会去调用一个列表中所有的Observer的update()方法,通知它们数据发生了变化。
Observer通过Observable的addObserver()方法把自己添加到这个列表中。这个列表虽然由Observable拥有,但Observable并不知道到底有哪些Observer正在观察等待通知。Observable只提供一个方法让Observer能把自己添加进列表,并保证会去通知Observer发生了变化。通过这种机制,可以有任意多个Observer对Observable进行观察,而不影响Observable的实现。
一个简单例子:
import java.util.Observable; public class SimpleObservable extends Observable { private int data = 0; public int getData(){ return data; } public void setData(int i){ if(this.data != i){ this.data = i; setChange(); } notifyObservers(); //只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。 } } } Java代码 import java.util.Observable; import java.util.Observer; public class SimpleObserver implements Observer { public SimpleObserver(SimpleObservable so){ so.addObserver(this ); } public void update(Observable o,Object arg/*任意对象,用于传递参数*/){ System.out.println(“Data has changed to” + (SimpleObservable)o.getData()); } } public class SimpleTest { public static void main(String[] args){ SimpleObservable doc = new SimpleObservable (); SimpleObserver view = new SimpleObserver (doc); doc.setData(1); doc.setData(2); doc.setData(2); doc.setData(3); } }
Data has changed to 1
Data has changed to 2 //第二次setData(2)时由于没有setChange,所以update没被调用
Data has changed to 3
Observable类有两个私有变量。一个boolean型的标志位,setChange()将它设为真,只有它为真时,notifyObservers方法才会调用Observer的update方法,clearChange()设标志位为假,hasChange返回当前标志位的值。另一个是一个Vector,保存着一个所有要通知的Observer列表,addObserver添加Observer到列表,deleteObserver从列表中删除指定Observer,deleteObservers清空列表,countObservers返回列表中Observer的数目,在Observer对象销毁前一定要用deleteObserver将其从列表中删除,不然因为还存在对象引用的关系,Observer对象不会被垃圾收集,造成内存泄漏,并且已死的Observer仍会被通知到,有可能造成意料外的错误,而且随着列表越来越大,notifyObservers操作也会越来越慢。
Observable的所有方法都是同步的,保证了在一个线程对其标志位、列表进行操作时,不会有其它线程也在操作它。
Observable的notifyObservers(Object obj)形式可以再调用update时将参数传进去。
通知顺序通常时越晚加入列表的越先通知。update会被依次调用,由于一个update返回后下一个update才被调用,这样当update中有大量操作时,最好将其中的工作拿到另一个线程或者Observer本身同时也是一个Thread类,Observer先挂起,在update中被唤醒,这样会有一个隐患,Observer线程还没来得及挂起,update就被调用了,通知消息就这样被错过了,一种解决办法是在Observer中实现一个同步的队列结构,并有一个类来封装参数,update实现一个参数类的对象把接收到的通知消息的参数封装在里面,然后把其加进队列,run方法从队列中移除参数对象,并进行处理,这保证了没有通知信息被丢失。
在多线程时,只有Observer会与单线程不同,Observable不需任何改变来支持多线程,因为它又很多作为单独线程运作的Observer。
http://blog.csdn.net/zhouyongyang621/archive/2010/07/20/5750702.aspx
Observable是一个类而不是一个接口这限制了它的使用,一个解决的办法是在一个Observable类中把我们的类包装进去(把我们的类实例当作Observable的域),因为Observable中的setChange是一个protected方法,我们没法在外面调用它。所以没法在我们的类中包装一个Observable,但是如果我们的类中同样也有protected方法,那这个办法就无法使用。
ContentObserver类详解:
http://blog.csdn.net/qinjuning/article/details/7047607
下面2个工程是Observable与Observer的经典运用,是android实现的单指拖动放大图片的操作。听说出自索爱。