基于Android平台的新闻客户端的设计与实现

实习项目四、

基于Android 平台的新闻客户端的

设计与实现

专 业:

学 号:

姓 名:ls

辅导老师:

2015年7月7日

目 录

第1章 诸论 ................................................... 3 1.1 开发背景 .................................................. 3 1.2 开发工具的选用及介绍 ...................................... 3 1.3 开发环境介绍 .............................................. 4 第2章 系统分析与设计流程 .................................... 5 2.1 服务器和数据库的搭建 ...................................... 5 2.2 使用 PHP 生成新闻 JSON 数据 . ............................... 6 2.3 实现新闻列表界面的布局 .................................... 8 2.4 实现新闻列表界面的 JSON 数据解析和填充 .................... 9 2.5 实现新闻列表界面的跳转并展示详情 ......................... 11 结束语 ....................................................... 12 附录 ......................................................... 13

第1章 诸论

1.1 开发背景

移动互联网背景下,手机凭借其随时随地、移动与便携等优势发展成为重要的大众传播媒体,成为媒介融合的新平台。移动新闻客户端凭借其丰富的资讯资源、实时的信息推送被越来越多的用户认可。对于各行各业来说,为了展示企业良好形象,新闻客户端是面向用户中必不可少的一部分。

1.2 开发工具的选用及介绍

