900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Android开发RSS阅读器

Android开发RSS阅读器

时间:2020-12-14 05:21:13

相关推荐

Android开发RSS阅读器

RSS阅读器的Logo:

RSS阅读器是一种软件或是说一个程序,这种软件可以自由读取RSS和Atom两种规范格式的文档,且这种读取RSS和Atom文档的软件有多个版本,由不同的人或公司开发,有着不同的名字。如目前流行的有:RSSReader、Feeddemon、SharpReader等。这些软件能够实现大致相同的功能,其实质都是为了方便地读取RSS和Atom文档。Really Simple Syndication “聚合真的很简单”就是RSS的英文原意。把新闻标题、摘要(Feed)、内容按照用户的要求,“送”到用户的桌面就是RSS的目的。

注:下面给出的这个例子来自Google Android SDK开发,经过阅读,理解,并加上自己的和汇总写下这篇文章。

首先,给出实现本实例的截图,我用这个阅读器打开了我的博客。

1.

这是程序运行的主界面,实现这个界面的代码如下:

package irdc.ex08_13;/* import相关class */import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;public class EX08_13 extends Activity{/* 变量声明 */private Button mButton;private EditText mEditText;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);/* 初始化对象 */mEditText=(EditText) findViewById(R.id.myEdit);mButton=(Button) findViewById(R.id.myButton);/* 设定Button的onClick事件 */mButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { String path=mEditText.getText().toString();if(path.equals("")){showDialog("网址不可为空白!");}else{/* new一个Intent对象,并指定class */Intent intent = new Intent();intent.setClass(EX08_13.this,EX08_13_1.class);/* new一个Bundle对象,并将要传递的数据传入 */Bundle bundle = new Bundle();bundle.putString("path",path);/* 将Bundle对象assign给Intent */intent.putExtras(bundle);/* 调用Activity EX08_13_1 */startActivityForResult(intent,0);}} });}/* 重写 onActivityResult()*/@Overrideprotected void onActivityResult(int requestCode,int resultCode,Intent data){switch (resultCode){ /** 当由主程序唤起的EX08_13_1发生运行错误时,会返回resultCode=99的信息,主程序* 在接收到信息时,将以Dialog显示错误信息*/case 99:/* 回传错误时以Dialog显示 */Bundle bunde = data.getExtras();String error = bunde.getString("error");showDialog(error);break; default: break; } } /* 显示Dialog的method */private void showDialog(String mess){new AlertDialog.Builder(EX08_13.this).setTitle("Message").setMessage(mess).setNegativeButton("确定", new DialogInterface.OnClickListener(){public void onClick(DialogInterface dialog, int which){}}).show();}}

2.点击打开按钮,进入文档界面,实现的截图如下:

说明:

* 这是一个ListActivity,主要用来显示订阅的RSS内容列表

* 当程序被主程序唤醒时,会先从Bundle对象中取得主程序传入的RSS网址,再调用自定义的getRss()方法

* 对RSS网址发出request,并解析由服务器返回的XML格式的文件。

* getRss()是自定义的方法,它除了会将RSS的request传送出去,在接收到服务器response时,会以

* SAXParser作为解析XML的主要工具,利用自定义的MyHandler类来取得XML内的相关信息。

* 调用getRss()时,会返回一个List<News>,内存的每一笔数据就是一个News对象,也就是所有新闻的列表;

* 在取得List<News>之后,将List传入自定义的MyAdapter对象,再使用setListAdapter()将数据设置给ListView。

* 程序中重写ListActivity的onListItemClick(),当ListView中的任一个item被单击时,onClick()会被触发,

* 此时会先取得单击的News对象,并将相关信息传入Bundle中,再将Bundle对象assign给Intent,并唤起EX08_13_2这个

* Activity。

* 当程序发生错误时,会返回resultCode=99的信息给上一个Activity

下面给出实现代码:

