2011-10-27

Android开发第一讲 - []

1.什么是Android。Android的体系结构介绍。

Android一词的英文意思是“机器人”它是Google公司于2007年11月宣布的基于Linux平台的开源手机操作系统,该平台由操作系统、中间件、用户界面和应用软件组成。Android体系结构从上到下分为应用程序,应用程序框架,各种库和Android运行环境,操作系统。

2.Android应用程序的组成。

一般来说Android程序主要有4部分组成:Activity、Broadcast Intent Receiver、Service、Content Provider。
(1)Activity介绍:Activity是应用程序中用到最多的也是最基本的模块之一。Activity代表手机屏幕的一屏。一个Android程序可以有多个Activity组成,每个Activity可以添加很多控件如:Button,TextView,ImageView等。Activity之间可以互相传递数据并且可以互相跳转。

(2)Broadcast Intent Receiver介绍:BroadcastReceiver可以让应用对一个外部事件做出响应。例如当一个电话呼入这个外部事件来的时候可以利用BroadcastReceiver来处理,或者当一个下载程序成功完成后也可以通过它来进行处理。BroadcastReceiver不能生产ui对用户来说是透明的,它可以通过NotificationManager来通知用户这些事情发生了。BroadcastReceiver既可以在AndroidManifest.xml里注册,也可以在运行时的代码中使用Context.registerReceiver()进行注册。各种应用还可以通过使用Context.sendBroadcast()将自己的intent Broadcasts广播给其他应用程序。

(3)Service介绍:service是一种程序,它可以运行很长时间,也没有用户界面。类似后台线程一样在后台运行着。例如一个音乐播放器程序在用户切换其他应用程序的时候还想继续播放音乐就可以使用Service在后台继续播放音乐。

(4)Content Provider介绍:程序之间可以通过ContentProvider来将数据暴露出去,

今天碰到一个怪问题,就是在使用listView的时候只要发生了滚动事件后首行和新出现的尾行在第一次点击事件后执行的结果是反着的。如果再点击一次第一行结果顺序就变成正确的了。即(点了第一行其实点了第末行,点第末行其实点了第一行这个错误)。刚开始以为是getView方法里的convertView缓冲视图出了问题,listview用缓冲的原理其实是这样的,当用户第一次初始化listview时候convertView是null的。当用户向上滚动视图第一行出了屏幕后,系统会缓冲第一行的item对象结构来复用加载出现的最下边的那行。当用户向下滚屏的时候这个缓冲行又跑到第一行的位置加载第0行了。这样就总有一个缓冲的行在首位之间转换加载。当然用户可以不用这个缓冲行即每次getView刷新都新new一个view使用。但这样效率肯定比使用缓冲低下。那么机制是这样的话那就是要把重复使用的这个缓冲行全新覆盖填充新行数据才能保证数据是正确的。可是我检查了这个逻辑是没问题的。每次都会重新设置新行数据即便是使用了缓冲行的结构。那就不是convertView的问题了。后来发现在2.1系统上没有这个问题,2.3.3上就会出现这个问题。难道真是系统问题?经过仔细考虑觉得也不是系统问题,肯定是代码那块有问题,后来发现是使用listview的时候实现了OnScrollListener监听在方法体里加了一句adapter.notifyDataSetChanged()。即在滚动列表手势离开屏幕后刷新数据。把这句取掉就没有问题了。就是说getView里已经对数据进行了刷新设置不需要在这个滚屏监听里再刷新adapter的数据了。onScrollStateChanged方法是会在getView之前调用的。用onScrollListener是为了慢加载list用的。只设置状态就可以了。没必要刷新list的数据。

昨天发现一个问题,是当我用ActivityGroup实现多activity跳转的时候用户按下back键直接从子activity退出应用,没有响应到activitygroup的onkeydown事件.其实可以在每个子activity覆写onkeydown事件弹出退出应用提示,但是就是想搞清楚为什么在子activity上按back就直接退出了而不响应到主activitygroup的onkeydown事件.如果可以响应,那么我们在主activityGroup里写一个退出提示框就可以了.这样不是可以省点代码吗.后来发现子activity是listview的时候里边的数据发生变化后就会先响应自己的onkeydown事件,如果子activity是非listview的可以直接响应到主activityGroup的onkeydown事件.(这里的前提是每个子activity都不覆写onkeydown事件只有activityGroup实现这个事件)后来查资料实验后给listview覆写onkeydown事件但是返回false.这样就可以将事件传递到主activityGroup里去响应了.总之比在子activity里覆写onkeydonw事件实现一堆逻辑要少一些代码的.子listview可以写:

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  if (keyCode == KeyEvent.KEYCODE_BACK) {
   return false;
  } else {
   return super.onKeyDown(keyCode, event);
  }
 }