1. PHP 生成 JSON 数据:PHP (外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C 语言、Java 和Perl 的特点,利于学习,使用广泛,主要适用于Web 开发领域。JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。本文利用PHP 文件解析数据库表,生成JSON 数据。 2.HBuilder :HBuilder 是DCloud (数字天堂)推出一款支持html5的Web 开发ide 。快,是HBuilder 的最大优势,通过完整的语法提示和代码输入法、代码块及很多配套,HBuilder 能大幅提升html 、js 、css 的开发效率。本文利用HBuilder 来编写PHP 文件。

3.XAMPP :XAMPP (Apache+MySQL+PHP+PERL)是一个功能强大的建 XAMPP 软件站集成软件包。许多人通过他们自己的经验认识到安装 Apache 服务器是件不容易的事儿。如果想添加 MySQL 、PHP 和 Perl ,那就更难了。XAMPP 是一个易于安装且包含 MySQL 、PHP 和 Perl 的 Apache 发行版。XAMPP 的确非常容易安装和使用:只需下载,解压缩,启动即可。本文通过XAMPP 搭建

Apache 服务器和MySQL 数据库。

4.Eclipse :Eclipse 是一个开放源代码的、基于Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java 开发工具(Java Development Kit ,JDK )。本文以Eclipse 为工具,以Android 为平台,开发一个简单的新闻客户端应用,实现新闻列表界面的布局、JSON 数据解析和填充、以及新闻列表界面的跳转并显示详情。

1.3 开发环境介绍

基于Android 平台的新闻客户端项目所用数据库为MySQL ,服务器为Apache ,主要开发工具为eclipse ,在Android 平台实现,程序运行环境为windows 8,内存4G ,源码详见附录。

第2章 系统分析与设计流程

本章主要利用Apache+MyAQL+Android,采用边开发边分析的方法,搭建了一个简单的、可运行的Android 新闻客户端服务系统,实现了从服务器端获取数据并显示在应用界面,点击时跳转到新闻详情页面的功能。

2.1 服务器和数据库的搭建

图2-1 用XAMPP 启动Apache 和MySQL

服务器的架设是在本机上完成,装上XAMPP 软件包后打开,如图2-1,启动Apache 服务器和MySQL 数据库,点击Admin 进入管理界面,新建一个名为newsdemo 的数据库,排序规则为utf8,然后建立一个名为news 的数据库表,创建六个字段,然后插入两条相应的新闻数据,如图2-2。

图2-2 数据库界面

2.2 使用 PHP 生成新闻 JSON 数据

图2-3 数据库表news

如图2-3,数据库中的表news ,有六个字段,第一个字段叫做id ,是新闻的序号,序号作为新闻的主键,使每条新闻不重复,与新闻内容有关的是另外五个字段:title (标题),desc (新闻简要概述),time (新闻时间),content_url(新闻内容链接),pic_url(新闻图片链接)。最终实现的效果是通过一个PHP 网

页,即http ://xxx/getNewsJSON.php,将表中的所有数据转换为JSON 数据的格式,就可以得到图下方的JSON 字符串,即一个数组包裹的JSON 对象,其中包含了5个键值对,分别为新闻的5个元素。

图2-4 用Hbuilder 编写PHP 文件

如图2-4,通过HBuider 编辑器编写PHP 网页,连接数据库,并把当前的数据输出为JSON 格式,新建一个getNewsJSON.php 文件用来获得JSON 数据,和一个mysql_connect.php文件用来连接数据库,代码详见附录。

因为服务器搭建在本机,在浏览器中访问地址http://127.0.0.1/NewsDemo/getNewsJSON.php,可以看到这时生成了格式为utf-8的JSON 数据,如图2-5,证明数据解析成功。

图2-5 本机测试浏览JSON 数据

2.3 实现新闻列表界面的布局

本节主要完成了在Android 界面中实现新闻列表界面的布局,主界面采用垂直线性布局,完成新闻列表项listview ,声明一个NewsAdapter 的类使其继承自BaseAdapter ,并实现图2-6的四个方法。

图2-6 adapter实现的四个方法

其中第四个方法getView ()是非常重要的,如图2-7,在News2程序界面的最外层是一个listview ,它里面有两项,对应了两条新闻,getView 是指的其中某一项的布局,也就是右边的view ,包括了新闻缩略图,新闻标题,新闻梗概,和布局右上侧的新闻时间,用NewsAdapter 将新闻与布局适配起来。

图2-7 getView方法的使用

2.4 实现新闻列表界面的 JSON 数据解析和填充

首先要有一个获取JSON 字符串的网络地址,即public static final String GET_NEWS_URL="http://192.168.191.1/NewsDemo/getNewsJSON.php";因为服务器软件是在本机运行的,所以192.168.191.1为本机的IP 地址,打开浏览器,输入http://192.168.191.1/NewsDemo/getNewsJSON.php,如图2-8,可以看到,确实从外网访问到了我本机的IP ,并且取到了getNewsJSON 所生成的这个字符串。

图2-8 利用IP 测试浏览JSON 数据

因为我们要访问网络,所以要写一个HttpUtils 的工具类,实现getNewsJSON ()方法,用来传入获取到JSON 数据的url 并解析JSON 数据,首先用new Thread()方法开启一个线程,开启输入流,一行一行的读取数据,每读完一行就要进行拼接,因为在字符串拼接方面StringBuilder 要比单纯的String 的那种“+”的方式要高效很多,所以这里使用StringBuilder 方法拼接。获取到JSON 数据后,调用handler.sendmessage ()方法通知主线程。然后再在MainActivity 当中实现Handler ()方法,调用其中的handlerMessage ()回调方法获取到JSON 数据,下一步就是对其进行解析。

因为JSON 数据格式为数组,它里面有若干个JSON 的对象,对于JSON 数据的解析,可以看下下面的代码,首先将获取到的jsonData 传递进来,

jsonArray.length()获取到JSON 对象的个数,然后写一个循环来获取到JSON 里的每一个对象。

JSONArray jsonArray = new JSONArray(jsonData); for (int i=0;i

JSONObject object = jsonArray.getJSONObject(i); String title = object.getString("title"); String desc = object.getString("desc"); „„

}

这样解析出来了还远远不够,得到的数据现在还是分散的,在组织上看起来比较杂乱无章,为了能让这些数据更好的组织起来,就是每个新闻对应5个元素,另一个新闻也对应5个元素,那么这时候我们在新建一个javabean 的类,比如说它叫News ,那么这个News 对象它里面就有5个属性,分别对应了新闻的5个元组,通过这种方式就可以很好地把获取到的数据有序的组织起来,方便后面的使用,方法里的成员属性和构造方法如下,并实现get ()和set ()方法。

public class News {

private String title; private String desc; private String time; private String content_url; private String pic_url;

public News(String title ,String desc,String time,String content_url,String, pic_url){ setTitle(title);

}

}

setDesc(desc); setTime(time);

setContent_url(content_url); setPic_url(pic_url);

在MainActivity 中定义一个List 集合,集合里的每个元素都是News 类型,叫做newslist ,在OnCreate ()方法中初始化newslist 后,就可以将解析完的JSON 对象的5个元素添加到newslist 里面,更新adapter 方法,并将List添加到成员属性和构造方法中。对于图片的加载,由于需要访问网络,则需在HttpUtils 工具类里用setPicBitmap()方法实现。

2.5 实现新闻列表界面的跳转并展示详情

对listview 添加点击事件,来实现点击相应的新闻列表项可以查看相应的新闻详情。实现机制如图2-9,在MainActivity 中就很多的新闻条目,点击某一个新闻条目的时候,将这个新闻项的content_url,也就是这个新闻的具体地址传递给一个Activity ,例如叫做BrowseNewsActivity ,用来浏览新闻,里面只有一个控件WebView ,WebView 相当于一个提供好的自带的浏览器,可以直接调用webView.loadUrl(),将content_url这个地址传递进去,在WebView 上加载出这个网页,根据这个思路,需要新建一个BrowseNewsActivity 以及对应的布局文件,用getSettings().setJavaScriptEnabled(true)方法启用当前WebView 的JavaScript , 就像当前页面中的

JavaScript

代码;用

getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK)方法设置为,当没有网络时读取本地的缓存,有网络的时候就直接访问。

图2-9 单击跳转的实现机制

