GoogleAndroid智能手机开发培训————兰州大学合作计划郭国勇Derek.Guo.2009@gmail.comAndroid应用流程Android应用开发流程设计原型1、设计草稿2、Activity数布局文件数组件类型1、Activity、BroadcastReceiver、Service……控件选择1、是否重写模型设计1、adapter2、javabeen架构设计1、设计模式Android应用阅读流程运行从AndroidManifest-actionandroid:name=android.intent.action.MAIN/主Activity开始查找所有Activity,startActivity(ForResult)开始,往下递归查找……,找出各个页面之间的跳转关系,并注意各个Activity所用的布局文件从AndroidManifest查找service和BroadcastRecevier,了解系统的组件组成查找所有适配器adapter,这些往往是模型层的东西查看各个Activity所用的布局文件是否有重写的控件,有则可阅读之GoogleAndroid智能手机开发培训————兰州大学郭国勇Derek.Guo.2009@gmail.comBluetoothChatBluetoothChatBluetoothChatBluetoothChat类似应用程序之面向对象设计分析BluetoothAPI(1)BluetoothAdapter类1、BluetoothAdapter.getDefaultAdapter():得到本地默认的BluetoothAdapter,若返回为null则表示本地不支持蓝牙2、isDiscovering():返回设备是否正在发现周围蓝牙设备3、cancelDiscovery():取消正在发现远程蓝牙设备的过程4、startDiscovery():开始发现过程5、getScanMode():得到本地蓝牙设备的ScanMode6、getBondedDevices():得到已配对的设备7、isEnabled():蓝牙功能是否启用。BluetoothAPI(2)BluetoothDevice类:对应远程的蓝牙Device1、createRfcommSocketToServiceRecord():创建该Device的socketBluetoothSocket类1、connect():请求连接蓝牙2、getInputStream():得到输入流,用于接收远程方信息3、getOutputStream():得到输出流,发送给远程方的信息4、close():关闭蓝牙连接。InputStream类:1、read(byte[]):以阻塞方式读取输入流OutputStream类:2、write(byte[]):将信息写入该输出流,发送给远程BluetoothChat分析蓝牙相关权限声明:1、/**Allowsapplicationstodiscoverandpairbluetoothdevices*/uses-permissionandroid:name=android.permission.BLUETOOTH_ADMIN/2、/**Allowsapplicationstoconnecttopairedbluetoothdevices*/uses-permissionandroid:name=android.permission.BLUETOOTH/BluetoothChatService1、publicsynchronizedvoidstart()开启AcceptThread线程,在这之前先检测ConnectThread和ConnectedThread线程是否运行,运行则先退出这些线程,更新聊天状态为:STATE_LISTEN2、publicsynchronizedvoidconnect(BluetoothDevicedevice)取消CONNECTING和CONNECTED状态下的相关线程,然后运行新的ConnectThread线程,更新聊天状态为:STATE_CONNECTING3、publicsynchronizedvoidconnected(BluetoothSocketsocket,BluetoothDevicedevice)开启一个ConnectedThread来管理对应的当前连接。之前先取消任意现存的ConnectThread、ConnectedThread、AcceptThread线程,然后开启新的ConnectedThread线程,传入当前刚刚接受的socket连接,最后通过Handler来通知更新UI,并传递蓝牙设备名称:MESSAGE_DEVICE_NAME4、publicsynchronizedvoidstop()停止所有相关线程,设当前状态为STATE_NONE5、publicvoidwrite(byte[]out)在STATE_CONNECTED状态下,调用mConnectedThread里的write方法,写入byte6、privatevoidconnectionFailed()连接失败的时候处理,更新聊天状态为:STATE_LISTEN,通知更新UI,并传递MESSAGE_TOAST,“无法连接设备”7、privatevoidconnectionLost()当失去连接的时候处理,更新聊天状态为:STATE_LISTEN,通知更新UI,并传递MESSAGE_TOAST,“设备连接丢失”BluetoothChatService内部类1、privateclassAcceptThreadextendsThread监听线程,准备接受新连接。使用阻塞方式,调用BluetoothServerSocket.accept(),提供cancel方法关闭socket2、privateclassConnectThreadextendsThread连接线程,用于对外发出连接对方蓝牙的请求处理流程。构造函数里通过BluetoothDevice.createRfcommSocketToServiceRecord()从待连接的device产生BluetoothSocket,然后在run方法中进行connect(),如果出错,调用外部类的ConnectionFailed()进行处理,在关闭socket,并调用外部类的start()方法,重新启动监听线程;如果成功后,调用外部类的connected()方法,重新启动连接管理线程。同时,定义cancel()在关闭线程时能够关闭相关socket。3、privateclassConnectedThreadextendsThread双方蓝牙连接后运行的连接管理线程。构造函数中设置输入输出流。线程体中使用阻塞模式的InputStream.read()循环读取输入流,然后发送UI更新消息MESSAGE_READ,如出现异常,则调用外部类的connectionLost()进行失去连接处理。也提供了write()将聊天消息写入输出流传输至对方,并发送更新UI消息MESSAGE_WRITE。同时,提供了cancel()关闭连接的socket。BluetoothChat主ActivityonCreate()得到本地BluetoothAdapter设备,检查是否支持。onStart()中检查是否启用蓝牙,并请求启用,然后执setupChat()。setupChat()中先对界面中的控件进行初始化增加点击监听器等,然后创建BluetoothChatService对象,该对象在整个应用过程中存在,并管理蓝牙连接建立、消息发送接受等行为。DeviceListActivity得到系统默认蓝牙设备的已配对设备列表,并搜索出的未配对的新设备的列表。然后提供点击后发出连接设备请求的功能。BluetoothChat分析蓝牙功能未启用时,设置启用蓝牙:if(!mBluetoothAdapter.isEnabled()){IntentenableIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableIntent,REQUEST_ENABLE_BT);}当设备没有打开对外可见模式,则传递Intent来打开可发现模式:IntentdiscoverableIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);startActivity(discoverableIntent);GoogleAndroid智能手机开发培训————兰州大学郭国勇Derek.Guo.2009@gmail.comLZUNewsLZUNewsLZUNews解决方案:XML解析URI:解析SAX:SimpleAPIforXMLDOM:DocumentObjectModelSAXSAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否符合XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口中。ContentHandler接口常用方法startDocument()当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。endDocument()和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。startElement(StringnamespaceURI,StringlocalName,StringqName,Attributesatts)当读到一个开始标签的时候,会触发这个方法。namespaceURI就是命名空间,localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。要注意的是SAX中一个重要的特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下以前所碰到的标签,也就是说,在startElement()方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元属等等其它与结构相关的信息,都是不得而知的,都需要你的程序来完成。这使得SAX在编程处理上没有DOM来得那么方便。ContentHandler接口常用方法endElement(Stringuri,StringlocalName,Stringname)这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。characters(char[]ch,intstart,intlength)这个方法用来处理在XML文件中读到的内容,第一个参数用于存放文件的内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用newString(ch,start,length)就可以获取内容。DOM除了可以使用SAX解析XML文件,大家也可以使用熟悉的DOM来解析XML文件。DOM解析XML文件时,会将XML文件的所有内容读取到内存中,然后允许您使用DOMAPI遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来比较直观,并且,在某些方面比基于SAX的实现更加简单。但是,因为DOM需要将XML文件的所有内容读取到内存中,所以内存的消耗比较大,特别