主acitivtyGroup可以写:

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  if (keyCode == KeyEvent.KEYCODE_BACK) {
   quit();//自己实现的弹出提示框,这个大家都会就不详细写了.
   return true;
  } else {
   return super.onKeyDown(keyCode, event);
  }
 }

以下是我查到的资料,很有用.

键盘事件只会发送到当前获得焦点的View,这个KeyEvent只能被最上层获得焦点窗口的activityview得到。一般来说这些事件会从上倒下去寻找合适的接受组件,ViewGroup的一个childViewonKeyDown()方法return true,那么表示该方法消费了此次事件,此时不会再传递到ViewGrouponKeyDown()方法,如果onKeyDown()方法return false,那么表示该方法并未处理完全,该事件仍然需要以某种方式传递下去继续等待处理,这时传递到ActivityGrouponKeyDown()方法。但是KeyEvent.KEYCODE_MENU不会传递到ActivityGroup去。

一个ActivityGroup的键盘事件处理
按下按键时执行
首先执行ActivityGroup dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_DOWN)
然后执行ActivityGroup onUserInteraction
最后执行ActivityGroup onKeyDown

松开按键时执行
首先执行ActivityGroup dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_UP)
然后执行ActivityGroup onUserInteraction
最后执行ActivityGroup onKeyDown

如果childViewlistView,按上下键选择列表时的事件执行流程
按下键时
首先执行ActivityGroup dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_DOWN)
然后执行ActivityGroup onUserInteraction
然后执行childActivity dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_DOWN)
然后执行childActivity onUserInteraction  
松开键时
首先执行ActivityGroup dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_UP)
然后执行ActivityGroup onUserInteraction
然后执行childActivity dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_UP)
然后执行childActivity onUserInteraction
然后执行childActivity onKeyUp
最后执行ActivityGroup onKeyUp


如果焦点在childViewlistView上,按Menu键的事件
首先执行ActivityGroup dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_DOWN)
然后执行ActivityGroup onUserInteraction
然后执行childActivity dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_DOWN)
然后执行childActivity onUserInteraction  
最后执行childActivity onKeyDown
松开键时
首先执行ActivityGroup dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_UP)
然后执行ActivityGroup onUserInteraction
然后执行childActivity dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_UP)
然后执行childActivity onUserInteraction
然后执行childActivity onKeyUp


如果焦点在childViewlistView上,按Back键的事件
首先执行ActivityGroup dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_DOWN)
然后执行ActivityGroup onUserInteraction
然后执行childActivity dispatchKeyEvent (event.getAction()==KeyEvent.ACTION_DOWN)
然后执行childActivity onUserInteraction  
然后执行childActivity onKeyDown
最后执行ActivityGroup onKeyDown

  Activity.dispatchKeyEvent(MotionEvent) - 这允许你的活动可以在分发给窗口之前捕获所有的键盘事件。
 
由上面可知,当焦点在childViewlistView上时,没有执行ActivityGroup onKeyDown,而有执行ActivityGroupdispatchKeyEvent,因此可以在ActivityGroupdispatchKeyEvent来捕获childActivityMenu键事件

摘抄一个博友的文章,写的很好.基本和我的方法一致,推荐给大家来自己虚拟mac系统.只是有几点建议,如果按以下方法安装不成功可以多试几次,如果一直安装不上那有可能是你机器的配置和mac本本的配置相差太远.最好是硬件配置仿照mac mini的或者mac book等的配置再来装mac系统.否则很难装上,我也是试了好多遍才装成功的.前提是我的配置和mac mini的配置差不多.芯片也都一样.

iPhone现在越来越火爆了,很多原本在PC上的互联网应用都纷纷推出了iPhone客户端(比如携程,新浪微博),iPhone的最佳开发环境是mac OS + iphone真机,一般情况下这个有点难满足。(想起一句网络经典语言:用钱能解决的问题都不是问题,问题是TM没钱)


但是可以在windows环境(比如win7)中,通过虚拟机安装mac os来搭建环境,下面将讲解vmware下如何安装mac os 10.6(雪豹操作系统)。