在MainAcitivity 中添加OnItemClickListener 点击事件, 并实现未实现的方法onItemClick (),在此方法中获取到新闻的地址conten_url,并传递到BrowseNewsActivity 当中去,然后在BrowseNewsActivity 中用getIntent ()方法获取到新闻地址,直接调用webView.loadUrl()函数将地址传入,最后将BrowseNewsActivity 加入到AndroidManifest 中就可以了。

结束语

经过老师耐心细致的指导,及设计小组同学们的密切合作,同时翻阅了大量的资料(包括网上资料,书本及学校的一些相关资料) ,项目已经初步完成,总结这次“基于Android 平台的新闻客户端”开发制作过程,我们综合使用了目前互联网上的各种工具,包括使用XAMPP 搭建服务器和数据库,使用HBuidler 设计PHP 文件等,初步在Android 平台上实现了这个简单的新闻客户端。同时通过解决项目中遇到的各类问题(比如由于本地搭建服务器,在真机测试时获取不到JSON 数据,获取到了数据填充不上等问题磨了很长时间才解决),对用Android 开发应用有了更进一步的认识。学会了如何使用MYSQL 建立数据库,以及对数据库浏览,修改,添加,查询;学会了如何用PHP 解析JSON 数据等;受益匪浅。

由于课程设计者水平有限,错误之处在所难免,请老师批评指正。

附录

MainActivity.java

package com.example.news2; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; import com.example.news2.R;

import com.example.news2.adapter.NewsAdapter; import com.example.news2.model.News; import com.example.news2.utils.HttpUtils; import android.support.v7.app.ActionBarActivity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; public

class

MainActivity

extends

ActionBarActivity

OnItemClickListener {

private ListView lvNews; private NewsAdapter adapter; private List newsList;

public

static

final

implements

String

GET_NEWS_URL="http://192.168.191.1/NewsDemo/getNewsJSON.php";

private Handler getNewsHander=new Handler(){

public void handleMessage(android.os.Message msg) {

String jsonData=(String) msg.obj; System.out.println(jsonData); try {

JSONArray jsonArray=new JSONArray(jsonData); for(int i=0;i

JSONObject object=jsonArray.getJSONObject(i); String title=object.getString("title"); String desc=object.getString("desc"); String time=object.getString("time");

String content_url=object.getString("content_url"); String pic_url=object.getString("pic_url");

System.out.println("title="+title); System.out.println("pic_url="+pic_url);

newsList.add(new

News(title,desc,time,content_url,pic_url));

};

};

}

adapter.notifyDataSetChanged();

} catch (Exception e) { }

e.printStackTrace();

@Override

protected void onCreate(Bundle savedInstanceState) {

arg3) {

}

}

super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

lvNews=(ListView) findViewById(R.id.lvNews); newsList=new ArrayList(); adapter=new NewsAdapter(this,newsList);

lvNews.setAdapter(adapter); lvNews.setOnItemClickListener(this);

HttpUtils.getNewsJSON(GET_NEWS_URL, getNewsHander);

@Override

public void onItemClick(AdapterView arg0, View arg1, int position, long

}

News news=newsList.get(position);

Intent intent=new Intent(this,BrowseNewsActivity.class); intent.putExtra("content_url", news.getContent_url()); startActivity(intent);

BrowseNewsActivity.java package com.example.news2;

import com.example.news2.R;

import android.app.Activity; import android.os.Bundle; import android.webkit.WebSettings;

public class BrowseNewsActivity extends Activity {

private WebView webView; @Override

protected void onCreate(Bundle savedInstanceState) {

webView.loadUrl(pic_url); super.onCreate(savedInstanceState);

setContentView(R.layout.activity_browse_news);

webView=(WebView) findViewById(R.id.webView); String pic_url=getIntent().getStringExtra("content_url");

webView.getSettings().setJavaScriptEnabled(true);

webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_

NETWORK);

}

}

NewsAdapter.java

package com.example.news2.adapter; import java.util.List;

import com.example.news2.R;

import com.example.news2.model.News; import com.example.news2.utils.HttpUtils; import android.content.Context; import android.view.LayoutInflater; import android.view.View;

import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;

public class NewsAdapter extends BaseAdapter {

private Context context; private List newsList;

public NewsAdapter(Context context,List newsList){ } @Override

public int getCount() { }

return newsList.size(); this.context=context; this.newsList=newsList;

@Override

public Object getItem(int position) { } @Override

public long getItemId(int position) { } @Override

public View getView(int position, View convertView, ViewGroup parent) {

if(convertView==null){ return position;

return newsList.get(position);

convertView=LayoutInflater.from(context).inflate(R.layout.news_item, null);

}

}

}

TextView tvDesc=(TextView) convertView.findViewById(R.id.tvDesc); TextView tvTime=(TextView) convertView.findViewById(R.id.tvTime); ImageView ivPic=(ImageView) convertView.findViewById(R.id.ivPic); News news=newsList.get(position); tvTitle.setText(news.getTitle()); tvDesc.setText(news.getDesc()); tvTime.setText(news.getTime()); String pic_url=news.getPic_url(); HttpUtils.setPicBitmap(ivPic, pic_url); return convertView;