public class EX08_13_1 extends ListActivity{/* 变量声明 */private TextView mText;private String title="";private List<News> li=new ArrayList<News>();@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);/* 设定layout为newslist.xml */setContentView(R.layout.newslist);mText=(TextView) findViewById(R.id.myText);/* 取得Intent中的Bundle对象 */Intent intent=this.getIntent();Bundle bunde = intent.getExtras();/* 取得Bundle对象中的数据 */String path = bunde.getString("path");/* 调用getRss()取得解析后的List */li=getRss(path);mText.setText(title);/* 设定自定义的MyAdapter */setListAdapter(new MyAdapter(this,li));}/* 设定ListItem被按下时要做的动作 */@Overrideprotected void onListItemClick(ListView l,View v,int position,long id){/* 取得News对象 */News ns=(News)li.get(position);/* new一个Intent对象,并指定class */Intent intent = new Intent();intent.setClass(EX08_13_1.this,EX08_13_2.class);/* new一个Bundle对象,并将要传递的数据传入 */Bundle bundle = new Bundle();bundle.putString("title",ns.getTitle());bundle.putString("desc",ns.getDesc());bundle.putString("link",ns.getLink());/* 将Bundle对象assign给Intent */intent.putExtras(bundle);/* 调用Activity EX08_13_2 */startActivity(intent);}/* 剖析XML的method */private List<News> getRss(String path){List<News> data=new ArrayList<News>();URL url = null;try{ url = new URL(path);/* 产生SAXParser对象 */ SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); /* 产生XMLReader对象 */ XMLReader xr = sp.getXMLReader(); /* 设定自定义的MyHandler给XMLReader */ MyHandler myExampleHandler = new MyHandler(); xr.setContentHandler(myExampleHandler);/* 解析XML */xr.parse(new InputSource(url.openStream()));/* 取得RSS标题与内容列表 */data =myExampleHandler.getParsedData(); title=myExampleHandler.getRssTitle();}catch (Exception e){ /* 发生错误时回传result回上一个activity */Intent intent=new Intent();Bundle bundle = new Bundle();bundle.putString("error",""+e);intent.putExtras(bundle);/* 错误的回传值设定为99 */EX08_13_1.this.setResult(99, intent);EX08_13_1.this.finish();}return data;}}

在上一个类中用到了Handler对象,下面给出这个类的介绍:

* 自定义的Handler对象,用来解析XML文件,并取得文件中的相关信息

* RSS返回的XML文件中,每一则新闻内容的起始为<item>,结束为</item>,格式如下:

*

* <item>

* <title>新闻标题</title>

* <guid isPermaLink="false">ID</guid>

* <link>新闻连接</link>

* <description>新闻描述</description>

* <pubDate>发布时间</pubDate>

* </item>

*

* MyHandler在解析上述XML文件内容的流程如下:

* 1.运行startDocument(),生成一个List<News>,作为存放News对象之用

* 2.当程序解析到Element的起始时,会运行startElement(),程序依据Element名称的不同,将其所对应的boolean

* 参数设置为true。

* 3.当程序解析到文件中的字符时(character),会运行characters()这个方法,将字符附加到(append)StringBuffer中

* 4.当程序解析到Element的结尾时会运行endElement(),程序依据Element名称的不同,将由StringBuffer转换成的字符串,

* 以setXXX()的方式把该属性写入News对象中,并把相对应的boolean变量设置为false。

实现代码如下:

