作者TonyQ (自立而後立人)
看板AndroidDev
标题[闲聊] 那些我从 android app 学到的事情
时间Sat Jun 8 05:46:46 2013
作者是 java 人买了 android 手机就想着可以自己写 app,
但其实还蛮懒的想不到要写什麽,
最後总算在买了两年後在公司专案上碰到 android app。
其实应该一篇一篇专文写得,不过最近实在太忙,
整理在一篇讲一下心得就好。
我这人懒得讲废话,底下讲得都是我心中的重点。
作者 android 纯新手,有些地方如果我讲得不对,
请直接指正我没关系,我会回来修改内文。
然後底下所有东西都没谈到 web view,
不是他不重要,是因为我没空碰跟专案规划上没用到。先声明。
底下环境都是有装 android-support-v4.jar 的前提下。
所有程式码基本上都是示范用,直接跑大概都还得改一些东西才会动,
基本上就是我从专案拔来去掉 package 跟一些不重要 import 的结果,
所以有 compile error 是正常的,想用就自己读一下逻辑。
---------------------------------
作者底子:
Web 写 n 年,前後端都碰,算精通。
Java/JavaEE 三年++ ,算精通。
Eclipse 非常娴熟(有 Eclipse plugin 开发经验...)
Android 经验 0,
只有一年前试着建环境时开 emulator 跑个 hello world ,
结果以 emulator 完全当掉跑不起来失败告终。
---------------------------------
目标专案:
因为工作需要的关系跑来写 android app ,
目标是作我们 server 的资料给我们下游厂商看,
然後可以做一些比方说是 server 跟 client 互传讯息(含图片),
client 作业时可以拍照、录音上传、设定闹钟提醒 client 。
btw 作者是个自干控,里面有许多 list ,
但是我都是自己刻没用 list view。
网站我写的、android app 也我写的,web api 也我刻的,
所以以下都是第一手经验,绝对不怕踢馆。XDDDDDDD
---------------------------------
基础建设篇:
@ Android 环境建置:
有很多 api 版本,但是基本上不用全装,不要像我白痴的全勾然後等超久,
装你想要开发的开发版(我是装最新的)跟你想要支援的最小版本,
剩下的开发过程有需要再装就好了。
没事不要升级 build tool 特别是在专案死线前,
要升级请留个 4-5 个小时,处理升级後可能会有的开发环境问题。
安装还算容易,装完把 eclispe 开起来就有很完整的环境。
@ 模拟器
内建的模拟器是垃圾,又慢又难用,真的是用到会想翻桌。(完)
建议用 androVM ,只要装 virtualbox (免费) 直接挂载他的 vm image 。
http://androvm.org/blog/
(2013/10/21 注,现在建议改用 genymoon 了~)
然後开起来需要再手动下一行指令作 adb connect,
adb connect 是用来让他出现在 eclipse 能看见的装置清单。
我在 windows 底下是写一个 bat 长这样(两行要接一起没换行),
adb 路径可能会需要看各自位置改一下,点两下就可以自动连接 还算方便。
--
C:\eclipses\adt-bundle-windows-x86_64\sdk\platform-tools\adb connect
192.168.56.101
--
@ 装置
手机除错选项要开,剩下就没啥问题了,线插到电脑上通常就会自己抓到了。
因为我懒得每次 run/debug 都在装置,
有多个装置时我会建多个 run configuration,
像是 myapp_androvm , myapp_evo3d 之类的。
然後执行不同 run configuration 时,
选择对应的 device 然後勾 always use this in the future。
选错了也没关系,重开 eclipse 就会要你再选一次了。
@ debug
Debug 最重要的当然是 breakpoint ,watch variable/expression。
不管模拟器或实机,基本上 breakpoint 都是能用的,
我一开始以为只有模拟器能用 breakpoint ,事实上是我白痴。
但是有些状况 breakpoint 不会触发,
因为 debug mode 基本上是 by process 去 inject 的。
有些 activity/service 在後来才起不同 process 去作的情况下,
你需要手动(?)设定 process 为 debug 的设定。
但像是 BOOT_COMPLETE 或 service 在 startService 才开另一个 process,
这种事件你不太可能抓到,所以有时候 breakpoint 没 trigger 可以检查这。
(通常要开在另一个 process 会需要在 menifest 里面设定,
应该不会错过才对。)
如果是 service 的话我通常是先设定成同一个 process debug 完再改回去,
BOOT_COMPLETE 我就纯粹靠 log 了。
(当然,也有可能只是我不知道该怎麽作。)
@ log
Android Eclipse 上 log 有内建的 logcat view ,
可以开这个 eclipse view 来看 log,
log 很多很乱,可以只筛 by applcation 来看自己 app 的 log 就好。
然後如果碰到当掉(俗称闪退),通常都是死在 NPE 或其他 exception,
开过来直接扫哪些是红字的 stacktrace 通常都很有帮助。
eclipse 的 logcat 在多个装置切换时会有灵异现象,
他没有聪明到你 run 哪个 dev 就切到哪个 dev 的 log。
像我在 androVM 跟 evo3d (实机) 两个装置间执行,
老是我在跑 evo3d 时看到 logcat 是 androVM 的 log 然後就鬼打墙。
我後来终於搞懂要怎麽驾驭他,很简单,
用 "run" mode 在你目标装置去跑你的 app ,
之後在 device view 选到你的装置的你的 app ,右上角 debug 插下去,
他就会自动显示 debug 中的装置的 log。
然後只要你没有再做一次这个动作,基本上 log 就不会换装置。
有点蠢我知道,但是这样作还算能动。
基本建置篇大概就写到这。
---------------------------------
架构篇(简论)
架构不外乎几个:
Activity 、Service 、 Receiver , 前两个比较重要,剩下的後面讲:
@ R
这是我虽然写了有点久 java 但是我写 android 还是非常卡的一个重点,
android 会自己 parse xml 去做一些很神奇的事情,
像是你在 layout 写个 android:id="@+id/hello" ,
java 世界就会多个 R.id.hello 可以用,
写个 .aidl 档, java 世界就会多个 interface 可以用。
res/drawable 资料夹里面多放个图档或 xml,
java 世界 R.drawable 就会跟着出对应属性可以用
重点在於,要去理解 android 在哪些状况哪些事情会帮你作 code gen,
code gen 对应的内容是什麽,习惯他的鸡婆之後就会好一点。
比较常见的是 R.drawable , R.id, R.layout , R.string
这件事情不太稳定,如果他运作得怪怪的,停掉整个 project ,
然後作 clean build 通常会改善。
@ Intent
Android 里面传递资料的基本单位,
可用 extra 来传递string/int/long ..etc。
也可用来指定要开启哪一个 activity / service。
举例在 activity call 这段 code 可以传递三个资料给 ImageActivity。
Intent intent = new Intent(MainActivity.this,
ImageActivity.class);
//MainActivity.this 是当前的 activity instance
intent.putExtra("Title","桃园县 asdasdasd先生 1 ");
intent.putExtra("Url", "
http://my.org/66.jpg");
intent.putExtra("Name", "media_66");
startActivity(intent);
而在 ImageActivity 则是这样接收
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
String title = extras.getString("Title");
String url = extras.getString("Url");
String name = extras.getString("Name");
//作其他的事情
}
@ Activity
如果你什麽都不会 Activity 一定是最先开始学的,
拿网页来类比的话, activity 大概就是 xxx.html ,
里面可以设 contentview 指定读取特定 xml 来呈现画面,
可以设定事件之类的。
你看到 app 里面一个一个的画面大多都是由 Activity 堆叠出来的,
然後你按 back 键通常就是回到上一个 Activity。
(可以设 flag 让它不要,但 default 就是回到上一个 Activity )
Activity 有几个 life-cycle method 一定要知道,
onCreate 、onStart、onResume 、onPause、onDestory
一般画面的建立跟呈现会尽量建议做在 onCreate 。
onStart、onResume 跟 onCreate 的差别,
onStart、onResume 触发次数比较多次,
是会在你手机切换到桌面再切换回来当前 activity 时、
onResume 会重新被 call 。
onPause 则是你切到其他 app 或回桌面时会 call ,
onDesotry 则是你开了太多其他 app 或是 finish时会 call 。
android user 一定都知道,使用者开一个画面之後,
看到 nofitication 或回桌面开其他 app 去干甚麽事情是很正常的事情,
所以不要期待一个 activity 会活太久。
@ Service
既然一个 activity 不会活太久,所以如果我想作一些事情,
像是定期检查有没有新讯息之类的,就不太适合在 activity 作,
因为我们可能希望每十分钟检查一次或之类的,
万一 activity 被 kill 掉就很麻烦。
service 就会是个好选择,他可以持续很长的时间。
只要在适当的时候 call startService 或是在 menifest 里面指定就行了。
另外在使用 service 要注意长时间存在就表示会有耗电问题,
要比较注意不要作太累的事情。
@ Service/Activity 沟通
讲了 Service 跟 Activity ,实作上你接下来一定会问,
那怎麽在两者之间传输资料,基本上是透过 Activity bindService 达成。
这边蛮复杂的,然後我实作下来的经验我会告诉你,
直接写 AIDL 最快。
http://developer.android.com/guide/components/aidl.html
这可以让你达到 Activity 在跟 Service 沟通时,
像是在直接操作 Service 的方法。
这里有我一个在 service 作背景录音,但由 Activity 控制的例子。
https://gist.github.com/tony1223/5731812
这里有一篇别人写的文章可以参考
http://android.yaohuiji.com/archives/728
@ Fragment
这个其实很重要,但我跟他不太熟,就先跳过。
我自己写 tab 时有用到 Fragment (我用官方建议的作法),
但是用得很火大,因为切换 tab 时 fragment getActivity 全死,
有些透过网路去抓资料的会比较晚更新,
但那时候如果 fragment 已经被 detach ,操作 UI 就非常容易中 NPE 。
搞得我每次作 UI 操作都要先判断 isAdd() ,常常中奖。
(当然,应该是我比较笨不会用。 -_-)
@ Receiver
用来注册事件跟执行的角色,他是可以跨 service 跟 activity 的,
甚至跨 app 都行的。
像是我们可以用 Receiver 来接 BOOT_COMPLETED 事件,
就可以在 android 一开机就做某些事情。(当然,需要额外要求权限)
他其实就像是 APP 等级的 event listener 。
在 activity /service 可以透过 sendBroadcast ,
来 trigger 事件叫 receiver 做事。
---------------------------------
废话扯太多了写不完了 -_-
底下加快速度继续讲一些重点,有些如果写得太简单的欢迎推文问,
我没有时间把每个部份写得很细,但现在写得都是我有实作的。Orz
---------------------------------
UI 功能相关篇
@ 网路
请让我粗鲁的下个副标:这真的是很靠北的麻烦问题。
android 4.0 以後不准 UI thread 里面碰网路,
这是完全可以理解的。
因为网路的传输可以快可以慢,但通常都很慢,
如果在 UI thread 里面作网路传输很有可能会让画面白掉、停止回应,
(就跟 web 的 sync request 一样意思。)
这意味着什麽呢?
先不要说你需要透过 web 去抓资料、爬资料、 call web api 之类的。
光是你要从用一个 imageview 显示一张放在网路上的图,
都得开个子 thread 先去把图片抓回来。
(不过抓图这件事情还有麻烦的问题,後面专章讨论。)
然後你 google 一下网路会有几个解法,众说纷纭,
大抵不外乎一个是 handler ,一个是 AsyncTask ,一个自己开 thread,
我直接可以在这里讲,大部分状况下直接用 AsyncTask 会比较快乐。Orz
理由:
life cycle 明确、资料传递简单(postMessage真的很烦)。
我一开始用 Handler 写得 5-6 个实作後来全被我拆成 AsyncTask 了。
他有两个 method ,一个叫 doInBackground(){} ,
不在 ui thread 里面所以你可以干 network 有关的事情。
另一个叫 onPostExecuted() 会把你在 doInBackground 准备好的东西传回来,
这时候就在 ui thread 里面所以你可以安心改 ui。
他还有其他 method ,但是我没用到我就不介绍了,有兴趣的自己啃文件;
但一定要小心的一件事情是 onPostExecuted 被执行的时间点不一定,
所以操作 ui 时不要假设他的执行顺序。
剩下的自己参考这篇文章
http://stackoverflow.com/questions/6964011/handler-vs-asynctask-vs-thread
@ 判断网路连线状态
有时候你会需要判断目前网路的连线状态,请参考这只 class:
https://gist.github.com/tony1223/5732145
context 可以丢 activity/service,
在 receiver 时直接把 onReceive 的 context 扔进去就行了。
当然,如果你想进一步判断现在连线的是 3g 或 wifi ,
(有些应用程式比较聪明的会在连接到 wifi 时才做需要大流量的事)
可以用 networkInfo.getType 去判断是 mobile(3g/4g) 或 wifi,
这里有 sample
http://goo.gl/C6eY0
然後如果你想作连上网路时自动恢复作业之类的,
你可以写个 receiever 听这个 action
android.net.conn.CONNECTIVITY_CHANGE
//manifest
<receiver android:name=".MyNetworkConnectedReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
这里有一个我写好的 receiver 范例
https://gist.github.com/tony1223/5732191
然後注意,开启 app 时并不会因为手机有连线就自动触发这个事件。
(上面这行有需要、看得懂的就知道我在讲什麽,看不懂就算了。XD)
---------------------------------
没时间了,底下以流水帐形式非常快速的带过
---------------------------------
@ 拍照问题
可以直接调用原生的相机 Activity 进行拍照,
但你一开始应该会碰到图很小的问题。
要设定 EXTRA_OUTPUT 让他把档案存在 SD 卡里面,
这样才能拿到完整解析度的图档。
范例 code 示例
https://gist.github.com/tony1223/5732291
然後这里手动拍的照片是不会存进使用者相簿的,
所以使用者可能会觉得有一点不方便。(至少我会)
如果你想让照片也进使用者相簿的话,可以看这个范例,不算难很好写。
https://gist.github.com/tony1223/5732304
@ 录音 自己找范例吧(汗)
@ 播放音源档
这里我直接用内建的播放软体开,蛮简单的。
Intent audioActivity = new Intent(Intent.ACTION_VIEW);
audioActivity.setDataAndType(Uri.fromFile(file), "audio/*");
startActivity(audioActivity);
@ 图片问题
android 的记忆体非常小,(16MB 起,看装置)
所有你自己 create 的 bitmap 都要自己手动 recycle ,
然後大多数的时候你只能呈现小图,不然没几张图你就爆了。
但是基本上 bitmap 操作还算蛮容易的。
这里非常容易事後整死人,请务必在很早期时就开始正视、面对这个问题。
这一块比较大的问题是在从档案或网路读取的图档,
我有独立写了一只包 cache 的 AsyncImageDownloader ,
不然每次一读网路图片就要写一次真的是没完没了,
然後在里面也处理掉 recycle 的问题,当然这只是解法之一。
我用了一个 interface 跟一个自己做的 action 来处理这个问题。
(主要还是我一直找不到 activity onDestroy 的 listener ,
我猜这里还有更简单的作法,写到这里想到如果现在是我作,
直接实作 image view 可能更靠谱,anyway 先我把目前的解法放出来。
)
(因为我所有的 activity 都有过自己的 BaseActivity ,
我是直接源头处理掉。)
范例码
https://gist.github.com/tony1223/5732415
@ 档案上传相关
千万别把档案转 base64 再传,
base64 会增加 33% 的体积真的只是小问题,
真正的问题是字串组装非常的浪费记忆体,(即使你用 stringbuffer)
超容易因为字串太大而 OOM 的。
(当然,这是跟 in-place 只读几 byte 写入几 byte 的 IO stream 比。)
然後也别像我这麽假掰不只用 base64 传,还用 JSON 传,
导致我传一个 5M 的档案,系统实际上会组出两个 超大字串。
我本来只是想让 web api 一致的,在这个议题上浪费 40 hrs+ 後我放弃了,
反正我是觉得在 android 的记忆体没办法这样搞。
我用 JSON + base64 传 3M 档案就有好几只手机会当掉了,
(对,偏偏就是我的开发测试机不会,Evo 3d 你好样的...)
传 10M 档案是全死,改用 multipart 上传後传 30m 都没问题。-_-#
android multipart 的档案上传很简单,
因为内建就有 httpclient ,只需要额外 include httpmime ,
放到 libs 资料夹跟加到 classpath。
我是在这里抓 httpcomponents 整组,只拿 httpmine-4.2.5.jar 出来用。
http://hc.apache.org/downloads.cgi
这里我直接放我自己用来作 get/post/multipart 的 util 函式当范例,
其实 httpclient 现在作 multipart 用法真的很简单,不难。
https://gist.github.com/tony1223/5732470
server side 的实作则跟一般网页表单上传一样。
@ 闹钟
android 有内建的 AlarmManager,可以自己在指定时间,
叫醒你一只 receiver 起来做事,
所以你不用自己烦恼要怎麽写一只 service 定期检查时间。
sample 大概如下
------------
Calendar cal = Calendar.getInstance();//这是要响起的时间
//设定时间
//ex. cal.setTime(new Date(2013,6,9));
AlarmManager alarmManager = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MyActivity.this, AlarmReceiver.class);
//要传给 receiver 收的资料,这里我传的是案件编号
//intent.putExtra("RequestWorkID", detail.getRequestWorkID());
int uuid = 10;//just for example ,请视状况取不重复 id
PendingIntent pi = PendingIntent.getBroadcast(SheetActivity.this,
uuid, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
-------------
receiver 收到後要弹 dialog、要发讯息干麽都可以。(那又是另一个故事了)
当然,还是有要注意的事情:
1.如果指定的时间是过去的时间,会当下马上响而不是忽略
2.重开机後,重开机之前设定的闹钟全部会消失。
这里我会建议先用 sharedPreference 存一份,
搭配 BOOT_COMPLETED 时重新注册事件。
@ 存资料
有几个选项: SQLite 、 SharedPreference、存档案
我自己是懒得用 SQLite ,我的东西不算多感觉一直去兜 SQL 有点整自己,
设定、一些字串什麽的小 cache 资料我建议用 SharePreference 存,
大块的资料用 db 也不适合,我建议你直接存档案。
除非是 list 型的资料或是你需要 select 协助你下一些条件,
不然 sql 我觉得是用不太到。
我的状况是我的案件列表会从伺服器 api 来,所以我不需要自己 host db ,
自己 host db 还要不断考虑跟 server sync 的问题,所以我不这麽做。
然後 SharePreference 因为是用 xml 作,资料一多时 commit 很花成本,
像我前面实做上传 task 时,一开始把 base64 字串直接塞进去,
commit 动辄就 4-5秒 (很蠢我知道 ,後来我改存档案路径。lol)。
@ 其他的
其实还有很多东西想写啦,但是越写越简略了我想写出来应该也没人看得懂,
能看到这行的我都算佩服你们了,啊哈哈哈。
写一点跟 ui 有关的:
---------------------------------
ProgrssDialog 可以帮你把整个画面转圈圈,让使用者不能动。
但是预设行为有一个行为很白痴是点圈圈外面就会取消 dialog 。
记得要 call setCanceledOnTouchOutside(false) 如果那不是你要得。
如果你只想要画面上有一个小圈圈转,而不是挡住整个画面,
你可以用 progressbar 这个元件
<ProgressBar
android:id="@+id/head_progress"
style="?android:attr/progressBarStyle"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical|center_horizontal"
android:indeterminate="false"
android:visibility="gone" />
/>
我自己的用法是要转就设 visibility 为 visible ,不转就设 gone。
---------------------------------
要写一个用两根手指就能 zoom-in zoom-out ,一根手指可以移动 ,
这麽看似简单功能的 imageview 其实是很难做的,
要自己 overwrite onTouch 跟一堆有的没的。
有一个作法好像是扔到 webview 去作,但是我没采用这个作法不确定成效。
我自己有手刻一个用 relative layout 跟 margin 刻的
zoom-in zoom-out / drag 的 image view。
(对,我就是把他当 web 跟 js 来写了......哈哈哈哈
但後来才发现他有 matrix 这个更聪明的机制。(泪奔))
https://gist.github.com/tony1223/5626327
自己刻得 ui 元件在 xml 定义起来用法是这样,
把 full classname 放到 tag 去就对了。
<com.mcall.view.ZoomImageView
android:id="@+id/image_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix" />
但是 zoom-in 会歪歪地,预设大小没处理好,
需要 parent 是 relative layout 都几点不太靠谱,
所以我一开始只是顶着应付需求先。=3=
後来我有参考某别人做的因盗版因素所以不在架上的 somecomic app 的 ui ,
另外刻一版新的(不过还是半成品,没空调整好。Orz)
你只要指定 imageview 的范围,他就会根据 imageview 的范围,
自己调整里面的 bitmap 在这范围内自由缩放、浏览。
https://gist.github.com/tony1223/5732622
效果可以参考我录得
https://www.youtube.com/watch?v=QpCxTSjSE4M
其实说半成品,是因为还有图片往左拖或往右超过一定范围就会触发事件,
可以用来做上一张或下一张,这一段我还没处理好现在还不会动,
不然他会是个蛮完整的 image view 。
等搞定会再发一个 github repo 出来放这个元件。Orz
写到这刚好七百行又花掉我三个小时,希望对有兴趣跳进来的朋友有帮助,
有兴趣再多聊聊的我们再另外讨论吧,就这样,掰。 XDDDDD
--
网页上拉近距离的帮手 实现 GMail丰富应用的功臣
数也数不清的友善使用者体验 这就是javascript
欢迎同好到 AJAX 板一同讨论。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 182.235.118.79
※ 编辑: TonyQ 来自: 182.235.118.79 (06/08 07:13)
1F:→ TonyQ:啊,没讲到 GCM ... 06/08 07:13
2F:→ TonyQ:算了先放着了,有空再写。Orz 06/08 07:13
3F:→ TonyQ:GCM 是可以透过 web server 发通知给 device 的一个机制, 06/08 07:14
4F:→ TonyQ:也就是 push-notification ,比起 polling 来讲省电很多。 06/08 07:14
5F:→ TonyQ:官方实作因为有 C2DM (旧) 跟 GCM (新) 所以文件非常混乱 06/08 07:24
6F:→ TonyQ:但机制其实很简单,就是文件新旧版本混杂让事情变得很复杂。 06/08 07:24
7F:→ TonyQ:如果大家要实作的话,直接看 GCM 相关的实作就行了。 06/08 07:24
8F:推 tangblack:好文 推 06/08 08:26
9F:推 coronach:XDD 推原PO自干控 其实现在开源LIB很多了... 06/08 08:32
10F:→ TonyQ:android 体系有没有像 maven 那样自动帮你 include 的工具啊 06/08 08:37
11F:→ TonyQ:不引开源 lib 有几个理由,1.版本支援 2.需求不好吻合 06/08 08:38
12F:→ TonyQ:3. 太肥会增加 apk 大小 06/08 08:38
13F:→ TonyQ:4. 放进专案麻烦 06/08 08:38
14F:推 qrtt1:新的都建议用 gradle 了 xd 06/08 09:00
15F:推 lovelycateye:推自干XD 不过我觉得4不是理由啊... 06/08 09:07
16F:推 asilzheng:好文 拜 06/08 11:55
17F:推 gpc:任何平台都很博大精深阿 06/08 12:24
18F:→ gpc:看看那精美的binder 06/08 12:24
19F:→ gpc:GCM听说会腿? 常常要等好一阵子 06/08 12:25
20F:推 tails32100:好文大推 >< 06/08 14:07
21F:推 y3k:推一个 很有心得XD 06/08 14:33
22F:→ Killercat:我觉得你的努力快要白费了 XD 因为这系统快被扬弃了 06/08 15:38
23F:→ Killercat:入场时间实在是太不巧了.... 06/08 15:38
24F:→ Killercat:喔我说的努力是指"熟悉IDE方面的努力" XD 06/08 15:38
25F:→ Killercat:另外service其实不难死 真的要不容易死的话 06/08 15:39
26F:→ Killercat:用IntentService 06/08 15:39
27F:→ Killercat:另外fragment... 先从改写被废弃的tab/tabhost较好理解 06/08 15:40
28F:推 Killercat:刚刚忘了推 补推这篇XD 06/08 15:42
29F:推 ian90911:推 06/08 16:29
30F:推 BBBroflovski:谢谢分享啊> < 06/08 17:07
31F:推 asadman1523:推~ 06/08 17:33
32F:→ TonyQ:GCM 我自己的心得是通常都一分钟内收到,但是因为我的 user 06/08 18:11
33F:→ TonyQ:数很少,所以可能不一定准。是说如果关闭 sync 的话好像不会 06/08 18:12
34F:→ TonyQ:发 所以要准备 fallback 策略,我预设是 polling ,只要有 06/08 18:12
35F:→ TonyQ:GCM 成功就自动采用 push-notification 。 06/08 18:12
36F:→ TonyQ:killercat 我是从 TabActivity 改成 Fragment 的,我很确定 06/08 18:13
37F:→ TonyQ:我懂 tab 跟 fragment 是怎麽回事,但是实务上真的很罗唆:Q 06/08 18:13
38F:→ TonyQ:Eclipse ADT 我觉得是没什麽差,我本来就是 Eclipse 很熟, 06/08 18:14
39F:→ TonyQ:而且短时间内 I 牌要进入战线还有得等。XD 06/08 18:14
40F:推 codemonkey:我觉得最难的是...自己刻类似iOS的UI出来........... 06/08 18:28
41F:→ codemonkey:所以我还没有去研究要怎麽刻... 06/08 18:29
42F:→ codemonkey:如果有GWT for Android就好罗 06/08 18:29
43F:→ Killercat:ouch 误会了 我不是说你不懂 XD 我是说 觉得fragment 06/08 18:39
44F:→ Killercat:难以理解的人 从tabhost 会比较快理解fragment怎麽弄XD 06/08 18:39
45F:→ Killercat:因为我自己也是一开始搞不懂fragment 从tab开始慢慢摸的 06/08 18:40
46F:→ Killercat:Eclipse最大的问题就是因为太全能所以泰肥大//sigh 06/08 18:40
47F:→ Killercat:跑得慢吃的记忆体多 我超不爱开的 XD 06/08 18:41
48F:→ TonyQ:没有觉得难以理解啊 我是觉得难用 XDDD 06/08 18:44
49F:→ TonyQ:其实 Eclipse 的重点就在於记忆体,记忆体多它其实很快的。 06/08 18:45
50F:→ TonyQ:lol 它会慢也是有理由的,这个理由我八月 java two 会介绍。 06/08 18:45
51F:推 milonga332:推 06/08 20:47
52F:→ y3k:新的那个IDE要起来绝对没这麽快 一堆问题待解 06/08 20:49
53F:→ y3k:我个人认为日蚀至少还会占据官方工具一两年以上甚至永远...XD 06/08 20:49
54F:推 jeffy84123:我不建议使用httpclient 虽然包的很好,但是我还是会用 06/08 21:04
56F:推 asadman1523:真的假的,我所有app都用httpclient QQ 06/09 03:21
57F:→ asadman1523:HttpURLConnection 为什麽比较省网路流量?看不太懂QQ 06/09 03:27
58F:推 KeySabre:推 06/09 07:48
59F:推 kewang:大推啊!!! 06/09 09:37
60F:推 pkmilk:推 06/09 11:09
61F:推 gpc:android app已经极限了 已经不是靠技术是靠其他的 06/09 17:20
62F:→ gpc:比方说不实广告 行销 再推广 (就跟某S牌的越越鸟一样) 06/09 17:20
63F:→ gpc:很多东西多人用的不见得好 而且市场已经顶了 其实一年前大概就 06/09 17:21
64F:→ gpc:就没有入场的时机了,反正ANDROID的APP最後就剩下行销罗 06/09 17:22
65F:→ gpc:行销不外乎是打广告 打击竞争对手 夸大 06/09 17:22
66F:→ gpc:我之前还有收到信,要我付点钱,可以帮我假造一系列优良评价 06/09 17:22
67F:→ gpc:还说会去各大论坛散拨postive comment的广告商XD 06/09 17:23
68F:→ gpc:以後可能会有不付他钱 就到处毁谤你的吧XD 06/09 17:24
69F:→ dreamcwli:毁谤那种已经有了 06/09 18:21
70F:推 VictorTom:推:) 06/09 19:25
71F:推 givemepass:这篇写得真好啊!!! 06/09 21:13
72F:推 howar31:TonyQ!! 啊啊这篇太好了!(详细阅读中 06/10 09:57
73F:推 WAYS22275:推推 06/10 10:31
74F:推 tga123:精辟! 06/10 13:38
75F:→ TonyQ:@gpc 就公司来讲,重点是 android app 能增加讯息传递跟订 06/10 13:55
76F:→ TonyQ:单,很多 app 不是靠购买赚钱啊。:P 06/10 13:55
77F:→ TonyQ:像是各种餐厅 POS 假设用 android client 或 iOS client 06/10 13:55
78F:→ TonyQ:那都不会因为现在市场状态而改变他的利益结果。 06/10 13:55
79F:→ TonyQ:我在写得 app 也是属於这种业务型 app。我相信这一块市场 06/10 13:55
80F:→ TonyQ:还是会有,当然 consumer 端的消费市场现在状况不太好是真的 06/10 13:56
81F:推 kaiyuegg:推!! 06/10 16:54
82F:推 loxyz:推 06/10 20:02
83F:推 vcidt:太棒了! 06/11 13:28
84F:推 popcorny:推!! 06/11 13:55
85F:推 gpc:客致化跟一班APP设计上还是有很大的距离 06/11 14:20
86F:推 nfsnfs:推 <(_ _)> 06/11 17:28
87F:推 tzk28419:一个月的新手看到这个真的很感动!虽然有一部份还没碰到 06/11 22:50
88F:推 inker610566:大推<(_ _)>网路好文极大成,不考虑出书吗XD 06/12 03:55
89F:→ TonyQ:写书这种事情留给其他有时间组织文章的人去做吧,我写文章 06/13 05:26
90F:→ TonyQ:还可以,组织文章不行。XD 06/13 05:26
91F:推 Brack:好文啊!!!! 怒推一波~ 07/22 22:26
92F:→ TonyQ:现在 androVM 的部份会改推 genymotion 了,安装效果好很多 08/05 11:10
93F:推 normanshi:写得真好@o@! 09/08 16:49
※ 编辑: TonyQ 来自: 118.166.159.253 (10/21 17:20)