News.java

package com.example.news2.adapter; import java.util.List;

import com.example.news2.R;

import com.example.news2.model.News; import com.example.news2.utils.HttpUtils; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;

public class NewsAdapter extends BaseAdapter {

private Context context; private List newsList;

} @Override

public int getCount() { }

return newsList.size(); this.context=context; this.newsList=newsList;

@Override

public Object getItem(int position) { } @Override

public long getItemId(int position) { } @Override

public View getView(int position, View convertView, ViewGroup parent) {

if(convertView==null){ return position;

return newsList.get(position);

convertView=LayoutInflater.from(context).inflate(R.layout.news_item, null);

}

TextView tvTitle=(TextView) convertView.findViewById(R.id.tvTitle); TextView tvDesc=(TextView) convertView.findViewById(R.id.tvDesc); TextView tvTime=(TextView) convertView.findViewById(R.id.tvTime); ImageView ivPic=(ImageView) convertView.findViewById(R.id.ivPic); News news=newsList.get(position); tvTitle.setText(news.getTitle()); tvDesc.setText(news.getDesc()); tvTime.setText(news.getTime());

}

}

HttpUtils.setPicBitmap(ivPic, pic_url); return convertView;

HttpUtils.java

package com.example.news2.utils;

import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;

import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.os.Message; import android.widget.ImageView;

public class HttpUtils {

public static void getNewsJSON(final String url,final Handler handler){

new Thread(new Runnable(){

@Override public void run() {

HttpURLConnection conn; InputStream is; try {

conn=(HttpURLConnection) new URL(url).openConnection();

conn.setRequestMethod("GET"); is=conn.getInputStream(); BufferedReader reader=new BufferedReader(new InputStreamReader(is));

} public static void setPicBitmap(final ImageView ivPic,final String pic_url){ new Thread(new Runnable() { @Override public void run() { try { HttpURLConnection conn=(HttpURLConnection) new } String line=""; StringBuilder result=new StringBuilder(); while((line=reader.readLine())!=null){ } Message msg=new Message(); msg.obj=result.toString(); handler.sendMessage(msg); result.append(line); } catch (Exception e) { } e.printStackTrace(); }).start(); URL(pic_url).openConnection();

conn.connect();

} } } Bitmap bitmap=BitmapFactory.decodeStream(is); ivPic.setImageBitmap(bitmap); is.close(); } catch (Exception e) { } e.printStackTrace(); }).start();

getNewsJSON.php

/*

* 获得JSON 数据

* 返回值:title desc time content_url pic_url */

require 'mysql_connect.php';

$n=0;

