`

android执行网络操作

 
阅读更多



本篇我们会介绍连接到网络中涉及的基本任务,监测的网络连接(包括连接更改),并给予用户控制应用程序的网络使用情况。还介绍了如何解析和使用XML数据。

这个类包含一个示例应用程序来说明如何执行常见的网络操作。您可以下载示例(在右边),并用它作为自己的应用程序源代码的可重用代码。本章的重点有三:

1.连接到网络

2.管理网络的使用

3.解析XML数据

一、连接到网络

在mainfest中声明权限,代码如下:

Java代码
  1. <uses-permissionandroid:name="android.permission.INTERNET"/>
  2. <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>

选择http客户端

大多数联网的Android应用程序使用HTTP来发送和接收数据。Android包括两个HTTP客户:HttpURLConnection HttpClient和Apache。都支持HTTPS,流媒体上传和下载,可配置的超时,IPv6,和连接池。我们建议使用HttpURLConnection目标应用程序。

检查网络连接

在你的应用程序尝试连接到网络,它应该检查是否一个网络连接可用使用getActiveNetworkInfo()和一个()。记住,这个装置可能范围的一个网络,或用户可能已经禁用wi - fi和移动数据访问。

Java代码
  1. publicvoidmyClickHandler(Viewview){
  2. ...
  3. ConnectivityManagerconnMgr=(ConnectivityManager)
  4. getSystemService(Context.CONNECTIVITY_SERVICE);
  5. NetworkInfonetworkInfo=connMgr.getActiveNetworkInfo();
  6. if(networkInfo!=null&&networkInfo.isConnected()){
  7. //fetchdata
  8. }else{
  9. //displayerror
  10. }
  11. ...
  12. }

在单独线程中执行网络操作

网络操作可以包括不可预测的延迟。为了防止这种导致一个糟糕的用户体验,总是执行网络操作在一个单独的线程。

Java代码
  1. publicclassHttpExampleActivityextendsActivity{
  2. privatestaticfinalStringDEBUG_TAG="HttpExample";
  3. privateEditTexturlText;
  4. privateTextViewtextView;
  5. @Override
  6. publicvoidonCreate(BundlesavedInstanceState){
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.main);
  9. urlText=(EditText)findViewById(R.id.myUrl);
  10. textView=(TextView)findViewById(R.id.myText);
  11. }
  12. //Whenuserclicksbutton,callsAsyncTask.
  13. //BeforeattemptingtofetchtheURL,makessurethatthereisanetworkconnection.
  14. publicvoidmyClickHandler(Viewview){
  15. //GetstheURLfromtheUI'stextfield.
  16. StringstringUrl=urlText.getText().toString();
  17. ConnectivityManagerconnMgr=(ConnectivityManager)
  18. getSystemService(Context.CONNECTIVITY_SERVICE);
  19. NetworkInfonetworkInfo=connMgr.getActiveNetworkInfo();
  20. if(networkInfo!=null&&networkInfo.isConnected()){
  21. newDownloadWebpageText().execute(stringUrl);
  22. }else{
  23. textView.setText("Nonetworkconnectionavailable.");
  24. }
  25. }
  26. //UsesAsyncTasktocreateataskawayfromthemainUIthread.Thistasktakesa
  27. //URLstringandusesittocreateanHttpUrlConnection.Oncetheconnection
  28. //hasbeenestablished,theAsyncTaskdownloadsthecontentsofthewebpageas
  29. //anInputStream.Finally,theInputStreamisconvertedintoastring,whichis
  30. //displayedintheUIbytheAsyncTask'sonPostExecutemethod.
  31. privateclassDownloadWebpageTextextendsAsyncTask{
  32. @Override
  33. protectedStringdoInBackground(String...urls){
  34. //paramscomesfromtheexecute()call:params[0]istheurl.
  35. try{
  36. returndownloadUrl(urls[0]);
  37. }catch(IOExceptione){
  38. return"Unabletoretrievewebpage.URLmaybeinvalid.";
  39. }
  40. }
  41. //onPostExecutedisplaystheresultsoftheAsyncTask.
  42. @Override
  43. protectedvoidonPostExecute(Stringresult){
  44. textView.setText(result);
  45. }
  46. }
  47. ...
  48. }

连接和下载数据

在你的线程执行您的网络交易,你可以使用HttpURLConnection来执行一个GET和下载数据。在您调用connect(),你可以得到一个InputStream的数据通过调用getInputStream()。

Java代码
  1. //GivenaURL,establishesanHttpUrlConnectionandretrieves
  2. //thewebpagecontentasaInputStream,whichitreturnsas
  3. //astring.
  4. privateStringdownloadUrl(Stringmyurl)throwsIOException{
  5. InputStreamis=null;
  6. //Onlydisplaythefirst500charactersoftheretrieved
  7. //webpagecontent.
  8. intlen=500;
  9. try{
  10. URLurl=newURL(myurl);
  11. HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
  12. conn.setReadTimeout(10000/*milliseconds*/);
  13. conn.setConnectTimeout(15000/*milliseconds*/);
  14. conn.setRequestMethod("GET");
  15. conn.setDoInput(true);
  16. //Startsthequery
  17. conn.connect();
  18. intresponse=conn.getResponseCode();
  19. Log.d(DEBUG_TAG,"Theresponseis:"+response);
  20. is=conn.getInputStream();
  21. //ConverttheInputStreamintoastring
  22. StringcontentAsString=readIt(is,len);
  23. returncontentAsString;
  24. //MakessurethattheInputStreamisclosedaftertheappis
  25. //finishedusingit.
  26. }finally{
  27. if(is!=null){
  28. is.close();
  29. }
  30. }
  31. }

getResponseCode()返回连接的状态码。这是一种有用的方式获得一些额外的信息的连接。一个200的状态代码表示成功。

转换InputStreamString

Java代码
  1. //ReadsanInputStreamandconvertsittoaString.
  2. publicStringreadIt(InputStreamstream,intlen)throwsIOException,UnsupportedEncodingException{
  3. Readerreader=null;
  4. reader=newInputStreamReader(stream,"UTF-8");
  5. char[]buffer=newchar[len];
  6. reader.read(buffer);
  7. returnnewString(buffer);
  8. }

二、管理网络

检查设备的网络连接

一个设备可以有各种类型的网络连接。这节课的重点是使用wi - fi或手机或网络连接,这个代码片段测试网络连接wi - fi和移动。它确定这些网络接口是可用的或连接的(即网络连接是否存在,如果可以建立套接字和传递数据)

Java代码
  1. privatestaticfinalStringDEBUG_TAG="NetworkStatusExample";
  2. ...
  3. ConnectivityManagerconnMgr=(ConnectivityManager)
  4. getSystemService(Context.CONNECTIVITY_SERVICE);
  5. NetworkInfonetworkInfo=connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
  6. booleanisWifiConn=networkInfo.isConnected();
  7. networkInfo=connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
  8. booleanisMobileConn=networkInfo.isConnected();
  9. Log.d(DEBUG_TAG,"Wificonnected:"+isWifiConn);
  10. Log.d(DEBUG_TAG,"Mobileconnected:"+isMobileConn);

管理网络的使用

您可以实现一个首选项活动,让用户明确控制应用程序的使用网络资源。例如:1.你可能允许用户上传的视频只有当设备被连接到wi - fi网络。2.你可能会同步(或没有)根据特定标准如网络可用性、时间间隔,等等。

编写一个应用程序,支持网络访问和管理网络的使用,你的清单必须有正确的权限和意图过滤器。

在样例应用程序中,这个规定了SettingsActivity,将显示一个UI让用户知道何时可以进行下载操作。

Xml代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.example.android.networkusage"
  4. ...>
  5. <uses-sdkandroid:minSdkVersion="4"
  6. android:targetSdkVersion="14"/>
  7. <uses-permissionandroid:name="android.permission.INTERNET"/>
  8. <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
  9. <application
  10. ...>
  11. ...
  12. <activityandroid:label="SettingsActivity"android:name=".SettingsActivity">
  13. <intent-filter>
  14. <actionandroid:name="android.intent.action.MANAGE_NETWORK_USAGE"/>
  15. <categoryandroid:name="android.intent.category.DEFAULT"/>
  16. </intent-filter>
  17. </activity>
  18. </application>
  19. </manifest>

Java代码
  1. publicclassSettingsActivityextendsPreferenceActivityimplementsOnSharedPreferenceChangeListener{
  2. @Override
  3. protectedvoidonCreate(BundlesavedInstanceState){
  4. super.onCreate(savedInstanceState);
  5. //LoadstheXMLpreferencesfile
  6. addPreferencesFromResource(R.xml.preferences);
  7. }
  8. @Override
  9. protectedvoidonResume(){
  10. super.onResume();
  11. //Registersalistenerwheneverakeychanges
  12. getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
  13. }
  14. @Override
  15. protectedvoidonPause(){
  16. super.onPause();
  17. //UnregistersthelistenersetinonResume().
  18. //It'sbestpracticetounregisterlistenerswhenyourappisn'tusingthemtocutdownon
  19. //unnecessarysystemoverhead.YoudothisinonPause().
  20. getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
  21. }
  22. //Whentheuserchangesthepreferencesselection,
  23. //onSharedPreferenceChanged()restartsthemainactivityasanew
  24. //task.SetsthetherefreshDisplayflagto"true"toindicatethat
  25. //themainactivityshouldupdateitsdisplay.
  26. //ThemainactivityqueriesthePreferenceManagertogetthelatestsettings.
  27. @Override
  28. publicvoidonSharedPreferenceChanged(SharedPreferencessharedPreferences,Stringkey){
  29. //SetsrefreshDisplaytotruesothatwhentheuserreturnstothemain
  30. //activity,thedisplayrefreshestoreflectthenewsettings.
  31. NetworkActivity.refreshDisplay=true;
  32. }
  33. }

响应网络变动

如果有一个匹配发生在设置和设备的网络连接(例如,如果设置为“wi - fi”和设备有一个wi - fi连接)之间,应用程序下载提继续并刷新显示

Java代码
  1. publicclassNetworkActivityextendsActivity{
  2. publicstaticfinalStringWIFI="Wi-Fi";
  3. publicstaticfinalStringANY="Any";
  4. privatestaticfinalStringURL="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";
  5. //WhetherthereisaWi-Ficonnection.
  6. privatestaticbooleanwifiConnected=false;
  7. //Whetherthereisamobileconnection.
  8. privatestaticbooleanmobileConnected=false;
  9. //Whetherthedisplayshouldberefreshed.
  10. publicstaticbooleanrefreshDisplay=true;
  11. //Theuser'scurrentnetworkpreferencesetting.
  12. publicstaticStringsPref=null;
  13. //TheBroadcastReceiverthattracksnetworkconnectivitychanges.
  14. privateNetworkReceiverreceiver=newNetworkReceiver();
  15. @Override
  16. publicvoidonCreate(BundlesavedInstanceState){
  17. super.onCreate(savedInstanceState);
  18. //RegistersBroadcastReceivertotracknetworkconnectionchanges.
  19. IntentFilterfilter=newIntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
  20. receiver=newNetworkReceiver();
  21. this.registerReceiver(receiver,filter);
  22. }
  23. @Override
  24. publicvoidonDestroy(){
  25. super.onDestroy();
  26. //UnregistersBroadcastReceiverwhenappisdestroyed.
  27. if(receiver!=null){
  28. this.unregisterReceiver(receiver);
  29. }
  30. }
  31. //Refreshesthedisplayifthenetworkconnectionandthe
  32. //prefsettingsallowit.
  33. @Override
  34. publicvoidonStart(){
  35. super.onStart();
  36. //Getstheuser'snetworkpreferencesettings
  37. SharedPreferencessharedPrefs=PreferenceManager.getDefaultSharedPreferences(this);
  38. //Retrievesastringvalueforthepreferences.Thesecondparameter
  39. //isthedefaultvaluetouseifapreferencevalueisnotfound.
  40. sPref=sharedPrefs.getString("listPref","Wi-Fi");
  41. updateConnectedFlags();
  42. if(refreshDisplay){
  43. loadPage();
  44. }
  45. }
  46. //ChecksthenetworkconnectionandsetsthewifiConnectedandmobileConnected
  47. //variablesaccordingly.
  48. publicvoidupdateConnectedFlags(){
  49. ConnectivityManagerconnMgr=(ConnectivityManager)
  50. getSystemService(Context.CONNECTIVITY_SERVICE);
  51. NetworkInfoactiveInfo=connMgr.getActiveNetworkInfo();
  52. if(activeInfo!=null&&activeInfo.isConnected()){
  53. wifiConnected=activeInfo.getType()==ConnectivityManager.TYPE_WIFI;
  54. mobileConnected=activeInfo.getType()==ConnectivityManager.TYPE_MOBILE;
  55. }else{
  56. wifiConnected=false;
  57. mobileConnected=false;
  58. }
  59. }
  60. //UsesAsyncTasksubclasstodownloadtheXMLfeedfromstackoverflow.com.
  61. publicvoidloadPage(){
  62. if(((sPref.equals(ANY))&&(wifiConnected||mobileConnected))
  63. ||((sPref.equals(WIFI))&&(wifiConnected))){
  64. //AsyncTasksubclass
  65. newDownloadXmlTask().execute(URL);
  66. }else{
  67. showErrorPage();
  68. }
  69. }
  70. ...
  71. }

检测网络连接变化

Java代码
  1. publicclassNetworkReceiverextendsBroadcastReceiver{
  2. @Override
  3. publicvoidonReceive(Contextcontext,Intentintent){
  4. ConnectivityManagerconn=(ConnectivityManager)
  5. context.getSystemService(Context.CONNECTIVITY_SERVICE);
  6. NetworkInfonetworkInfo=conn.getActiveNetworkInfo();
  7. //Checkstheuserprefsandthenetworkconnection.Basedontheresult,decideswhether
  8. //torefreshthedisplayorkeepthecurrentdisplay.
  9. //IftheuserprefisWi-Fionly,checkstoseeifthedevicehasaWi-Ficonnection.
  10. if(WIFI.equals(sPref)&&networkInfo!=null&&networkInfo.getType()==ConnectivityManager.TYPE_WIFI){
  11. //IfdevicehasitsWi-Ficonnection,setsrefreshDisplay
  12. //totrue.Thiscausesthedisplaytoberefreshedwhentheuser
  13. //returnstotheapp.
  14. refreshDisplay=true;
  15. Toast.makeText(context,R.string.wifi_connected,Toast.LENGTH_SHORT).show();
  16. //IfthesettingisANYnetworkandthereisanetworkconnection
  17. //(whichbyprocessofeliminationwouldbemobile),setsrefreshDisplaytotrue.
  18. }elseif(ANY.equals(sPref)&&networkInfo!=null){
  19. refreshDisplay=true;
  20. //Otherwise,theappcan'tdownloadcontent--eitherbecausethereisnonetwork
  21. //connection(mobileorWi-Fi),orbecausetheprefsettingisWIFI,andthere
  22. //isnoWi-Ficonnection.
  23. //SetsrefreshDisplaytofalse.
  24. }else{
  25. refreshDisplay=false;
  26. Toast.makeText(context,R.string.lost_connection,Toast.LENGTH_SHORT).show();
  27. }
  28. }

三、解析xml

上传和解析XML数据是很常见的任务,网络连接应用程序。这一课解释了如何解析XML文档并使用他们的数据

选择转换器

我们建议XmlPullParser,这是一种高效且可维护的方式来解析XML在Android里。

分析需求

Xml代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <feedxmlns="http://www.w3.org/2005/Atom"xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"...">
  3. <titletype="text">newestquestionstaggedandroid-StackOverflow</title>
  4. ...
  5. <entry>
  6. ...
  7. </entry>
  8. <entry>
  9. <id>http://stackoverflow.com/q/9439999</id>
  10. <re:rankscheme="http://stackoverflow.com">0</re:rank>
  11. <titletype="text">Whereismydatafile?</title>
  12. <categoryscheme="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest/tags"term="android"/>
  13. <categoryscheme="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest/tags"term="file"/>
  14. <author>
  15. <name>cliff2310</name>
  16. <uri>http://stackoverflow.com/users/1128925</uri>
  17. </author>
  18. <linkrel="alternate"href="http://stackoverflow.com/questions/9439999/where-is-my-data-file"/>
  19. <published>2012-02-25T00:30:54Z</published>
  20. <updated>2012-02-25T00:30:54Z</updated>
  21. <summarytype="html">
  22. <p>IhaveanApplicationthatrequiresadatafile...</p>
  23. </summary>
  24. </entry>
  25. <entry>
  26. ...
  27. </entry>
  28. ...
  29. </feed>

实例化转化器

Java代码
  1. publicclassStackOverflowXmlParser{
  2. //Wedon'tusenamespaces
  3. privatestaticfinalStringns=null;
  4. publicListparse(InputStreamin)throwsXmlPullParserException,IOException{
  5. try{
  6. XmlPullParserparser=Xml.newPullParser();
  7. parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,false);
  8. parser.setInput(in,null);
  9. parser.nextTag();
  10. returnreadFeed(parser);
  11. }finally{
  12. in.close();
  13. }
  14. }
  15. ...
  16. }
  17. 读取xml
  18. privateListreadFeed(XmlPullParserparser)throwsXmlPullParserException,IOException{
  19. Listentries=newArrayList();
  20. parser.require(XmlPullParser.START_TAG,ns,"feed");
  21. while(parser.next()!=XmlPullParser.END_TAG){
  22. if(parser.getEventType()!=XmlPullParser.START_TAG){
  23. continue;
  24. }
  25. Stringname=parser.getName();
  26. //Startsbylookingfortheentrytag
  27. if(name.equals("entry")){
  28. entries.add(readEntry(parser));
  29. }else{
  30. skip(parser);
  31. }
  32. }
  33. returnentries;
  34. }

下面这个代码片段展示了如何解析器解析条目、标题、链接和总结:

Java代码
  1. publicstaticclassEntry{
  2. publicfinalStringtitle;
  3. publicfinalStringlink;
  4. publicfinalStringsummary;
  5. privateEntry(Stringtitle,Stringsummary,Stringlink){
  6. this.title=title;
  7. this.summary=summary;
  8. this.link=link;
  9. }
  10. }
  11. //Parsesthecontentsofanentry.Ifitencountersatitle,summary,orlinktag,handsthemoff
  12. //totheirrespective"read"methodsforprocessing.Otherwise,skipsthetag.
  13. privateEntryreadEntry(XmlPullParserparser)throwsXmlPullParserException,IOException{
  14. parser.require(XmlPullParser.START_TAG,ns,"entry");
  15. Stringtitle=null;
  16. Stringsummary=null;
  17. Stringlink=null;
  18. while(parser.next()!=XmlPullParser.END_TAG){
  19. if(parser.getEventType()!=XmlPullParser.START_TAG){
  20. continue;
  21. }
  22. Stringname=parser.getName();
  23. if(name.equals("title")){
  24. title=readTitle(parser);
  25. }elseif(name.equals("summary")){
  26. summary=readSummary(parser);
  27. }elseif(name.equals("link")){
  28. link=readLink(parser);
  29. }else{
  30. skip(parser);
  31. }
  32. }
  33. returnnewEntry(title,summary,link);
  34. }
  35. //Processestitletagsinthefeed.
  36. privateStringreadTitle(XmlPullParserparser)throwsIOException,XmlPullParserException{
  37. parser.require(XmlPullParser.START_TAG,ns,"title");
  38. Stringtitle=readText(parser);
  39. parser.require(XmlPullParser.END_TAG,ns,"title");
  40. returntitle;
  41. }
  42. //Processeslinktagsinthefeed.
  43. privateStringreadLink(XmlPullParserparser)throwsIOException,XmlPullParserException{
  44. Stringlink="";
  45. parser.require(XmlPullParser.START_TAG,ns,"link");
  46. Stringtag=parser.getName();
  47. StringrelType=parser.getAttributeValue(null,"rel");
  48. if(tag.equals("link")){
  49. if(relType.equals("alternate")){
  50. link=parser.getAttributeValue(null,"href");
  51. parser.nextTag();
  52. }
  53. }
  54. parser.require(XmlPullParser.END_TAG,ns,"link");
  55. returnlink;
  56. }
  57. //Processessummarytagsinthefeed.
  58. privateStringreadSummary(XmlPullParserparser)throwsIOException,XmlPullParserException{
  59. parser.require(XmlPullParser.START_TAG,ns,"summary");
  60. Stringsummary=readText(parser);
  61. parser.require(XmlPullParser.END_TAG,ns,"summary");
  62. returnsummary;
  63. }
  64. //Forthetagstitleandsummary,extractstheirtextvalues.
  65. privateStringreadText(XmlPullParserparser)throwsIOException,XmlPullParserException{
  66. Stringresult="";
  67. if(parser.next()==XmlPullParser.TEXT){
  68. result=parser.getText();
  69. parser.nextTag();
  70. }
  71. returnresult;
  72. }
  73. ...
  74. }

跳过无用的标签

Java代码
  1. privatevoidskip(XmlPullParserparser)throwsXmlPullParserException,IOException{
  2. if(parser.getEventType()!=XmlPullParser.START_TAG){
  3. thrownewIllegalStateException();
  4. }
  5. intdepth=1;
  6. while(depth!=0){
  7. switch(parser.next()){
  8. caseXmlPullParser.END_TAG:
  9. depth--;
  10. break;
  11. caseXmlPullParser.START_TAG:
  12. depth++;
  13. break;
  14. }
  15. }
  16. }

使用xml数据

Java代码
  1. publicclassNetworkActivityextendsActivity{
  2. publicstaticfinalStringWIFI="Wi-Fi";
  3. publicstaticfinalStringANY="Any";
  4. privatestaticfinalStringURL="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";
  5. //WhetherthereisaWi-Ficonnection.
  6. privatestaticbooleanwifiConnected=false;
  7. //Whetherthereisamobileconnection.
  8. privatestaticbooleanmobileConnected=false;
  9. //Whetherthedisplayshouldberefreshed.
  10. publicstaticbooleanrefreshDisplay=true;
  11. publicstaticStringsPref=null;
  12. ...
  13. //UsesAsyncTasktodownloadtheXMLfeedfromstackoverflow.com.
  14. publicvoidloadPage(){
  15. if((sPref.equals(ANY))&&(wifiConnected||mobileConnected)){
  16. newDownloadXmlTask().execute(URL);
  17. }
  18. elseif((sPref.equals(WIFI))&&(wifiConnected)){
  19. newDownloadXmlTask().execute(URL);
  20. }else{
  21. //showerror
  22. }
  23. }

动态下载xml

Java代码
  1. //ImplementationofAsyncTaskusedtodownloadXMLfeedfromstackoverflow.com.
  2. privateclassDownloadXmlTaskextendsAsyncTask<String,Void,String>{
  3. @Override
  4. protectedStringdoInBackground(String...urls){
  5. try{
  6. returnloadXmlFromNetwork(urls[0]);
  7. }catch(IOExceptione){
  8. returngetResources().getString(R.string.connection_error);
  9. }catch(XmlPullParserExceptione){
  10. returngetResources().getString(R.string.xml_error);
  11. }
  12. }
  13. @Override
  14. protectedvoidonPostExecute(Stringresult){
  15. setContentView(R.layout.main);
  16. //DisplaystheHTMLstringintheUIviaaWebView
  17. WebViewmyWebView=(WebView)findViewById(R.id.webview);
  18. myWebView.loadData(result,"text/html",null);
  19. }
  20. }

加载xml

Java代码
  1. //UploadsXMLfromstackoverflow.com,parsesit,andcombinesitwith
  2. //HTMLmarkup.ReturnsHTMLstring.
  3. privateStringloadXmlFromNetwork(StringurlString)throwsXmlPullParserException,IOException{
  4. InputStreamstream=null;
  5. //Instantiatetheparser
  6. StackOverflowXmlParserstackOverflowXmlParser=newStackOverflowXmlParser();
  7. List<Entry>entries=null;
  8. Stringtitle=null;
  9. Stringurl=null;
  10. Stringsummary=null;
  11. CalendarrightNow=Calendar.getInstance();
  12. DateFormatformatter=newSimpleDateFormat("MMMddh:mmaa");
  13. //Checkswhethertheusersetthepreferencetoincludesummarytext
  14. SharedPreferencessharedPrefs=PreferenceManager.getDefaultSharedPreferences(this);
  15. booleanpref=sharedPrefs.getBoolean("summaryPref",false);
  16. StringBuilderhtmlString=newStringBuilder();
  17. htmlString.append("<h3>"+getResources().getString(R.string.page_title)+"</h3>");
  18. htmlString.append("<em>"+getResources().getString(R.string.updated)+""+
  19. formatter.format(rightNow.getTime())+"</em>");
  20. try{
  21. stream=downloadUrl(urlString);
  22. entries=stackOverflowXmlParser.parse(stream);
  23. //MakessurethattheInputStreamisclosedaftertheappis
  24. //finishedusingit.
  25. }finally{
  26. if(stream!=null){
  27. stream.close();
  28. }
  29. }
  30. //StackOverflowXmlParserreturnsaList(called"entries")ofEntryobjects.
  31. //EachEntryobjectrepresentsasinglepostintheXMLfeed.
  32. //ThissectionprocessestheentrieslisttocombineeachentrywithHTMLmarkup.
  33. //EachentryisdisplayedintheUIasalinkthatoptionallyincludes
  34. //atextsummary.
  35. for(Entryentry:entries){
  36. htmlString.append("<p><ahref='");
  37. htmlString.append(entry.link);
  38. htmlString.append("'>"+entry.title+"</a></p>");
  39. //Iftheusersetthepreferencetoincludesummarytext,
  40. //addsittothedisplay.
  41. if(pref){
  42. htmlString.append(entry.summary);
  43. }
  44. }
  45. returnhtmlString.toString();
  46. }
  47. //GivenastringrepresentationofaURL,setsupaconnectionandgets
  48. //aninputstream.
  49. privateInputStreamdownloadUrl(StringurlString)throwsIOException{
  50. URLurl=newURL(urlString);
  51. HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
  52. conn.setReadTimeout(10000/*milliseconds*/);
  53. conn.setConnectTimeout(15000/*milliseconds*/);
  54. conn.setRequestMethod("GET");
  55. conn.setDoInput(true);
  56. //Startsthequery
  57. conn.connect();
  58. InputStreamstream=conn.getInputStream();
  59. }

上面的片段代码为了帮助大家理解,这里还是老习惯,贴上项目的源代码,本来是有项目截图,运行效果图之类的图的,只是这篇文章太长了,再弄图片,就更占篇幅了,所以就只贴源码了,大家可以自己的运行起来看看,希望能从整体的架构和具体的代码细节上帮助到大家。

本篇我们会介绍连接到网络中涉及的基本任务,监测的网络连接(包括连接更改),并给予用户控制应用程序的网络使用情况。还介绍了如何解析和使用XML数据。

这个类包含一个示例应用程序来说明如何执行常见的网络操作。您可以下载示例(在右边),并用它作为自己的应用程序源代码的可重用代码。本章的重点有三:

1.连接到网络

2.管理网络的使用

3.解析XML数据

一、连接到网络

在mainfest中声明权限,代码如下:

Java代码
  1. <uses-permissionandroid:name="android.permission.INTERNET"/>
  2. <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>

选择http客户端

大多数联网的Android应用程序使用HTTP来发送和接收数据。Android包括两个HTTP客户:HttpURLConnection HttpClient和Apache。都支持HTTPS,流媒体上传和下载,可配置的超时,IPv6,和连接池。我们建议使用HttpURLConnection目标应用程序。

检查网络连接

在你的应用程序尝试连接到网络,它应该检查是否一个网络连接可用使用getActiveNetworkInfo()和一个()。记住,这个装置可能范围的一个网络,或用户可能已经禁用wi - fi和移动数据访问。

Java代码
  1. publicvoidmyClickHandler(Viewview){
  2. ...
  3. ConnectivityManagerconnMgr=(ConnectivityManager)
  4. getSystemService(Context.CONNECTIVITY_SERVICE);
  5. NetworkInfonetworkInfo=connMgr.getActiveNetworkInfo();
  6. if(networkInfo!=null&&networkInfo.isConnected()){
  7. //fetchdata
  8. }else{
  9. //displayerror
  10. }
  11. ...
  12. }

在单独线程中执行网络操作

网络操作可以包括不可预测的延迟。为了防止这种导致一个糟糕的用户体验,总是执行网络操作在一个单独的线程。

Java代码
  1. publicclassHttpExampleActivityextendsActivity{
  2. privatestaticfinalStringDEBUG_TAG="HttpExample";
  3. privateEditTexturlText;
  4. privateTextViewtextView;
  5. @Override
  6. publicvoidonCreate(BundlesavedInstanceState){
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.main);
  9. urlText=(EditText)findViewById(R.id.myUrl);
  10. textView=(TextView)findViewById(R.id.myText);
  11. }
  12. //Whenuserclicksbutton,callsAsyncTask.
  13. //BeforeattemptingtofetchtheURL,makessurethatthereisanetworkconnection.
  14. publicvoidmyClickHandler(Viewview){
  15. //GetstheURLfromtheUI'stextfield.
  16. StringstringUrl=urlText.getText().toString();
  17. ConnectivityManagerconnMgr=(ConnectivityManager)
  18. getSystemService(Context.CONNECTIVITY_SERVICE);
  19. NetworkInfonetworkInfo=connMgr.getActiveNetworkInfo();
  20. if(networkInfo!=null&&networkInfo.isConnected()){
  21. newDownloadWebpageText().execute(stringUrl);
  22. }else{
  23. textView.setText("Nonetworkconnectionavailable.");
  24. }
  25. }
  26. //UsesAsyncTasktocreateataskawayfromthemainUIthread.Thistasktakesa
  27. //URLstringandusesittocreateanHttpUrlConnection.Oncetheconnection
  28. //hasbeenestablished,theAsyncTaskdownloadsthecontentsofthewebpageas
  29. //anInputStream.Finally,theInputStreamisconvertedintoastring,whichis
  30. //displayedintheUIbytheAsyncTask'sonPostExecutemethod.
  31. privateclassDownloadWebpageTextextendsAsyncTask{
  32. @Override
  33. protectedStringdoInBackground(String...urls){
  34. //paramscomesfromtheexecute()call:params[0]istheurl.
  35. try{
  36. returndownloadUrl(urls[0]);
  37. }catch(IOExceptione){
  38. return"Unabletoretrievewebpage.URLmaybeinvalid.";
  39. }
  40. }
  41. //onPostExecutedisplaystheresultsoftheAsyncTask.
  42. @Override
  43. protectedvoidonPostExecute(Stringresult){
  44. textView.setText(result);
  45. }
  46. }
  47. ...
  48. }

连接和下载数据

在你的线程执行您的网络交易,你可以使用HttpURLConnection来执行一个GET和下载数据。在您调用connect(),你可以得到一个InputStream的数据通过调用getInputStream()。

Java代码
  1. //GivenaURL,establishesanHttpUrlConnectionandretrieves
  2. //thewebpagecontentasaInputStream,whichitreturnsas
  3. //astring.
  4. privateStringdownloadUrl(Stringmyurl)throwsIOException{
  5. InputStreamis=null;
  6. //Onlydisplaythefirst500charactersoftheretrieved
  7. //webpagecontent.
  8. intlen=500;
  9. try{
  10. URLurl=newURL(myurl);
  11. HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
  12. conn.setReadTimeout(10000/*milliseconds*/);
  13. conn.setConnectTimeout(15000/*milliseconds*/);
  14. conn.setRequestMethod("GET");
  15. conn.setDoInput(true);
  16. //Startsthequery
  17. conn.connect();
  18. intresponse=conn.getResponseCode();
  19. Log.d(DEBUG_TAG,"Theresponseis:"+response);
  20. is=conn.getInputStream();
  21. //ConverttheInputStreamintoastring
  22. StringcontentAsString=readIt(is,len);
  23. returncontentAsString;
  24. //MakessurethattheInputStreamisclosedaftertheappis
  25. //finishedusingit.
  26. }finally{
  27. if(is!=null){
  28. is.close();
  29. }
  30. }
  31. }

getResponseCode()返回连接的状态码。这是一种有用的方式获得一些额外的信息的连接。一个200的状态代码表示成功。

转换InputStreamString

Java代码
  1. //ReadsanInputStreamandconvertsittoaString.
  2. publicStringreadIt(InputStreamstream,intlen)throwsIOException,UnsupportedEncodingException{
  3. Readerreader=null;
  4. reader=newInputStreamReader(stream,"UTF-8");
  5. char[]buffer=newchar[len];
  6. reader.read(buffer);
  7. returnnewString(buffer);
  8. }

二、管理网络

检查设备的网络连接

一个设备可以有各种类型的网络连接。这节课的重点是使用wi - fi或手机或网络连接,这个代码片段测试网络连接wi - fi和移动。它确定这些网络接口是可用的或连接的(即网络连接是否存在,如果可以建立套接字和传递数据)

Java代码
  1. privatestaticfinalStringDEBUG_TAG="NetworkStatusExample";
  2. ...
  3. ConnectivityManagerconnMgr=(ConnectivityManager)
  4. getSystemService(Context.CONNECTIVITY_SERVICE);
  5. NetworkInfonetworkInfo=connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
  6. booleanisWifiConn=networkInfo.isConnected();
  7. networkInfo=connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
  8. booleanisMobileConn=networkInfo.isConnected();
  9. Log.d(DEBUG_TAG,"Wificonnected:"+isWifiConn);
  10. Log.d(DEBUG_TAG,"Mobileconnected:"+isMobileConn);

管理网络的使用

您可以实现一个首选项活动,让用户明确控制应用程序的使用网络资源。例如:1.你可能允许用户上传的视频只有当设备被连接到wi - fi网络。2.你可能会同步(或没有)根据特定标准如网络可用性、时间间隔,等等。

编写一个应用程序,支持网络访问和管理网络的使用,你的清单必须有正确的权限和意图过滤器。

在样例应用程序中,这个规定了SettingsActivity,将显示一个UI让用户知道何时可以进行下载操作。

Xml代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.example.android.networkusage"
  4. ...>
  5. <uses-sdkandroid:minSdkVersion="4"
  6. android:targetSdkVersion="14"/>
  7. <uses-permissionandroid:name="android.permission.INTERNET"/>
  8. <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
  9. <application
  10. ...>
  11. ...
  12. <activityandroid:label="SettingsActivity"android:name=".SettingsActivity">
  13. <intent-filter>
  14. <actionandroid:name="android.intent.action.MANAGE_NETWORK_USAGE"/>
  15. <categoryandroid:name="android.intent.category.DEFAULT"/>
  16. </intent-filter>
  17. </activity>
  18. </application>
  19. </manifest>

Java代码
  1. publicclassSettingsActivityextendsPreferenceActivityimplementsOnSharedPreferenceChangeListener{
  2. @Override
  3. protectedvoidonCreate(BundlesavedInstanceState){
  4. super.onCreate(savedInstanceState);
  5. //LoadstheXMLpreferencesfile
  6. addPreferencesFromResource(R.xml.preferences);
  7. }
  8. @Override
  9. protectedvoidonResume(){
  10. super.onResume();
  11. //Registersalistenerwheneverakeychanges
  12. getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
  13. }
  14. @Override
  15. protectedvoidonPause(){
  16. super.onPause();
  17. //UnregistersthelistenersetinonResume().
  18. //It'sbestpracticetounregisterlistenerswhenyourappisn'tusingthemtocutdownon
  19. //unnecessarysystemoverhead.YoudothisinonPause().
  20. getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
  21. }
  22. //Whentheuserchangesthepreferencesselection,
  23. //onSharedPreferenceChanged()restartsthemainactivityasanew
  24. //task.SetsthetherefreshDisplayflagto"true"toindicatethat
  25. //themainactivityshouldupdateitsdisplay.
  26. //ThemainactivityqueriesthePreferenceManagertogetthelatestsettings.
  27. @Override
  28. publicvoidonSharedPreferenceChanged(SharedPreferencessharedPreferences,Stringkey){
  29. //SetsrefreshDisplaytotruesothatwhentheuserreturnstothemain
  30. //activity,thedisplayrefreshestoreflectthenewsettings.
  31. NetworkActivity.refreshDisplay=true;
  32. }
  33. }

响应网络变动

如果有一个匹配发生在设置和设备的网络连接(例如,如果设置为“wi - fi”和设备有一个wi - fi连接)之间,应用程序下载提继续并刷新显示

Java代码
  1. publicclassNetworkActivityextendsActivity{
  2. publicstaticfinalStringWIFI="Wi-Fi";
  3. publicstaticfinalStringANY="Any";
  4. privatestaticfinalStringURL="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";
  5. //WhetherthereisaWi-Ficonnection.
  6. privatestaticbooleanwifiConnected=false;
  7. //Whetherthereisamobileconnection.
  8. privatestaticbooleanmobileConnected=false;
  9. //Whetherthedisplayshouldberefreshed.
  10. publicstaticbooleanrefreshDisplay=true;
  11. //Theuser'scurrentnetworkpreferencesetting.
  12. publicstaticStringsPref=null;
  13. //TheBroadcastReceiverthattracksnetworkconnectivitychanges.
  14. privateNetworkReceiverreceiver=newNetworkReceiver();
  15. @Override
  16. publicvoidonCreate(BundlesavedInstanceState){
  17. super.onCreate(savedInstanceState);
  18. //RegistersBroadcastReceivertotracknetworkconnectionchanges.
  19. IntentFilterfilter=newIntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
  20. receiver=newNetworkReceiver();
  21. this.registerReceiver(receiver,filter);
  22. }
  23. @Override
  24. publicvoidonDestroy(){
  25. super.onDestroy();
  26. //UnregistersBroadcastReceiverwhenappisdestroyed.
  27. if(receiver!=null){
  28. this.unregisterReceiver(receiver);
  29. }
  30. }
  31. //Refreshesthedisplayifthenetworkconnectionandthe
  32. //prefsettingsallowit.
  33. @Override
  34. publicvoidonStart(){
  35. super.onStart();
  36. //Getstheuser'snetworkpreferencesettings
  37. SharedPreferencessharedPrefs=PreferenceManager.getDefaultSharedPreferences(this);
  38. //Retrievesastringvalueforthepreferences.Thesecondparameter
  39. //isthedefaultvaluetouseifapreferencevalueisnotfound.
  40. sPref=sharedPrefs.getString("listPref","Wi-Fi");
  41. updateConnectedFlags();
  42. if(refreshDisplay){
  43. loadPage();
  44. }
  45. }
  46. //ChecksthenetworkconnectionandsetsthewifiConnectedandmobileConnected
  47. //variablesaccordingly.
  48. publicvoidupdateConnectedFlags(){
  49. ConnectivityManagerconnMgr=(ConnectivityManager)
  50. getSystemService(Context.CONNECTIVITY_SERVICE);
  51. NetworkInfoactiveInfo=connMgr.getActiveNetworkInfo();
  52. if(activeInfo!=null&&activeInfo.isConnected()){
  53. wifiConnected=activeInfo.getType()==ConnectivityManager.TYPE_WIFI;
  54. mobileConnected=activeInfo.getType()==ConnectivityManager.TYPE_MOBILE;
  55. }else{
  56. wifiConnected=false;
  57. mobileConnected=false;
  58. }
  59. }
  60. //UsesAsyncTasksubclasstodownloadtheXMLfeedfromstackoverflow.com.
  61. publicvoidloadPage(){
  62. if(((sPref.equals(ANY))&&(wifiConnected||mobileConnected))
  63. ||((sPref.equals(WIFI))&&(wifiConnected))){
  64. //AsyncTasksubclass
  65. newDownloadXmlTask().execute(URL);
  66. }else{
  67. showErrorPage();
  68. }
  69. }
  70. ...
  71. }

检测网络连接变化

Java代码
  1. publicclassNetworkReceiverextendsBroadcastReceiver{
  2. @Override
  3. publicvoidonReceive(Contextcontext,Intentintent){
  4. ConnectivityManagerconn=(ConnectivityManager)
  5. context.getSystemService(Context.CONNECTIVITY_SERVICE);
  6. NetworkInfonetworkInfo=conn.getActiveNetworkInfo();
  7. //Checkstheuserprefsandthenetworkconnection.Basedontheresult,decideswhether
  8. //torefreshthedisplayorkeepthecurrentdisplay.
  9. //IftheuserprefisWi-Fionly,checkstoseeifthedevicehasaWi-Ficonnection.
  10. if(WIFI.equals(sPref)&&networkInfo!=null&&networkInfo.getType()==ConnectivityManager.TYPE_WIFI){
  11. //IfdevicehasitsWi-Ficonnection,setsrefreshDisplay
  12. //totrue.Thiscausesthedisplaytoberefreshedwhentheuser
  13. //returnstotheapp.
  14. refreshDisplay=true;
  15. Toast.makeText(context,R.string.wifi_connected,Toast.LENGTH_SHORT).show();
  16. //IfthesettingisANYnetworkandthereisanetworkconnection
  17. //(whichbyprocessofeliminationwouldbemobile),setsrefreshDisplaytotrue.
  18. }elseif(ANY.equals(sPref)&&networkInfo!=null){
  19. refreshDisplay=true;
  20. //Otherwise,theappcan'tdownloadcontent--eitherbecausethereisnonetwork
  21. //connection(mobileorWi-Fi),orbecausetheprefsettingisWIFI,andthere
  22. //isnoWi-Ficonnection.
  23. //SetsrefreshDisplaytofalse.
  24. }else{
  25. refreshDisplay=false;
  26. Toast.makeText(context,R.string.lost_connection,Toast.LENGTH_SHORT).show();
  27. }
  28. }

三、解析xml

上传和解析XML数据是很常见的任务,网络连接应用程序。这一课解释了如何解析XML文档并使用他们的数据

选择转换器

我们建议XmlPullParser,这是一种高效且可维护的方式来解析XML在Android里。

分析需求

Xml代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <feedxmlns="http://www.w3.org/2005/Atom"xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"...">
  3. <titletype="text">newestquestionstaggedandroid-StackOverflow</title>
  4. ...
  5. <entry>
  6. ...
  7. </entry>
  8. <entry>
  9. <id>http://stackoverflow.com/q/9439999</id>
  10. <re:rankscheme="http://stackoverflow.com">0</re:rank>
  11. <titletype="text">Whereismydatafile?</title>
  12. <categoryscheme="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest/tags"term="android"/>
  13. <categoryscheme="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest/tags"term="file"/>
  14. <author>
  15. <name>cliff2310</name>
  16. <uri>http://stackoverflow.com/users/1128925</uri>
  17. </author>
  18. <linkrel="alternate"href="http://stackoverflow.com/questions/9439999/where-is-my-data-file"/>
  19. <published>2012-02-25T00:30:54Z</published>
  20. <updated>2012-02-25T00:30:54Z</updated>
  21. <summarytype="html">
  22. <p>IhaveanApplicationthatrequiresadatafile...</p>
  23. </summary>
  24. </entry>
  25. <entry>
  26. ...
  27. </entry>
  28. ...
  29. </feed>

实例化转化器

Java代码
  1. publicclassStackOverflowXmlParser{
  2. //Wedon'tusenamespaces
  3. privatestaticfinalStringns=null;
  4. publicListparse(InputStreamin)throwsXmlPullParserException,IOException{
  5. try{
  6. XmlPullParserparser=Xml.newPullParser();
  7. parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,false);
  8. parser.setInput(in,null);
  9. parser.nextTag();
  10. returnreadFeed(parser);
  11. }finally{
  12. in.close();
  13. }
  14. }
  15. ...
  16. }
  17. 读取xml
  18. privateListreadFeed(XmlPullParserparser)throwsXmlPullParserException,IOException{
  19. Listentries=newArrayList();
  20. parser.require(XmlPullParser.START_TAG,ns,"feed");
  21. while(parser.next()!=XmlPullParser.END_TAG){
  22. if(parser.getEventType()!=XmlPullParser.START_TAG){
  23. continue;
  24. }
  25. Stringname=parser.getName();
  26. //Startsbylookingfortheentrytag
  27. if(name.equals("entry")){
  28. entries.add(readEntry(parser));
  29. }else{
  30. skip(parser);
  31. }
  32. }
  33. returnentries;
  34. }

下面这个代码片段展示了如何解析器解析条目、标题、链接和总结:

Java代码
  1. publicstaticclassEntry{
  2. publicfinalStringtitle;
  3. publicfinalStringlink;
  4. publicfinalStringsummary;
  5. privateEntry(Stringtitle,Stringsummary,Stringlink){
  6. this.title=title;
  7. this.summary=summary;
  8. this.link=link;
  9. }
  10. }
  11. //Parsesthecontentsofanentry.Ifitencountersatitle,summary,orlinktag,handsthemoff
  12. //totheirrespective"read"methodsforprocessing.Otherwise,skipsthetag.
  13. privateEntryreadEntry(XmlPullParserparser)throwsXmlPullParserException,IOException{
  14. parser.require(XmlPullParser.START_TAG,ns,"entry");
  15. Stringtitle=null;
  16. Stringsummary=null;
  17. Stringlink=null;
  18. while(parser.next()!=XmlPullParser.END_TAG){
  19. if(parser.getEventType()!=XmlPullParser.START_TAG){
  20. continue;
  21. }
  22. Stringname=parser.getName();
  23. if(name.equals("title")){
  24. title=readTitle(parser);
  25. }elseif(name.equals("summary")){
  26. summary=readSummary(parser);
  27. }elseif(name.equals("link")){
  28. link=readLink(parser);
  29. }else{
  30. skip(parser);
  31. }
  32. }
  33. returnnewEntry(title,summary,link);
  34. }
  35. //Processestitletagsinthefeed.
  36. privateStringreadTitle(XmlPullParserparser)throwsIOException,XmlPullParserException{
  37. parser.require(XmlPullParser.START_TAG,ns,"title");
  38. Stringtitle=readText(parser);
  39. parser.require(XmlPullParser.END_TAG,ns,"title");
  40. returntitle;
  41. }
  42. //Processeslinktagsinthefeed.
  43. privateStringreadLink(XmlPullParserparser)throwsIOException,XmlPullParserException{
  44. Stringlink="";
  45. parser.require(XmlPullParser.START_TAG,ns,"link");
  46. Stringtag=parser.getName();
  47. StringrelType=parser.getAttributeValue(null,"rel");
  48. if(tag.equals("link")){
  49. if(relType.equals("alternate")){
  50. link=parser.getAttributeValue(null,"href");
  51. parser.nextTag();
  52. }
  53. }
  54. parser.require(XmlPullParser.END_TAG,ns,"link");
  55. returnlink;
  56. }
  57. //Processessummarytagsinthefeed.
  58. privateStringreadSummary(XmlPullParserparser)throwsIOException,XmlPullParserException{
  59. parser.require(XmlPullParser.START_TAG,ns,"summary");
  60. Stringsummary=readText(parser);
  61. parser.require(XmlPullParser.END_TAG,ns,"summary");
  62. returnsummary;
  63. }
  64. //Forthetagstitleandsummary,extractstheirtextvalues.
  65. privateStringreadText(XmlPullParserparser)throwsIOException,XmlPullParserException{
  66. Stringresult="";
  67. if(parser.next()==XmlPullParser.TEXT){
  68. result=parser.getText();
  69. parser.nextTag();
  70. }
  71. returnresult;
  72. }
  73. ...
  74. }

跳过无用的标签

Java代码
  1. privatevoidskip(XmlPullParserparser)throwsXmlPullParserException,IOException{
  2. if(parser.getEventType()!=XmlPullParser.START_TAG){
  3. thrownewIllegalStateException();
  4. }
  5. intdepth=1;
  6. while(depth!=0){
  7. switch(parser.next()){
  8. caseXmlPullParser.END_TAG:
  9. depth--;
  10. break;
  11. caseXmlPullParser.START_TAG:
  12. depth++;
  13. break;
  14. }
  15. }
  16. }

使用xml数据

Java代码
  1. publicclassNetworkActivityextendsActivity{
  2. publicstaticfinalStringWIFI="Wi-Fi";
  3. publicstaticfinalStringANY="Any";
  4. privatestaticfinalStringURL="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";
  5. //WhetherthereisaWi-Ficonnection.
  6. privatestaticbooleanwifiConnected=false;
  7. //Whetherthereisamobileconnection.
  8. privatestaticbooleanmobileConnected=false;
  9. //Whetherthedisplayshouldberefreshed.
  10. publicstaticbooleanrefreshDisplay=true;
  11. publicstaticStringsPref=null;
  12. ...
  13. //UsesAsyncTasktodownloadtheXMLfeedfromstackoverflow.com.
  14. publicvoidloadPage(){
  15. if((sPref.equals(ANY))&&(wifiConnected||mobileConnected)){
  16. newDownloadXmlTask().execute(URL);
  17. }
  18. elseif((sPref.equals(WIFI))&&(wifiConnected)){
  19. newDownloadXmlTask().execute(URL);
  20. }else{
  21. //showerror
  22. }
  23. }

动态下载xml

Java代码
  1. //ImplementationofAsyncTaskusedtodownloadXMLfeedfromstackoverflow.com.
  2. privateclassDownloadXmlTaskextendsAsyncTask<String,Void,String>{
  3. @Override
  4. protectedStringdoInBackground(String...urls){
  5. try{
  6. returnloadXmlFromNetwork(urls[0]);
  7. }catch(IOExceptione){
  8. returngetResources().getString(R.string.connection_error);
  9. }catch(XmlPullParserExceptione){
  10. returngetResources().getString(R.string.xml_error);
  11. }
  12. }
  13. @Override
  14. protectedvoidonPostExecute(Stringresult){
  15. setContentView(R.layout.main);
  16. //DisplaystheHTMLstringintheUIviaaWebView
  17. WebViewmyWebView=(WebView)findViewById(R.id.webview);
  18. myWebView.loadData(result,"text/html",null);
  19. }
  20. }

加载xml

Java代码
  1. //UploadsXMLfromstackoverflow.com,parsesit,andcombinesitwith
  2. //HTMLmarkup.ReturnsHTMLstring.
  3. privateStringloadXmlFromNetwork(StringurlString)throwsXmlPullParserException,IOException{
  4. InputStreamstream=null;
  5. //Instantiatetheparser
  6. StackOverflowXmlParserstackOverflowXmlParser=newStackOverflowXmlParser();
  7. List<Entry>entries=null;
  8. Stringtitle=null;
  9. Stringurl=null;
  10. Stringsummary=null;
  11. CalendarrightNow=Calendar.getInstance();
  12. DateFormatformatter=newSimpleDateFormat("MMMddh:mmaa");
  13. //Checkswhethertheusersetthepreferencetoincludesummarytext
  14. SharedPreferencessharedPrefs=PreferenceManager.getDefaultSharedPreferences(this);
  15. booleanpref=sharedPrefs.getBoolean("summaryPref",false);
  16. StringBuilderhtmlString=newStringBuilder();
  17. htmlString.append("<h3>"+getResources().getString(R.string.page_title)+"</h3>");
  18. htmlString.append("<em>"+getResources().getString(R.string.updated)+""+
  19. formatter.format(rightNow.getTime())+"</em>");
  20. try{
  21. stream=downloadUrl(urlString);
  22. entries=stackOverflowXmlParser.parse(stream);
  23. //MakessurethattheInputStreamisclosedaftertheappis
  24. //finishedusingit.
  25. }finally{
  26. if(stream!=null){
  27. stream.close();
  28. }
  29. }
  30. //StackOverflowXmlParserreturnsaList(called"entries")ofEntryobjects.
  31. //EachEntryobjectrepresentsasinglepostintheXMLfeed.
  32. //ThissectionprocessestheentrieslisttocombineeachentrywithHTMLmarkup.
  33. //EachentryisdisplayedintheUIasalinkthatoptionallyincludes
  34. //atextsummary.
  35. for(Entryentry:entries){
  36. htmlString.append("<p><ahref='");
  37. htmlString.append(entry.link);
  38. htmlString.append("'>"+entry.title+"</a></p>");
  39. //Iftheusersetthepreferencethttp://oincludesummarytext,
  40. //addsittothedisplay.
  41. if(pref){
  42. htmlString.append(entry.summary);
  43. }
  44. }
  45. returnhtmlString.toString();
  46. }
  47. //GivenastringrepresentationofaURL,setsupaconnectionandgets
  48. //aninputstream.
  49. privateInputStreamdownloadUrl(StringurlString)throwsIOException{
  50. URLurl=newURL(urlString);
  51. HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
  52. conn.setReadTimeout(10000/*milliseconds*/);
  53. conn.setConnectTimeout(15000/*milliseconds*/);
  54. conn.setRequestMethod("GET");
  55. conn.setDoInput(true);
  56. //Startsthequery
  57. conn.connect();
  58. InputStreamstream=conn.getInputStream();
  59. }

上面的片段代码为了帮助大家理解,这里还是老习惯,贴上项目的源代码,本来是有项目截图,运行效果图之类的图的,只是这篇文章太长了,再弄图片,就更占篇幅了,所以就只贴源码了,大家可以自己的运行起来看看,希望能从整体的架构和具体的代码细节上帮助到大家。点击打开下载链接

分享到:
评论

相关推荐

    android检测网络两个方法

    罗列了android常用两种检测网络方法,在工作线程中定时执行检测操作

    android从网络获取图片资源,图片放大、缩小、触摸等操作。

    从网络异步加载图片资源,主线程执行ui操作,工作线程执行耗时操作。并可对图片触摸放大缩小。

    Android代码-这是一个专用于解决Android中网络请求及图片加载的缓存处理框架

    这是一个专用于解决Android中网络请求及图片加载的缓存处理框架 项目目标 本项目是作为实验项目,不保证其稳定性及可靠性 因为缓存业务的复杂性,本项目尽可能适应更多的使用场景 目前考虑到的,会实现的功能清单,...

    Android网络音乐播放器 源码下载

    异步任务AsyncTask执行耗时任务-音乐的收藏(使用到数据库)操作及音乐的搜索等需要访问网络的操作; 自定义view实现圆形专辑图片,滚动歌词,支持下拉刷新的音乐列表; Json解析网络响应,正则表达式解析歌词; ...

    RxAndroid配合MVP模式,执行网络操作并更新ui的demo

    RxAndroid配合MVP模式,执行网络操作并更新ui的demo

    iperf3工具-windows+android设备可执行文件

    iPerf3是一个用于测量网络带宽性能的开源工具。它被设计用于评估网络连接的吞吐量、延迟和数据包丢失率等性能指标。以下是关于iPerf3的一些重要信息和功能: ...跨平台支持:iPerf3可在多种操作系统上运行,包括Lin

    Android代码-安卓下载任务管理

    实现Runnable接口,实际下载工作,负责网络请求,数据库信息更新 DownloadManager 单例,创建下载任务,提供获取正在下载任务,所有下载信息,设置监听器等接口 DownloadEngine 负责创建线程池,根据任务创建...

    快速Android网络::rocket:完整的快速Android网络库,还支持HTTP2:rocket:

    没有其他库提供简单的界面来执行网络中的所有类型的事情,例如设置优先级,取消等。 由于使用 ,因此android应用程序中不会再有GC开销。 可以在分配内存时处理GC开销。 做了一些聪明的事情来节省CPU和内存。 它使用...

    新版Android开发教程.rar

    这一联盟将会支持 Google 发布的 Android 手机操作系统或者应用软件,共同开发名为 Android 的 开 放源代码的移动系统。开放手机联盟包括手机制造商、手机芯片厂商和移动运营商几类。目前,联盟成员 数 量已经达到了...

    最简易的网络框架封装(新手可看)

    网络通信在Android上的重要性就不多说了。...1、在同一个项目中,我们要执行网络操作可定不想要每次都编写一遍HTTP请求的代码。通常情况我们都会将这些网络操作提取到一个公共的类里面,并提供一个静态方法,

    Android高级编程--源代码

     由于Android 1.0是一个正在兴起的全新手机操作系统,所以当前支持它的手机还不多。和任何其他产品早期的发行版一样,Android的软件和开发库还会经历很多正常的改进和完善。本书的内容和示例提供了如何使用当前SDK...

    android VNC

    4)运行androidvncserver,在手机的“终端”执行以下代码:  如下指定键盘和触摸屏设备,以免找不到kdb设备: ./androidvncserver -k /dev/input/event0 -t /dev/input/event1  这样androidvncserver就启动...

    Google Android SDK开发范例大全(完整版)

    Android 有丰富的功能,因此很容易与桌面操作系统混淆。Android 是一个分层的环境,构建在 Linux 内核的基础上,它包括丰富的功能。UI 子系统包括: •窗口 •视图 •用于显示一些常见组件(例如编辑框、列表和下拉...

    Android中Volley框架进行请求网络数据的使用

    解决:Volley就是为解决这些而生,它与2013年Google I/O大会上被提出:使得Android应用网络操作更方便更快捷;抽象了底层Http Client等实现的细节,让开发者更专注与产生RESTful Request。另外,Volley在不同的线程...

    Android数据库应用编程——为企业开发数据驱动Android应用

    学习为企业系统构建数据驱动的...◆ 通过避免在Internet上执行CRUD操作来提高性能 ◆ 开始编写连接到Android的后端云服务 ◆ 介绍新的开源和通用同步框架(专门与Android API集成) ◆ 解决应用程序实现中的安全问题

    android开发秘籍

    2.2.2 秘诀3:强制执行单任务模式 26 2.2.3 秘诀4:强制屏幕方向 26 2.2.4 秘诀5:保存和恢复activity信息 27 2.3 多个activity 28 2.3.1 秘诀6:使用按钮和文本框 28 2.3.2 秘诀7:通过事件启动另外一个activity...

    Android应用程序开发教程PDF电子书完整版、Android开发学习教程

    Android是一个专门针对移动设备的软件集,它包括一个操作系统,中间件和一些重要的应用程序。Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 • ...

    Android加载对话框同时异步执行实现方法

    Android中通过子线程连接网络获取资料,同时显示加载进度对话框给用户的操作

    Android静默安装常用工具类

    Android Shell工具类,可用于检查系统root权限,并在shell或root用户下执行shell命令。如: checkRootPermission() 检查root权限 execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) shell...

Global site tag (gtag.js) - Google Analytics