版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
#10网络访问刘宁Email:liuning2@使用网络,应该有相应使用允许。文件AndroidManifest添加:网络访问<uses-permissionandroid:name="android.permission.INTERNET">
</uses-permission><uses-permissionandroid:name="android.permission.CHANGE_NETWORK_STATE">
</uses-permission>2超文本传输协议(HTTP,HyperTextTransferProtocol)是互联网上应用最为广泛的一种网络协议。最常见的从网络传输数据的方式就是使用HTTPHTTP可以封装几乎所有类型的数据一、访问因特网(HTTP)3从Web读取数据通过一个URL类来读取Web服务器上某个文件的定长部分适用于仅仅需要从一个Web站点读取一些数据的情况下,例如:当应用程序只需要一个轻量级、不太关键的网络特性一、访问因特网(HTTP)4从Web读取数据创建一个新的URL对象为这个URL资源打开一个stream读取数据关闭InputStream一、访问因特网(HTTP)URLtext=newURL("/st/index.html");InputStreamisText=text.openStream();byte[]bText=new
byte[250];
intreadSize=isText.read(bText);Log.i(“HTTP","readSize="+readSize);Log.i(“HTTP","bText="+newString(bText));isText.close();5从Web读取数据LogCat观察输出结果一、访问因特网(HTTP)URLtext=newURL("/st/index.html");InputStreamisText=text.openStream();byte[]bText=new
byte[250];
intreadSize=isText.read(bText);Log.i(“HTTP","readSize="+readSize);Log.i(“HTTP","bText="+newString(bText));isText.close();6从Web读取数据这种方法虽简单,但并不严谨没有很好的错误处理:如手机没有网络、服务器关闭、URL无效、用户操作超时因此,从一个URL读取数据值之前,往往需要了解更多的信息,例如,需要读取的数据到底有多大一、访问因特网(HTTP)7使用HttpURLConnection对URL进行侦查,避免错误地传输过多的数据HttpURLConnection获取一些有关URL对象所引用的资源信息如:HTTP状态、头信息、内容的长度、类型和日期时间等一、访问因特网(HTTP)8使用HttpURLConnection创建一个新的URL对象为这个URL资源打开一个stream读取数据关闭InputStream一、访问因特网(HTTP)
URLtext=new
URL(“/services/feeds/photos_public.gne?id=
26648248@N04&lang=en-us&format=atom");
HttpURLConnectionhttp=(HttpURLConnection)text.openConnection();
Log.i("HTTP","length="+http.getContentLength());Log.i("HTTP","respCode="+http.getResponseCode());Log.i("HTTP","contentType="+http.getContentType());Log.i("HTTP","content="+http.getContent());9使用HttpURLConnectionLogCat观察输出结果一、访问因特网(HTTP)
URLtext=new
URL(“/services/feeds/photos_public.gne?id=
26648248@N04&lang=en-us&format=atom");
HttpURLConnectionhttp=(HttpURLConnection)text.openConnection();
Log.i("HTTP","respCode="+http.getResponseCode());Log.i("HTTP","contentType="+http.getContentType());Log.i("HTTP","content="+http.getContent());10解析从网络获取的XML大部分网络资源的传输存储在一种结构化的形式中“可拓展标记语言(ExtensibleMarkupLanguage,XML)Android提供了一种快速而高效的XMLPullParse是网络应用程序解析器的首选一、访问因特网(HTTP)11解析从网络获取的XMLSTART_TAG:事件指定了一个XML标记的开始START_TAG:找到一个新的标记时(<tag>)返回TEXT:当找到文本时返回(即<tag>TEXT</tag>)END_TAG:找到标记的结束时(</tag>)返回END_DOCUMENT:当到达XML文件末尾时返回一、访问因特网(HTTP)12解析从网络获取的XML创建URL实例从XmlPullParserFactory中获取一个XmlPullParser实例一、访问因特网(HTTP)URLtext=newURL(“http://......");XmlPullParserFactoryparserCreator=xmlPullParserFactory.newInstance();XmlPullParserparser=parserCreator.newPullParser();parser.setInput(text.openStream(),null);status.setText("Parsing...");13解析从网络获取的XML若要寻找在<link>下,当rel=“enclosure”、
type=“image/*”,href中的值一、访问因特网(HTTP)14解析从网络获取的XML一、访问因特网(HTTP)intparserEvent=parser.getEventType();while(parserEvent!=XmlPullParser.END_DOCUMENT){switch(parserEvent){
caseXmlPullParser.START_TAG:Stringtag=parser.getName();
if(pareTo("link")==0){StringrelType=parser.getAttributeValue(null,"rel");
if(relTpareTo("enclosure")==0){StringencType=parser.getAttributeValue(null,"type");
if(encType.startsWith("image/")){StringimageSrc=parser.getAttributeValue(null,"href");Log.i(“HTTP","imagesource="+imageSrc);}}}
break;}parserEvent=parser.next();}15使用线程访问网络之前所提及到的网络操作方式会造成UI线程阻塞,直到网络操作完成为止把一些耗时的操作从UI线程中移开,重新开启一个新的工作线程来执行这些任务,带给用户流畅的体验一、访问因特网(HTTP)16Android线程模型
当第一次启动一个Android程序时,Android会自动创建一个称为“main”主线程的线程。这个主线程(也称为UI线程)负责把事件分派到相应的控件。例如,当你在屏幕上按下一个按钮后,UI线程会把这个事件分发给刚按的那个按钮,紧接着按钮设置它自身为被按下状态并向事件队列发送一个更新界面(invalidate)请求。UI线程会把这个请求移出事件队列并通知按钮在屏幕上重新绘制自身。
Android线程机制17Android线程模型
单线程模型常常会引起Android应用程序性能低下,因为所有的任务都在同一个线程中执行,如果执行一些耗时的操作,如访问网络或查询数据库,会阻塞整个用户界面。如果阻塞应用程序的时间过长(在Android系统中为5秒钟),Android会向用户提示一些信息,即打开一个“应用程序没有相应(applicationnotresponding)”的对话框。Android线程机制18Android线程模型
因此需要避免在UI线程中执行耗时的操作在后台线程或工作者线程中执行这些耗时的任务是否可以呢?请看以下代码:按钮的单击事件从网络上下载一副图片并使用ImageView来展现这幅图片。Android线程机制 public
voidonClick(Viewv){ newThread(newRunnable(){ public
voidrun(){Bitmapb=loadImageFromNetwork();mImageView.setImageBitmap(b);}}).start();}19Android线程模型
这段代码好像很好地解决了遇到的问题,因为它不会阻塞UI线程。然而运行时,Android会提示程序因为异常而终止。Why?!Android线程机制 public
voidonClick(Viewv){ newThread(newRunnable(){ public
voidrun(){Bitmapb=loadImageFromNetwork();mImageView.setImageBitmap(b);}}).start();}20Android线程模型
LogCat中打印的日志信息就会发现这样的错误日志:
android.view.ViewRoot$CalledFromWrongThreadException:Onlytheoriginalthreadthatcreatedaviewhierarchycantouchitsviews.
从错误信息不难看出Android禁止其他子线程来更新由UIthread创建的View。上述代码违背了Android单线程模型的原则:AndroidUI操作并不是线程安全的,并且这些操作必须在UI线程中执行。Android线程机制21Android线程模型
因此,Andriod提供了几种在其他线程中访问UI线程的方法。Android线程机制Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable,
long)
Handler
22Android线程模型
使用这些类和方法中的任何一种纠正前面的代码示例例如:把Runnable添加至消息队列,并由UI线程来处理Android线程机制public
void
onClick(View
v)
{
new
Thread(new
Runnable()
{
public
void
run()
{
final
Bitmap
b
=
loadImageFromNetwork();
mImageView.post(new
Runnable()
{
public
void
run()
{
mImageView.setImageBitmap(b);
}
});
}
}).start();
}
23Android线程模型---AsyncTask在Android1.5中,Android.os包引入了一个新的类,称为AsyncTask它是一个抽象的辅助类,用来管理后台操作,并最终返回到UI线程。开发人员创建一个AsyncTask的子类并实现相应的事件方法,这与为后台处理创建线程并使用消息机制更新UI不同Android线程机制24Android线程模型---AsyncTaskdoInBackground()方法会自动地在工作者线程中执行onPreExecute()、onPostExecute()和onProgressUpdate()方法会在UI线程中被调用doInBackground()方法的返回值会被传递给onPostExecute()方法在doInBackground()方法中你可以调用publishProgress()方法,每一次调用都会使UI线程执行一次onProgressUpdate()方法Android线程机制25Android线程模型---AsyncTask
Android线程机制
private
classImageLoaderextendsAsyncTask<URL,String,String>{
@Override
protectedStringdoInBackground(URL...params){try{URLtext=params[0];
//执行代码,如网络访问,结果解析等
publishProgress(“Test”);//调用onProgressUpdate}catch(Exceptione){Log.e("Net","Failed",e);
return
"Finishedwithfailure.";}
return
"Done...";}26Android线程模型---AsyncTask
Android线程机制
protected
voidonCancelled(){Log.e("Net","AsynctaskCancelled");}
protected
voidonPostExecute(Stringresult){
mStatus.setText(result);//result是doInBackground中
//return的值,本例中为”Done...”}
protected
voidonPreExecute(){
mStatus.setText("AbouttoloadURL");}
protected
voidonProgressUpdate(String...values){
mStatus.setText(values[0]);//values[0]为doInBackg中
//publishProgress(String)中的String
super.onProgressUpdate(values);}27使用线程访问网络新建线程一、访问因特网(HTTP)newThread(){
public
voidrun(){
try{
//执行网络连接代码以及解析代码
mHandler.post(newRunnable(){
public
voidrun(){//把有关用户界面更新的内容提交回主线程
}});}catch(Exceptione){//异常处理
}}}.start();28使用线程访问网络一、访问因特网(HTTP)newThread(){
public
voidrun(){
try{
//执行网络连接
mHandler.post(newRunnable(){
public
voidrun(){status.setText(“Parsing...");
}});
//执行解析代码
mHandler.post(newRunnable(){
public
voidrun(){status.setText(“Done...");
}});}catch(Exceptione){
//异常处理
}}}.start();29WebService是一种基于SOAP协议的远程调用标准。通过WebService可以将不同操作系统平台,不同语言、不同技术整合到一起。PC版本的WebService客户端类库非常丰富,例如,Axis2、CXF等,但这些类库对于Android系统过于庞大。适合手机的WebService客户端类库也有一些。比较常用的为Ksoap2。二、使用Ksoap2访问WebService30在AndroidSDK中并没有提供调用WebService的库,因此,需要使用第三方类库(Ksoap2)来调用WebService。Ksoap2是一个SOAPWebservice客户端包。主要用于资源受限制的Java环境如Applets或J2ME应用程序(CLDC/CDC/MIDP)。二、使用Ksoap2访问WebService31下载Ksoap2包
/p/ksoap2-android/
将下载后的jar文件复制到Eclipse工程的lib目录中(如果没有该目录,可以新建一个,当然,也可以放在其他的目录中),并在Eclipse工程中引用这个jar包。二、使用Ksoap2访问WebService32指定WebService的URL,命名空间和调用的方法名命名空间和调用方法可参考网站二、使用Ksoap2访问WebServiceStringurl="/WebServices/WeatherWebService.asmx";StringnameSpace="http://WebX/";StringmethodName="getSupportCity";/WebServices/WeatherWebService.asmx/WebServices/WeatherWebService.asmx?WSDL33从WSDL查看WebService的Namespace进入/WebServices/WeatherWebService.asmx?WSDL二、使用Ksoap2访问WebServicenameSpace34二、使用Ksoap2访问WebServicemethodName进入/WebServices/WeatherWebService.asmx
查看WebService提供的方法35设置调用方法的参数值,这一步是可选的,如果方法没有参数,可以省略这一步。设置方法的参数值的代码如下
addProperty方法的第1个参数虽然表示调用方法的参数名,但该参数值并不一定与服务端的WebService类中的方法参数名一致,只要设置参数的顺序一致即可。二、使用Ksoap2访问WebServiceSoapObject
request
=
new
SoapObject(nameSpace,
methodName);request.addProperty(“param1",
"value1");
request.addProperty("param2",
"value2");
36查看Method的输入输出参数进入/WebServices/WeatherWebService.asmx?op=getWeatherbyCityName
查看getWeatherbyCityName
二、使用Ksoap2访问WebServiceWebService读入参数格式定义WebService输出参数格式定义37二、使用Ksoap2访问WebService把读入的String赋给变量theCityNameSoapObject
request
=
new
SoapObject(nameSpace,
methodName);request.addProperty("theCityName",
"广州");
38生成调用WebService方法的SOAP请求信息。该信息由SoapSerializationEnvelope对象描述,代码如下:
创建SoapSerializationEnvelope对象时需要通过SoapSerializa
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025 奇妙的天气预报作文课件
- 2025 好玩的排球发球技巧进阶作文课件
- 交通局上半年工作总结及下半年计划(2篇)
- 某乡某年上半年工作总结及下半年工作思路(2篇)
- 数字化赋能:中沙社区财务报销系统的创新构建与实践
- 数字化赋能健康:居民健康与慢性病管理信息系统的设计与实践
- 数字化浪潮下资金结算系统的创新设计与高效实现路径探究
- 数字化浪潮下协鑫集团财务共享服务中心的转型与优化策略
- 数字化浪潮下中国旅游主管部门官方微博营销的破局与革新
- 2025 奇妙的光影艺术作文课件
- 洗涤红细胞输注规范与临床应用
- 2025年软件评测师考试详细试题及答案解析
- 房屋赠予女儿协议书
- 检察院相关试题及答案
- 《激光雷达技术概述》课件
- 学校广告制作合同协议
- GB/T 43982.11-2025地下供水管网非开挖修复用塑料管道系统第11部分:软管穿插内衬法
- 《温度传感器选型》课件
- 糖尿病酮症酸中毒纠正后-静脉胰岛素输注向皮下注射的转换技巧
- 医疗废物管理组织机构
- 2024年小学生托管管理制度(五篇)
评论
0/150
提交评论