$result=mysql_query("select * from news"); while($row=mysql_fetch_array($result)){ $arr[$n++]=array(

"title"=>$row['title'],

"desc"=>$row['desc'],

"time"=>$row['time'],

"content_url"=>$row['content_url'], "pic_url"=>$row['pic_url'],

);

//数组转换为JSON 字符串 echo json_encode($arr); ?>

mysql_connect.php

?> $con = mysql_connect("localhost","root",""); //设置字符集为utf8 mysql_query("SET NAMES 'utf8'"); mysql_query("SET CHARACTER SET utf8"); mysql_query("SET CHARACTER_SET_RESULT=utf8"); if(!$con){ } mysql_select_db("newsdemo",$con); die(mysql_error());

实习项目四、

基于Android 平台的新闻客户端的

设计与实现

专 业:

学 号:

姓 名:ls

辅导老师:

2015年7月7日

目 录

第1章 诸论 ................................................... 3 1.1 开发背景 .................................................. 3 1.2 开发工具的选用及介绍 ...................................... 3 1.3 开发环境介绍 .............................................. 4 第2章 系统分析与设计流程 .................................... 5 2.1 服务器和数据库的搭建 ...................................... 5 2.2 使用 PHP 生成新闻 JSON 数据 . ............................... 6 2.3 实现新闻列表界面的布局 .................................... 8 2.4 实现新闻列表界面的 JSON 数据解析和填充 .................... 9 2.5 实现新闻列表界面的跳转并展示详情 ......................... 11 结束语 ....................................................... 12 附录 ......................................................... 13

第1章 诸论

1.1 开发背景

移动互联网背景下,手机凭借其随时随地、移动与便携等优势发展成为重要的大众传播媒体,成为媒介融合的新平台。移动新闻客户端凭借其丰富的资讯资源、实时的信息推送被越来越多的用户认可。对于各行各业来说,为了展示企业良好形象,新闻客户端是面向用户中必不可少的一部分。

1.2 开发工具的选用及介绍

1. PHP 生成 JSON 数据:PHP (外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C 语言、Java 和Perl 的特点,利于学习,使用广泛,主要适用于Web 开发领域。JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。本文利用PHP 文件解析数据库表,生成JSON 数据。 2.HBuilder :HBuilder 是DCloud (数字天堂)推出一款支持html5的Web 开发ide 。快,是HBuilder 的最大优势,通过完整的语法提示和代码输入法、代码块及很多配套,HBuilder 能大幅提升html 、js 、css 的开发效率。本文利用HBuilder 来编写PHP 文件。

3.XAMPP :XAMPP (Apache+MySQL+PHP+PERL)是一个功能强大的建 XAMPP 软件站集成软件包。许多人通过他们自己的经验认识到安装 Apache 服务器是件不容易的事儿。如果想添加 MySQL 、PHP 和 Perl ,那就更难了。XAMPP 是一个易于安装且包含 MySQL 、PHP 和 Perl 的 Apache 发行版。XAMPP 的确非常容易安装和使用:只需下载,解压缩,启动即可。本文通过XAMPP 搭建

Apache 服务器和MySQL 数据库。

4.Eclipse :Eclipse 是一个开放源代码的、基于Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java 开发工具(Java Development Kit ,JDK )。本文以Eclipse 为工具,以Android 为平台,开发一个简单的新闻客户端应用,实现新闻列表界面的布局、JSON 数据解析和填充、以及新闻列表界面的跳转并显示详情。

1.3 开发环境介绍

基于Android 平台的新闻客户端项目所用数据库为MySQL ,服务器为Apache ,主要开发工具为eclipse ,在Android 平台实现,程序运行环境为windows 8,内存4G ,源码详见附录。

第2章 系统分析与设计流程

本章主要利用Apache+MyAQL+Android,采用边开发边分析的方法,搭建了一个简单的、可运行的Android 新闻客户端服务系统,实现了从服务器端获取数据并显示在应用界面,点击时跳转到新闻详情页面的功能。

2.1 服务器和数据库的搭建

图2-1 用XAMPP 启动Apache 和MySQL

服务器的架设是在本机上完成,装上XAMPP 软件包后打开,如图2-1,启动Apache 服务器和MySQL 数据库,点击Admin 进入管理界面,新建一个名为newsdemo 的数据库,排序规则为utf8,然后建立一个名为news 的数据库表,创建六个字段,然后插入两条相应的新闻数据,如图2-2。

图2-2 数据库界面

2.2 使用 PHP 生成新闻 JSON 数据

图2-3 数据库表news

如图2-3,数据库中的表news ,有六个字段,第一个字段叫做id ,是新闻的序号,序号作为新闻的主键,使每条新闻不重复,与新闻内容有关的是另外五个字段:title (标题),desc (新闻简要概述),time (新闻时间),content_url(新闻内容链接),pic_url(新闻图片链接)。最终实现的效果是通过一个PHP 网

页,即http ://xxx/getNewsJSON.php,将表中的所有数据转换为JSON 数据的格式,就可以得到图下方的JSON 字符串,即一个数组包裹的JSON 对象,其中包含了5个键值对,分别为新闻的5个元素。

图2-4 用Hbuilder 编写PHP 文件

如图2-4,通过HBuider 编辑器编写PHP 网页,连接数据库,并把当前的数据输出为JSON 格式,新建一个getNewsJSON.php 文件用来获得JSON 数据,和一个mysql_connect.php文件用来连接数据库,代码详见附录。

因为服务器搭建在本机,在浏览器中访问地址http://127.0.0.1/NewsDemo/getNewsJSON.php,可以看到这时生成了格式为utf-8的JSON 数据,如图2-5,证明数据解析成功。

图2-5 本机测试浏览JSON 数据

2.3 实现新闻列表界面的布局

本节主要完成了在Android 界面中实现新闻列表界面的布局,主界面采用垂直线性布局,完成新闻列表项listview ,声明一个NewsAdapter 的类使其继承自BaseAdapter ,并实现图2-6的四个方法。

图2-6 adapter实现的四个方法

其中第四个方法getView ()是非常重要的,如图2-7,在News2程序界面的最外层是一个listview ,它里面有两项,对应了两条新闻,getView 是指的其中某一项的布局,也就是右边的view ,包括了新闻缩略图,新闻标题,新闻梗概,和布局右上侧的新闻时间,用NewsAdapter 将新闻与布局适配起来。

图2-7 getView方法的使用

2.4 实现新闻列表界面的 JSON 数据解析和填充

首先要有一个获取JSON 字符串的网络地址,即public static final String GET_NEWS_URL="http://192.168.191.1/NewsDemo/getNewsJSON.php";因为服务器软件是在本机运行的,所以192.168.191.1为本机的IP 地址,打开浏览器,输入http://192.168.191.1/NewsDemo/getNewsJSON.php,如图2-8,可以看到,确实从外网访问到了我本机的IP ,并且取到了getNewsJSON 所生成的这个字符串。

图2-8 利用IP 测试浏览JSON 数据

因为我们要访问网络,所以要写一个HttpUtils 的工具类,实现getNewsJSON ()方法,用来传入获取到JSON 数据的url 并解析JSON 数据,首先用new Thread()方法开启一个线程,开启输入流,一行一行的读取数据,每读完一行就要进行拼接,因为在字符串拼接方面StringBuilder 要比单纯的String 的那种“+”的方式要高效很多,所以这里使用StringBuilder 方法拼接。获取到JSON 数据后,调用handler.sendmessage ()方法通知主线程。然后再在MainActivity 当中实现Handler ()方法,调用其中的handlerMessage ()回调方法获取到JSON 数据,下一步就是对其进行解析。

因为JSON 数据格式为数组,它里面有若干个JSON 的对象,对于JSON 数据的解析,可以看下下面的代码,首先将获取到的jsonData 传递进来,

jsonArray.length()获取到JSON 对象的个数,然后写一个循环来获取到JSON 里的每一个对象。

JSONArray jsonArray = new JSONArray(jsonData); for (int i=0;i

JSONObject object = jsonArray.getJSONObject(i); String title = object.getString("title"); String desc = object.getString("desc"); „„

}

这样解析出来了还远远不够,得到的数据现在还是分散的,在组织上看起来比较杂乱无章,为了能让这些数据更好的组织起来,就是每个新闻对应5个元素,另一个新闻也对应5个元素,那么这时候我们在新建一个javabean 的类,比如说它叫News ,那么这个News 对象它里面就有5个属性,分别对应了新闻的5个元组,通过这种方式就可以很好地把获取到的数据有序的组织起来,方便后面的使用,方法里的成员属性和构造方法如下,并实现get ()和set ()方法。

public class News {

private String title; private String desc; private String time; private String content_url; private String pic_url;

public News(String title ,String desc,String time,String content_url,String, pic_url){ setTitle(title);

}

}

setDesc(desc); setTime(time);

setContent_url(content_url); setPic_url(pic_url);

在MainActivity 中定义一个List 集合,集合里的每个元素都是News 类型,叫做newslist ,在OnCreate ()方法中初始化newslist 后,就可以将解析完的JSON 对象的5个元素添加到newslist 里面,更新adapter 方法,并将List添加到成员属性和构造方法中。对于图片的加载,由于需要访问网络,则需在HttpUtils 工具类里用setPicBitmap()方法实现。

2.5 实现新闻列表界面的跳转并展示详情

对listview 添加点击事件,来实现点击相应的新闻列表项可以查看相应的新闻详情。实现机制如图2-9,在MainActivity 中就很多的新闻条目,点击某一个新闻条目的时候,将这个新闻项的content_url,也就是这个新闻的具体地址传递给一个Activity ,例如叫做BrowseNewsActivity ,用来浏览新闻,里面只有一个控件WebView ,WebView 相当于一个提供好的自带的浏览器,可以直接调用webView.loadUrl(),将content_url这个地址传递进去,在WebView 上加载出这个网页,根据这个思路,需要新建一个BrowseNewsActivity 以及对应的布局文件,用getSettings().setJavaScriptEnabled(true)方法启用当前WebView 的JavaScript , 就像当前页面中的

JavaScript

代码;用

getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK)方法设置为,当没有网络时读取本地的缓存,有网络的时候就直接访问。

图2-9 单击跳转的实现机制

在MainAcitivity 中添加OnItemClickListener 点击事件, 并实现未实现的方法onItemClick (),在此方法中获取到新闻的地址conten_url,并传递到BrowseNewsActivity 当中去,然后在BrowseNewsActivity 中用getIntent ()方法获取到新闻地址,直接调用webView.loadUrl()函数将地址传入,最后将BrowseNewsActivity 加入到AndroidManifest 中就可以了。

结束语

经过老师耐心细致的指导,及设计小组同学们的密切合作,同时翻阅了大量的资料(包括网上资料,书本及学校的一些相关资料) ,项目已经初步完成,总结这次“基于Android 平台的新闻客户端”开发制作过程,我们综合使用了目前互联网上的各种工具,包括使用XAMPP 搭建服务器和数据库,使用HBuidler 设计PHP 文件等,初步在Android 平台上实现了这个简单的新闻客户端。同时通过解决项目中遇到的各类问题(比如由于本地搭建服务器,在真机测试时获取不到JSON 数据,获取到了数据填充不上等问题磨了很长时间才解决),对用Android 开发应用有了更进一步的认识。学会了如何使用MYSQL 建立数据库,以及对数据库浏览,修改,添加,查询;学会了如何用PHP 解析JSON 数据等;受益匪浅。

由于课程设计者水平有限,错误之处在所难免,请老师批评指正。

附录

MainActivity.java

package com.example.news2; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; import com.example.news2.R;

import com.example.news2.adapter.NewsAdapter; import com.example.news2.model.News; import com.example.news2.utils.HttpUtils; import android.support.v7.app.ActionBarActivity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; public

class

MainActivity

extends

ActionBarActivity

OnItemClickListener {

private ListView lvNews; private NewsAdapter adapter; private List newsList;

public

static

final

implements

String

GET_NEWS_URL="http://192.168.191.1/NewsDemo/getNewsJSON.php";

private Handler getNewsHander=new Handler(){

public void handleMessage(android.os.Message msg) {

String jsonData=(String) msg.obj; System.out.println(jsonData); try {

JSONArray jsonArray=new JSONArray(jsonData); for(int i=0;i

JSONObject object=jsonArray.getJSONObject(i); String title=object.getString("title"); String desc=object.getString("desc"); String time=object.getString("time");

String content_url=object.getString("content_url"); String pic_url=object.getString("pic_url");

System.out.println("title="+title); System.out.println("pic_url="+pic_url);

newsList.add(new

News(title,desc,time,content_url,pic_url));

};

};

}

adapter.notifyDataSetChanged();

} catch (Exception e) { }

e.printStackTrace();

@Override

protected void onCreate(Bundle savedInstanceState) {

arg3) {

}

}

super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

lvNews=(ListView) findViewById(R.id.lvNews); newsList=new ArrayList(); adapter=new NewsAdapter(this,newsList);

lvNews.setAdapter(adapter); lvNews.setOnItemClickListener(this);

HttpUtils.getNewsJSON(GET_NEWS_URL, getNewsHander);

@Override

public void onItemClick(AdapterView arg0, View arg1, int position, long

}

News news=newsList.get(position);

Intent intent=new Intent(this,BrowseNewsActivity.class); intent.putExtra("content_url", news.getContent_url()); startActivity(intent);

BrowseNewsActivity.java package com.example.news2;

import com.example.news2.R;

import android.app.Activity; import android.os.Bundle; import android.webkit.WebSettings;

public class BrowseNewsActivity extends Activity {

private WebView webView; @Override

protected void onCreate(Bundle savedInstanceState) {

webView.loadUrl(pic_url); super.onCreate(savedInstanceState);

setContentView(R.layout.activity_browse_news);

webView=(WebView) findViewById(R.id.webView); String pic_url=getIntent().getStringExtra("content_url");

webView.getSettings().setJavaScriptEnabled(true);

webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_

NETWORK);

}

}

