这个学期学校开了安卓的课程,因为自己一直学习wp的开发,一直用的是.net和Silverlight这一套,也着实没有太多时间投入安卓的方向去,因为想着毕业也不从事安卓的工作,所以也一直没有怎么研究。但是期末了,要交作品了,我想不如就做个RSS阅读器交吧,因为在学习wp的时候觉得RSS阅读器还是相对简单的,安卓上应该也是用的一样的思路。所以昨天晚上,在我们宿舍安卓大神的帮助下(主要是解决一些wp和安卓不同的地方带给我的疑问),我花了4个多小时做了这个应用。
总体思路是获取IT之家的RSS源,保存到一个集合里,然后把数据绑定到ListView上,点击ListView的其中一项,跳转到另一个页面,该页面只有一个WebView,用来显示点击项带过来的网址所对应的网页——当然wp里最简单的RSS阅读器也是这个思路。
首先定义一个文章的模型:
public class Item { private String title; private String description; private String date; private String link; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getLink() { return link; } public void setLink(String link) { this.link = link; } public HashMap<String,String> getMap(){ HashMap<String, String> map = new HashMap<String, String>(); map.put("title", title); map.put("description", description); map.put("date", date); map.put("link", link); return map; } }
最后一个方法getMap的作用是把当前对象的属性以HashMap的形式返回。为什么要这么做呢?因为后面要用到。
获取RSS源的实现方法:
public static List<Map<String, String>> readXML(InputStream inStream) { List<Map<String, String>> data = new ArrayList<Map<String, String>>(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); Document dom = builder.parse(inStream); Element root = dom.getDocumentElement(); NodeList items = root.getElementsByTagName("item");// 查找所有item节点 for (int i = 0; i < items.getLength(); i++) { Item item = new Item(); // 得到第一个item节点 Element itemNode = (Element) items.item(i); // 获取item节点下的所有子节点 NodeList childsNodes = itemNode.getChildNodes(); for (int j = 0; j < childsNodes.getLength(); j++) { Node node = (Node) childsNodes.item(j); // 判断是否为元素类型 if (node.getNodeType() == Node.ELEMENT_NODE) { Element childNode = (Element) node; if ("title".equals(childNode.getNodeName())) { item.setTitle(childNode.getFirstChild() .getNodeValue()); } else if ("link".equals(childNode.getNodeName())) { String computer = childNode.getFirstChild() .getNodeValue(); String phone = "http://wap.ithome.com/html" + computer.substring(computer .lastIndexOf("/")); Log.e("jpho", phone); item.setLink(phone); } else if ("description" .equals(childNode.getNodeName())) { item.setDescription(childNode.getFirstChild() .getNodeValue()); } else if ("pubDate".equals(childNode.getNodeName())) { item.setDate(childNode.getFirstChild() .getNodeValue()); } } } data.add(item.getMap()); } inStream.close(); } catch (Exception e) { e.printStackTrace(); } return data; }
这个方法把获取到的RSS数据添加到一个List集合里,里面就用到了上面提到的getMap方法。这里做了一个小小的处理,就是把获取到的文章链接转换成手机版的链接。毕竟要在手机上看,一来加载快,二来节省流量。
下面是逻辑:
String[] from = new String[] { "title", "date", "description", "link" }; int[] to = new int[] { R.id.title, R.id.date, R.id.description, R.id.link }; URL url; List<Map<String, String>> data = new ArrayList<Map<String, String>>(); try { url = new URL("http://www.ithome.com/rss/"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); InputStream isr = conn.getInputStream(); data = readXML(isr); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item, from, to); this.getListView().setAdapter(adapter); this.getListView().setOnItemClickListener(this);
这里的数据绑定跟wp的写法有点不同,这里是通过适配器来把属性绑定到相应控件里,在wp里我们直接写Bingding就可以了。getListView().setAdapter(adatper)跟wp里的设置数据上下文有点类似,不过这里是设置数据适配器。
接下来是Item的点击事件:
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub ListView listView = (ListView) parent; HashMap<String, String> map = (HashMap<String, String>) listView .getItemAtPosition(position); String url = map.get("link"); Intent intent = new Intent(getApplicationContext(), ItemActivity.class); intent.putExtra("url", url); startActivity(intent); }
Intent有点像是wp里的应用程序设置,也是通过键值对得方式把数据保存到独立存储空间里,然后在别的页面获取它。下面是文章页面的逻辑:
@SuppressLint("SetJavaScriptEnabled") public class ItemActivity extends Activity { private WebView mWebView; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.activity_item); Intent intent = getIntent(); mWebView = (WebView) findViewById(R.id.webView); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.loadUrl(intent.getStringExtra("url")); } }
要使WebView能加载js,就要添加这句话:@SuppressLint("SetJavaScriptEnabled"),还有这句:mWebView.getSettings().setJavaScriptEnabled(true),然后在onCreate方法里获取传过来的链接,并用WebView显示之。
这就是总体思路。毕竟是第一次写安卓应用,写得不好之处还望指正。不过真的跟wp的思路是一样的,所以只要掌握了一种移动开发方法,转向其他平台只是语言问题,还有一些不一样的特性,主要思路还是一摸一样的。不过以后不打算从事安卓开发,这可能是第一次,也是最后一次开发安卓的应用。仅以此文纪念那些还未开始便结束的东西。
有需要的可以在这里下载项目代码。