1、准备工作,先到网上down下面这些软件

  a、 vmware7.1 (虚拟机软件)
  b、 darwin.iso 约24.8m (mac os系统的引导盘,没有这个无法进入安装,而且安装好以后,也需要这个引导才能进入mac os,迅雷上就能找到)
  c、 Mac.OSX.Snow.Leopard.v10.6.2(雪豹10.6)的DMG文件  约6.13G (迅雷或apple官网上就有)


2、安装vmware虚拟机

 

3、在虚拟机里创建一个FreeBSD 64-bit类型的虚拟机

因为vmware的操作系统选项里,并没有mac OS,所以只能选择最接近的FreeBSD 64-bit,然后一路next下去,注意:内存至少要分配1G,硬盘容量建议15G以上吧(因为后面开发工具+系统更新会占用很多的空间),另外在硬件配置里软驱可以去掉(没啥用),创建完成后退出vmware。

 

4、关键之一:上一步做完之后,会生成一个后缀名为vmx的文件,用记事本打开,找到下面这一行

guestOS = "freebsd-64" 改成 guestOS = "darwin10"

然后重新启动vmware,正常情况下,查看虚拟机的属性,应该会自动变成Mac OS X Server 10.6,如下图

如果这一步没成功,请检查前面的步骤

 

5、然后将darwin.iso挂到虚拟机的光驱,启动虚拟机

启动后,如果顺利会看到下面这个界面:

注:如果不能正常引导到该界面,可尝试将虚拟机power off关掉,然后重新开启

 

6、在虚拟机保持开启的状态下,切换光盘,把dmg文件挂到光驱上

方法:右击虚拟机名称-->setting--> CD/DVD -->Use ISO Image file-->Browse 默认情况下,看不到dmg文件,把下拉框改成"All files(*)"

选择mac os的dmg文件

注意:记得要勾选Connected!

点击ok,如果运气好的话,稍等一会儿,应该就能进入mac os的安装界面了

建议安装英文版(因为monoDeveloper跟monoTouch都是英文版的,光操作系统是中文其实意义也不大),剩下的事情地球人都知道了

 

7、安装完成以后,记得将光驱重新挂回darwin.iso,不然就算安装好了,也无法引导系统。

8、分辨率问题

默认情况下vmware中的mac os在偏好设置里,显示器的分辨率只有1024 * 768,玩不了全屏,这是因为没安装vmware tools,安装方法如下:

点击vmware最右下角的光盘图标,先把connect,然后在mac os 里就会看到光盘了,打开光盘,里面就能看到"install Vmware Tools.app",双击安装即可

安装完成后,就能随意切换分辨率了。

 

注:有某些本本上(比如thinkpad t61p),按文中的方法死活就是进入不了安装界面,多半是不兼容,这时可以在其它PC机器上按上面的方法安装好,然后将安装好以后的所有文件复制到本本上,在vmware中直接打开即可。

双击执行SDK Manager.exe启动sdk更新进程,等下载完成后会在android sdk文件夹下出现一个temp文件夹.这里边是刚下载的更新包,等待安装用的.点击安装后如果提示出现下图错误:

这时不要点击yes直接打开temp文件夹,里边有个ToolPackage.new0x的文件夹,文件夹里面的东西和tools里面的一样,只需要把原来sdk tools文件夹下的所有文件都删除然后用ToolPackage.new0x里的文件替换重新执行下更新程序就可以了.删除旧tools的时候提示有进程在使用lib下的资源可以跳过,不影响替换.

今天在Eclipse下调试j2me程序发现模拟器一闪就过,或者报奇妙的空指针异常。直接运行程序是没有问题的,肯定就是eclipse的配置问题。后来通过google发现确实如此:

用Eclipse无法调试J2ME程序,Eclipse配置方法如下:
菜单栏Window→Preferences→Java→Debug   去掉suspend execution on uncaught exceptions和Suspend execution on compilation errors前面两个勾勾,再把Debugger timeout(ms)设置为不少于15000ms
调试配置是通用的,只不过调试J2ME时会忘了罢啦!

经过千辛万苦终于让自己写的helloworld这我的iphone上跑起来了。这要谢谢卢师傅,贺师傅,和好多网友的帮助。先说说我的环境配置:mac mini 10.5.8系统   iphone 3.0.1系统   iphone sdk 3.1   xcode3.1.4。要在真机上调试注意以下几点:

1.首先你的iphone sdk版本需要高于你的iphone系统。

2.iphone必须是破解越狱后的,没越狱的手机是不能在中国大陆打电话的。如果你的手机可以正常使用并且可以安装盗版游戏那应该就是越狱后的。