NewsAdapter.java

package com.example.news2.adapter; import java.util.List;

import com.example.news2.R;

import com.example.news2.model.News; import com.example.news2.utils.HttpUtils; import android.content.Context; import android.view.LayoutInflater; import android.view.View;

import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;

public class NewsAdapter extends BaseAdapter {

private Context context; private List newsList;

public NewsAdapter(Context context,List newsList){ } @Override

public int getCount() { }

return newsList.size(); this.context=context; this.newsList=newsList;

@Override

public Object getItem(int position) { } @Override

public long getItemId(int position) { } @Override

public View getView(int position, View convertView, ViewGroup parent) {

if(convertView==null){ return position;

return newsList.get(position);

convertView=LayoutInflater.from(context).inflate(R.layout.news_item, null);

}

}

}

TextView tvDesc=(TextView) convertView.findViewById(R.id.tvDesc); TextView tvTime=(TextView) convertView.findViewById(R.id.tvTime); ImageView ivPic=(ImageView) convertView.findViewById(R.id.ivPic); News news=newsList.get(position); tvTitle.setText(news.getTitle()); tvDesc.setText(news.getDesc()); tvTime.setText(news.getTime()); String pic_url=news.getPic_url(); HttpUtils.setPicBitmap(ivPic, pic_url); return convertView;