public class MyHandler extends DefaultHandler{ /* 变量声明 */private boolean in_item = false;//News对象的四个属性标记private boolean in_title = false;private boolean in_link = false;private boolean in_desc = false;private boolean in_date = false;private boolean in_mainTitle = false;private List<News> li;private News news;private String title="";private StringBuffer buf=new StringBuffer();/* 将转换成List<News>的XML数据回传 */public List<News> getParsedData(){ return li; }/* 将解析出的RSS title回传 */public String getRssTitle(){ return title; }/* XML文件开始解析时调用此method */@Override public void startDocument() throws SAXException{ li = new ArrayList<News>(); } /* XML文件结束解析时调用此method */@Override public void endDocument() throws SAXException{} /* 解析到Element的开头时调用此method */@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException{ if (localName.equals("item")){ this.in_item = true;/* 解析到item的开头时new一个News对象 */news=new News();}else if (localName.equals("title")){ if(this.in_item){this.in_title = true;}else{this.in_mainTitle = true;}}else if (localName.equals("link")){ if(this.in_item){this.in_link = true;}}else if (localName.equals("description")){ if(this.in_item){this.in_desc = true;}}else if (localName.equals("pubDate")){ if(this.in_item){this.in_date = true;}} }/* 解析到Element的结尾时调用此method */@Override public void endElement(String namespaceURI, String localName,String qName) throws SAXException{ if (localName.equals("item")){ this.in_item = false;/* 解析到item的结尾时将News对象写入List中 */li.add(news);}else if (localName.equals("title")){ if(this.in_item){/* 设定News对象的title */news.setTitle(buf.toString().trim());buf.setLength(0);this.in_title = false;}else{/* 设定RSS的title */title=buf.toString().trim();buf.setLength(0);this.in_mainTitle = false;}}else if (localName.equals("link")){ if(this.in_item){/* 设定News对象的link */news.setLink(buf.toString().trim());buf.setLength(0);this.in_link = false;}}else if (localName.equals("description")){ if(in_item){/* 设定News对象的description */news.setDesc(buf.toString().trim());buf.setLength(0);this.in_desc = false;}}else if (localName.equals("pubDate")){ if(in_item){/* 设定News对象的pubDate */news.setDate(buf.toString().trim());buf.setLength(0);this.in_date = false;}} } /* 取得Element的开头结尾中间夹的字符串 */@Override public void characters(char ch[], int start, int length){ if(this.in_item||this.in_mainTitle){/* 将char[]加入StringBuffer */buf.append(ch,start,length);}} }

在前两个类中都用到了News这个类对象,这是对阅读文档对象的定义,代码文件如下:

* 这是一个JavaBean的类,用来存放每一篇新闻的详细信息。简单的说,每一个News对象就代表了一则新闻,News对象中的

*定义了的四个属性

*1.新闻的标题_title

*2.新闻的描述_desc

*3.网站的连接_link

*4.发布时间_date

public class News{ /* News的四个变数 */private String _title="";private String _link="";private String _desc="";private String _date="";public String getTitle(){ return _title; } public String getLink(){ return _link; }public String getDesc(){ return _desc; } public String getDate(){ return _date; }public void setTitle(String title){ _title=title; } public void setLink(String link){ _link=link; }public void setDesc(String desc){ _desc=desc; } public void setDate(String date){ _date=date; }}

第二个文件的主布局是一个ListView用来显示可阅读文档,下面给出提供数据的Adapter文件:

package irdc.ex08_13;/* import相关class */import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;/* 自定义的Adapter,继承android.widget.BaseAdapter */public class MyAdapter extends BaseAdapter{/* 变量声明 */private LayoutInflater mInflater;private List<News> items;/* MyAdapter的建构子,传入两个参数 */ public MyAdapter(Context context,List<News> it){/* 参数初始化 */mInflater = LayoutInflater.from(context);items = it;}/* 因继承BaseAdapter,需重写以下method */@Overridepublic int getCount(){return items.size();}@Overridepublic Object getItem(int position){return items.get(position);}@Overridepublic long getItemId(int position){return position;}@Overridepublic View getView(int position,View convertView,ViewGroup par){ViewHolder holder;if(convertView == null){/* 使用自定义的news_row作为Layout */convertView = mInflater.inflate(R.layout.news_row, null);/* 初始化holder的text与icon */holder = new ViewHolder();holder.text = (TextView) convertView.findViewById(R.id.text);convertView.setTag(holder);}else{holder = (ViewHolder) convertView.getTag();}News tmpN=(News)items.get(position);holder.text.setText(tmpN.getTitle());return convertView;}/* class ViewHolder */private class ViewHolder{TextView text;}}

之后,当我们点击一条信息之后,就会进入下一界面,实现的截图如下:

我们只需要点击其中的链接,就可以打开相应的网页文件,截图如下:

实现的代码如下:

注意,打开网页是调用系统自带的浏览器:

package irdc.ex08_13;/* import相关class */import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.text.util.Linkify;import android.widget.TextView;public class EX08_13_2 extends Activity{/* 变量声明 */private TextView mTitle;private TextView mDesc;private TextView mLink;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);/* 设定layout为newscontent.xml */setContentView(R.layout.newscontent);/* 初始化对象 */mTitle=(TextView) findViewById(R.id.myTitle);mDesc=(TextView) findViewById(R.id.myDesc);mLink=(TextView) findViewById(R.id.myLink);/* 取得Intent中的Bundle对象 */Intent intent=this.getIntent();Bundle bunde = intent.getExtras();/* 取得Bundle对象中的数据 */mTitle.setText(bunde.getString("title"));mDesc.setText(bunde.getString("desc")+"....");mLink.setText(bunde.getString("link"));/* 设定mLink为网页连结 */Linkify.addLinks(mLink,Linkify.WEB_URLS);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。