3.xcode版本只是和mac系统版本有关,和真机调试没太大关系。只要能安装你的iphone sdk在模拟器里能跑程序就可以了。

4.需要别人帮你申请个开发者调试用证书。就是将你的机器uuid号挂在他的证书下,只可以真机调试程序不可以发布  程序。

5.双击下载后的证书developer_identity.pt12那个,导入你的mac。连接iphone后双击KdanMobile_Development.mobileprovision文件会自动打开xcode的organizer页面导入你的iphone里。

6.打开xcode后新建一个工程,在工程文件上点击右键选择get info打开工程配置文件,选择base sdk为你iphone的系统版本或者更低的版本,不能选择比自己iphone系统高的设备。Code Signing Identity选择你的证书。如果证书导入成功会出现你刚才那个证书。注意最上边的configuration选项一定要选择debug模式。然后在xcode下选择debug模式点build go。系统会自动上传程序到你的iphone。

7.如果你出现签名错误CodeSign error: code signing is required for product type 'Application' in SDK 'Device - iPhone OS 3.0'说明你选择的有可能不是debug模式而是release模式。前提是证书没问题,并且能在xcode的organizer里看到你iphone的applications选项和provision选项。

8如果你出现Could not translate messages from device,估计是你手机上已经有这个程序了。没删除干净或者是你当前程序修改了某个地方没改回来后先clean all然后再build and go。建议新建一个工程按上边说的去设置应该就可以了。


在安装android2.1sdk的时候从官方网站下了一个有setup的包.这个包是自动升级包,在安装之前必须将该升级包放在c盘,如果放在其他盘,在下载了最新的sdk文件后是不容许安装的.直接包文件夹修改错误.

在c盘进行安装需要修改google默认下载方式,在setting选项里勾选http方式下载.否则也是会报联网错误的.当下载完成后弹出可选包列表,如果开发游戏和软件的话最好是全选安装,如果只是看看新的模拟器可以只安装android 2.1那个包就行了.剩下的步骤就是一直next.安装完成后该安装文件夹就是你最新的sdk了.如果想放在其他盘也可以.直接在eclipse里指定当前文件夹就可以找到新的sdk了.

在android的列表中动态加载列表项需要对adapter里的源容器进行更新修改后再调用adapter.notifyViewChanaged()方法刷新当前listView.比如说:

        adapter = new SimpleAdapter(this, tempList,
          android.R.layout.simple_list_item_2, new String[] { Item.TITLE,Item.PUBDATE },
          new int[]{ android.R.id.text1 , android.R.id.text2});

 listView.setAdapter(adapter);

对adapter构造里的tempList进行修改后再调用adapter.notifyViewChanaged()就可以实现动态修改listView的内容了.如果想动态修改listView里字体的大小和相关布局的话,程序中验证adapter一旦构造后就不能再修改布局文件.可以通过重新构造adapter加入不同的布局文件来实现动态修改listView字体大小的目的.这样的缺点是需要多个描述listView列表布局的布局文件.好处是可以作为主题修改功能来用.

我自己制作的apk签名批处理文件给大家下载。方便大家签名自己的apk。将下边的指令做成一个bat文件即可。然后将要签名的文件和bat文件放在d:\sign\目录下(可以自己定义)。

@Rem android签名程序//注释指令

@Rem echo是显示指令 格式:echo [{on|off}] [message]
@echo **********************************************************
@echo android签名工具
@echo 作者:sld
@echo 日期:2010/3/11
@echo **********************************************************

@Rem 文件是否存在命令格式:if exist 路径+文件名 命令
@if exist d:\sign\android.keystore goto sign

@echo 创建签名文件android.keystore

@Rem keytool命令格式:-genkey产生签名 -alias别名 -keyalg加密算法 -validity有效天数 -keystore生产签名文件名称
keytool -genkey -alias android.keystore -keyalg RSA -validity 40000 -keystore android.keystore
@echo 开始签名:

@Rem jarsigner命令格式:-verbose输出详细信息 -keystore密钥库位置 -signedjar要生成的文件 要签名的文件 密钥库文件
jarsigner -verbose -keystore android.keystore -signedjar android_signed.apk android.apk android.keystore
@goto over

:sign
@echo 开始签名:
jarsigner -verbose -keystore android.keystore -signedjar android_signed.apk android.apk android.keystore

:over
@echo ********************android.apk 签名完成!************************
pause

共12页 1 2 3 4 5 6 7 8 9 10 下一页 最后一页