News.java

package com.example.news2.adapter; import java.util.List;

import com.example.news2.R;

import com.example.news2.model.News; import com.example.news2.utils.HttpUtils; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;

public class NewsAdapter extends BaseAdapter {

private Context context; private List newsList;

} @Override

public int getCount() { }

return newsList.size(); this.context=context; this.newsList=newsList;

@Override

public Object getItem(int position) { } @Override

public long getItemId(int position) { } @Override

public View getView(int position, View convertView, ViewGroup parent) {

if(convertView==null){ return position;

return newsList.get(position);

convertView=LayoutInflater.from(context).inflate(R.layout.news_item, null);

}

TextView tvTitle=(TextView) convertView.findViewById(R.id.tvTitle); TextView tvDesc=(TextView) convertView.findViewById(R.id.tvDesc); TextView tvTime=(TextView) convertView.findViewById(R.id.tvTime); ImageView ivPic=(ImageView) convertView.findViewById(R.id.ivPic); News news=newsList.get(position); tvTitle.setText(news.getTitle()); tvDesc.setText(news.getDesc()); tvTime.setText(news.getTime());

}

}

HttpUtils.setPicBitmap(ivPic, pic_url); return convertView;

HttpUtils.java

package com.example.news2.utils;

import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;

import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.os.Message; import android.widget.ImageView;

