在 Android 应用程序中使用 Internet 数据
为什么80%的码农都做不了架构师?>>>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"><EditText android:id="@+id/symbol" android:layout_width="wrap_content"android:layout_height="wrap_content" android:width="120dip"/><Button android:id="@+id/addBtn" android:layout_width="wrap_content"android:layout_height="wrap_content" android:text="@string/addBtnLbl"/></LinearLayout><LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"><TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/symList" /><Button android:id="@+id/dlBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/dlBtnLbl"/></LinearLayout><ListView android:id="@android :id/list" android:layout_height="fill_parent" android:layout_width="fill_parent"android:layout_weight="1"/>
</LinearLayout>
public class Main extends ListActivity {private int mode = XML; // default@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);final EditText input = (EditText) findViewById(R.id.symbol);final TextView symbolsList = (TextView) findViewById(R.id.symList);final Button addButton = (Button) findViewById(R.id.addBtn);final Button dlButton = (Button) findViewById(R.id.dlBtn);addButton.setOnClickListener(new OnClickListener(){public void onClick(View v) {String newSymbol = input.getText().toString();if (symbolsList.getText() == null || symbolsList.getText().length() == 0){symbolsList.setText(newSymbol);} else {StringBuilder sb = new StringBuilder(symbolsList.getText());sb.append(",");sb.append(newSymbol);symbolsList.setText(sb.toString());}input.setText("");}});dlButton.setOnClickListener(new OnClickListener(){public void onClick(View v) {String symList = symbolsList.getText().toString();String[] symbols = symList.split(",");symbolsList.setText("");switch (mode){case JSON :new StockJsonParser().execute(symbols);break;case PROTOBUF :new StockProtoBufParser().execute(symbols);break;default :new StockXmlParser().execute(symbols);break;}}});}
}
此 Activity 设置了 清单 1 中 XML 文件的布局,它将几个事件处理程序连接起来。首先,对于 Add Stock 按钮而言,代码读取文本框中的代码并将其添加到 symList TextView 中,用逗号分隔每个代码。接下来,对于 Download 按钮而言,处理程序从 symList TextView 中读取数据,然后 —基于 mode 变量— 使用三个不同的类之一从服务器下载数据。菜单设置 mode 变量的值;这个代码不是很重要,因此我在 清单 2 中省略了它。在了解各种数据下载/解析类之前,我先为您展示一下服务器如何提供此数据。
public class StockBrokerServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {String[] symbols = request.getParameterValues("stock");List<Stock> stocks = getStocks(symbols);String format = request.getParameter("format");String data = "";if (format == null || format.equalsIgnoreCase("xml")){data = Stock.toXml(stocks);response.setContentType("text/xml"); } else if (format.equalsIgnoreCase("json")){data = Stock.toJson(stocks);response.setContentType("application/json");} else if (format.equalsIgnoreCase("protobuf")){Portfolio p = Stock.toProtoBuf(stocks);response.setContentType("application/octet-stream");response.setContentLength(p.getSerializedSize());p.writeTo(response.getOutputStream());response.flushBuffer();return;}response.setContentLength(data.length());response.getWriter().print(data);response.flushBuffer();response.getWriter().close();}public List<Stock> getStocks(String... symbols) throws IOException{StringBuilder sb = new StringBuilder();for (String symbol : symbols){sb.append(symbol);sb.append('+');}sb.deleteCharAt(sb.length() - 1);String urlStr = "http://finance.yahoo.com/d/quotes.csv?f=sb2n&s=" + sb.toString();URL url = new URL(urlStr);HttpURLConnection conn = (HttpURLConnection) url.openConnection();BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));String quote = reader.readLine();List<Stock> stocks = new ArrayList<Stock>(symbols.length);while (quote != null){String[] values = quote.split(",");Stock s = new Stock(values[0], values[2],Double.parseDouble(values[1]));stocks.add(s);quote = reader.readLine();}return stocks;}
}
public class Stock { private final String symbol;private final String name;private final double price;//getters and setters omittedpublic String toXml(){return "<stock><symbol>" + symbol +
"</symbol><name><![CDATA[" +name + "]]></name><price>" + price +
"</price></stock>";}public String toJson(){return "{ 'stock' : { 'symbol' : " +symbol +", 'name':" + name + ", 'price': '" + price + "'}}";}public static String toXml(List<Stock> stocks){StringBuilder xml = new StringBuilder("<stocks>");for (Stock s : stocks){xml.append(s.toXml());}xml.append("</stocks>");return xml.toString();}public static String toJson(List<Stock> stocks){StringBuilder json = new StringBuilder("{'stocks' : [");for (Stock s : stocks){json.append(s.toJson());json.append(',');}json.deleteCharAt(json.length() - 1);json.append("]}");return json.toString();}
}
package stocks;option java_package = "org.developerworks.stocks";message Quote{required string symbol = 1;required string name = 2;required double price = 3;
}message Portfolio{repeated Quote quote = 1;
}
public static Stocks.Portfolio toProtoBuf(List<Stock> stocks){List<Stocks.Quote> quotes = new ArrayList<Stocks.Quote>(stocks.size());for (Stock s : stocks){Quote q = Quote.newBuilder().setName(s.name).setSymbol(s.symbol).setPrice(s.price).build();quotes.add(q);}return Portfolio.newBuilder().addAllQuote(quotes).build();
}
abstract class BaseStockParser extends AsyncTask<String, Integer, Stock[]>{String urlStr = "http://protostocks.appspot.com/stockbroker?format=";protected BaseStockParser(String format){urlStr += format;}private String makeUrlString(String... symbols) {StringBuilder sb = new StringBuilder(urlStr);for (int i=0;i<symbols.length;i++){sb.append("&stock=");sb.append(symbols[i]);}return sb.toString();}protected InputStream getData(String[] symbols) throws Exception{HttpClient client = new DefaultHttpClient();HttpGet request = new HttpGet(new URI(makeUrlString(symbols)));HttpResponse response = client.execute(request);return response.getEntity().getContent();}@Overrideprotected void onPostExecute(Stock[] stocks){ArrayAdapter<Stock> adapter = new ArrayAdapter<Stock>(Main.this, R.layout.stock, stocks );setListAdapter(adapter);}
}
private class StockXmlParser extends BaseStockParser{public StockXmlParser(){super("xml");}@Overrideprotected Stock[] doInBackground(String... symbols) {ArrayList<Stock> stocks = new ArrayList<Stock>(symbols.length);try{ContentHandler handler = newHandler(stocks);Xml.parse(getData(symbols), Xml.Encoding.UTF_8, handler);} catch (Exception e){Log.e("DayTrader", "Exception getting XML data", e);}Stock[] array = new Stock[symbols.length];return stocks.toArray(array);}private ContentHandler newHandler(final ArrayList<Stock> stocks){RootElement root = new RootElement("stocks");Element stock = root.getChild("stock");final Stock currentStock = new Stock();stock.setEndElementListener(new EndElementListener(){public void end() {stocks.add((Stock) currentStock.clone());}});stock.getChild("name").setEndTextElementListener(new EndTextElementListener(){public void end(String body) {currentStock.setName(body);}});stock.getChild("symbol").setEndTextElementListener(new EndTextElementListener(){public void end(String body) {currentStock.setSymbol(body);}});stock.getChild("price").setEndTextElementListener(new EndTextElementListener(){public void end(String body) {currentStock.setPrice(Double.parseDouble(body));}});return root.getContentHandler();}
}
清单 8 中的大部分代码都在 newHandler() 方法中,该方法创建一个 ContentHandler。如果熟悉 SAX 解析, 会知道 ContentHandler通过响应 SAX 解析器触发的各种事件创建解析数据。newHandler() 方法使用 Android 便捷 API 指定使用事件处理程序的ContentHandler。代码只是侦听在解析器遇到各种标记时触发的事件,然后选取数据,放到 Stock 对象列表中。 创建ContentHandler 后,调用 Xml.parse() 方法来解析基类提供的 InputStream 并返回 Stock 对象数组。这是快速解析 XML 的方法,但是 —即使使用 Android 提供的便捷 API— 它也是非常冗长的。
private class StockJsonParser extends BaseStockParser{public StockJsonParser(){super("json");}@Overrideprotected Stock[] doInBackground(String... symbols) {Stock[] stocks = new Stock[symbols.length];try{StringBuilder json = new StringBuilder();BufferedReader reader = new BufferedReader(new InputStreamReader(getData(symbols)));String line = reader.readLine();while (line != null){json.append(line);line = reader.readLine();}JSONObject jsonObj = new JSONObject(json.toString());JSONArray stockArray = jsonObj.getJSONArray("stocks");for (int i=0;i<stocks.length;i++){JSONObject object = stockArray.getJSONObject(i).getJSONObject("stock");stocks[i] = new Stock(object.getString("symbol"), object.getString("name"), object.getDouble("price"));}} catch (Exception e){Log.e("DayTrader", "Exception getting JSON data", e);}return stocks;}
}
private class StockProtoBufParser extends BaseStockParser{public StockProtoBufParser(){super("protobuf");}@Overrideprotected Stock[] doInBackground(String... symbols) {Stock[] stocks = new Stock[symbols.length];try{Stocks.Portfolio portfolio = Stocks.Portfolio.parseFrom(getData(symbols));for (int i=0;i<symbols.length;i++){stocks[i] = Stock.fromQuote(portfolio.getQuote(i));}} catch (Exception e){Log.e("DayTrader", "Exception getting ProtocolBuffer data", e);}return stocks;}
如 清单 3 所示,您可以使用 protocol buffers 编译器生成的 helper 类。这与服务器使用的 helper 类相同。可以编译它一次,然后在服务器和客户端共享它。 这样,您可以更轻松地直接从服务器的流读取数据并将其转换成 Stock 对象数组。这种简单编程也具有非常出色的性能。现在看一下此性能与 XML 和 JSON 的比较。
转载于:https://my.oschina.net/dsm/blog/75411
在 Android 应用程序中使用 Internet 数据相关推荐
- 在 Android 应用程序中使用 SQLite 数据库以及怎么用
part one : android SQLite 简单介绍 SQLite 介绍 SQLite 一个非常流行的嵌入式数据库.它支持 SQL 语言,而且仅仅利用非常少的内存就有非常好的性能.此外它还是开 ...
- Android的5中主要的数据存储方式
Android有5中主要的数据存储方式: 1.Android本身的数据库(SQLite数据库):SQlite是一个轻量级的.跨平台的数据库.占用内存小,支持基本的SQL语法,通常用于存储用户信息. 2 ...
- java中使用es的dsl_基于DSL的基于图论的Java程序中输入图数据的方法
java中使用es的dsl 我们大多数人已经编写了一些处理图论算法的程序,例如找到两个顶点之间的最短路径,找到给定图的最小生成树等等. 在这些算法的每一种中,表示图形的编程方式是使用邻接矩阵或邻接列表 ...
- 在MVC 6 .NET核心应用程序中添加种子数据
目录 目标 介绍 使用的组件 创建项目 DbInitializer类 结论 目标 就像MVC 5一样,我试图启用自动迁移和Seeding默认数据,但似乎MVC 6中的行为已经改变,所以我想分享这个提示 ...
- android程序root权限,android应用程序中应用root权限
android应用程序中使用root权限 要在android应用程序中使用root权限,那么运行程序的设备必须具有root权限. http://www.eoeandroid.com/code/2012 ...
- 绕过Android虚拟机,如何绕过android应用程序中的模拟器检测
如何绕过android应用程序中的模拟器检测 介绍 在模拟器上测试一些android应用程序时,它总会显示应用程序与CPU不兼容,或者在模拟器上安装应用程序时会出现一些错误 我会告诉你如何轻松绕过 留 ...
- android 浏览器 cookie,从Android的浏览器中传递cookie数据到App中
从Android的浏览器中传递cookie数据到App中 蒋彪@南京 2013-4-19 1. 需求 客户有一个需求, 在Android的浏览器上登录一个site, login之后,会在本地co ...
- 如何在微信小程序中爬取数据
如何在微信小程序中爬取数据 下载Charles 在Charles中点击Help -> SSL Proxying -> Install Charles Root Certificate 然后 ...
- Android程序 地图,在定制的Android应用程序中使用谷歌地图
我收到以下问题(显示在LogCat中).我希望any1可以帮助我,因为我是android应用程序开发的新手.在定制的Android应用程序中使用谷歌地图 11-17 16:50:38.087: E/A ...
最新文章
- 多个敏捷团队同时做一个项目_您说您的团队很敏捷……但是这个词可能并不代表您的想法。...
- freemarker的${!}
- SecureCRT安装的注意事项
- java update多个字段的值_SQL的update多个字段的写法
- pl/sql链接64位oracle数据库报错Could not initialize oci.dll
- OpenCV学习笔记之Mat
- James Shore:敏捷的衰落
- org.apache.hadoop.hive.metastore.api.InvalidObjectException: Role public already exists.
- win10下markdownpad2显示问题
- ATL offsetofclass 的工作原理
- nginx配置跨域、gzip加速、代理详细讲解
- java缓存内存泄漏_java – getMethod是缓存并导致内存泄漏
- 漫画:大厂总体 SaaS 化部署,到底什么是 IaaS、PaaS 和 SaaS?
- Bootstrap 异常
- 在面向服务的设计时有四个原则:
- ubuntu实现屏幕的旋转和开启自动旋转屏幕
- #define 喵 int_【吃鸡大作战第三季】第12集 告白小雪喵
- 『Java CVE』CVE-2022-33980: Apache Commons Configuration 读文件RCE
- 【Beta】Scrum Meeting 7 与助教谈话
- linux下退出mysql
热门文章
- LVS+Heartbeat+Ipvsadm+Ldirectord安装(四)
- Python才排第8名!2018增速最快TOP 10编程语言盘点
- android实现模拟自动点击_昆仑通态专题(十三):模拟实现全自动洗衣机系统的设计(案例)...
- 机器学习库一:scikit-learn
- Redis添加从节点
- 单机负载告警,数据库与应用分离
- Lambda表达式的注意事项【理解】
- 获取class文件对象三种方式
- 百万数据报表导出:使用SXSSFWorkbook完成百万数据报表打印
- ServletFileUpload API详解