public class HttpUtils {

public static void getNewsJSON(final String url,final Handler handler){

new Thread(new Runnable(){

@Override public void run() {

HttpURLConnection conn; InputStream is; try {

conn=(HttpURLConnection) new URL(url).openConnection();

conn.setRequestMethod("GET"); is=conn.getInputStream(); BufferedReader reader=new BufferedReader(new InputStreamReader(is));

} public static void setPicBitmap(final ImageView ivPic,final String pic_url){ new Thread(new Runnable() { @Override public void run() { try { HttpURLConnection conn=(HttpURLConnection) new } String line=""; StringBuilder result=new StringBuilder(); while((line=reader.readLine())!=null){ } Message msg=new Message(); msg.obj=result.toString(); handler.sendMessage(msg); result.append(line); } catch (Exception e) { } e.printStackTrace(); }).start(); URL(pic_url).openConnection();

conn.connect();

} } } Bitmap bitmap=BitmapFactory.decodeStream(is); ivPic.setImageBitmap(bitmap); is.close(); } catch (Exception e) { } e.printStackTrace(); }).start();

getNewsJSON.php

/*

* 获得JSON 数据

* 返回值:title desc time content_url pic_url */

require 'mysql_connect.php';

$n=0;

$result=mysql_query("select * from news"); while($row=mysql_fetch_array($result)){ $arr[$n++]=array(

"title"=>$row['title'],

"desc"=>$row['desc'],

"time"=>$row['time'],

"content_url"=>$row['content_url'], "pic_url"=>$row['pic_url'],

);

//数组转换为JSON 字符串 echo json_encode($arr); ?>

mysql_connect.php

?> $con = mysql_connect("localhost","root",""); //设置字符集为utf8 mysql_query("SET NAMES 'utf8'"); mysql_query("SET CHARACTER SET utf8"); mysql_query("SET CHARACTER_SET_RESULT=utf8"); if(!$con){ } mysql_select_db("newsdemo",$con); die(mysql_error());


相关文章

  • (完整版)基于安卓的网上订餐系统毕业设计
  • 摘 要 在科学技术高度发展的当今社会,网络信息化已经成为时代的潮 流.随着计算机技术的不断更新变化,特别是Android 操作系统的出现,使移动互联网业务更加蓬勃的发展.根据专家的调查和研究,发现传统的订餐模式已经不能适应市场的高速发展.因 ...查看


  • 基于安卓的校园快递
  • 基于Android 的校园快递平台的设计与实现 摘 要:随着智能手机的普及以及移动互联网的快速发展,很多人尤其是在校大学生已经习惯于 使用手机应用来享受生活的便利.本文设计了一款基于Android 的校园快递平台,该平台可以方便快递人员进行 ...查看


  • 基于安卓平台的中国象棋游戏的开发
  • 摘 要:目前,随着科技的不断发展,通信技术得到了长足的进步,如Pad,手机等数字产品成为人们日常生活中必不可少的重要组成部分,现在的手机等移动通信设备不仅具有通信这项单一的功能,还逐渐演变成一个可以移动的微机系统,为人们提供丰富的信息和服务 ...查看


  • 厦门大学"随行"创业计划书
  • 厦门大学"随行"创业计划书 第一章 主要产品概述 1.1 产品名称 中文名称:随行校园移动应用平台 1.2 产品开发背景 近年来,移动互联网呈现出了爆发式增长,移动互联网用户快速增长.根据2013中国移动互联网白皮书,该 ...查看


  • 基于Android的计算机基础知识移动学习APP设计
  • 摘 要 本文主要介绍基于Android 平台的计算机基础知识移动学习APP的设计实现过程,该系统客户端基础学习.单元练习.综合测试和错题本功能,可以满足用户基本学习需求,视频及精品教程功能可以丰富用户的学习模式,提升用户的学习效果,服务器端 ...查看


  • 新浪微博毕业论文
  • 2015届本科毕业论文(设计) 新浪微博客户端部分功能的实现 姓 名: xxxxxxxx 系 别: 计算机与信息技术学院 专 业: 网络安全 学 号: xxxxxxxx 指导教师: xxxxxxx 2015 年 04 月 16 日 目 录 ...查看


  • 移动办公方案
  • 第二章移动办公解决方案 河北省高级人民法院的信息化经过近10年的发展,已经在内部专网部署了多套应用系统用于日常办公.但是当院领导在会议.外出等没有办公环境的时候,常常会面临紧急文件签署的问题.伴随着3G时代来临,这个问题已经迎刃而解.中国联 ...查看


  • 基于Android混合移动应用开发技术研究
  • 基于混合移动应用开发技术研究 上海交通大学计算机科学与工程系 摘要:随着移动智能设备的不断普及,移动应用的数量也在快速增长.移动应用的潮流最先由互联网公司引领,互联网公司通常选择原生开发模式,在移动应用向企业普及的过程中,原生应用的趋势传导 ...查看


  • android常见面试题
  • Android面试题班得瑞 (补充) 1.onCreate():当Activity被创建的时候调用(第一次).操作:设置布局文件,初始化视图,绑定数据文件等. 2.onStart():当Activity能被我们看到的时候. 3.onResu ...查看


热门内容