实现步骤: n 在Mysql上创建表news,并初始化几条记录 n 用Php开发工具(如PhpStorm或HBuider)写连个php文件用于连接Mysql数据库并获取news表数据,并包装成JSON数据包(可先用浏览器测试获取的数据) n Android端接收JSON数据并进行解析,并展现出来 News类用于news表中记录对象 HttpUtils类用于接收JSON数据和接收网络图片,并通知主线程更新数据
|
在MySQL中创建一个表 |
|
创建表及初始化数据的sql |
-- phpMyAdmin SQL Dump -- version 2.11.4 -- http://www.phpmyadmin.net -- -- Host: localhost -- Generation Time: Dec 17, 2015 at 07:10 AM -- Server version: 5.1.57 -- PHP Version: 5.2.17
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
-- -- Database: `a2393827_db` --
-- --------------------------------------------------------
-- -- Table structure for table `news` --
DROP TABLE IF EXISTS `news`; CREATE TABLE IF NOT EXISTS `news` ( `id` INT(10) NOT NULL AUTO_INCREMENT, `title` TEXT NOT NULL, `desc` TEXT NOT NULL, `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `content_url` TEXT NOT NULL, `pic_url` TEXT NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
-- -- Dumping data for table `news` --
INSERT INTO `news` VALUES(1, ' Android 广播接收器 ', 'Android 广播接收器 BroadcastReceiver 注册、注销、优先级、拦截', '2015-01-23 20:50:03', 'http://blog.csdn.net/caizhigui/article/details/50323215', 'http://img.blog.csdn.net/20151216084351023?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center'); INSERT INTO `news` VALUES(4, ' android应用间数据传递\r\n ', ' android应用间数据传递(使用ContentProvider及SQLite在应用间传递数据) ', '2015-12-17 07:03:24', 'http://blog.csdn.net/caizhigui/article/details/50226769', 'http://avatar.csdn.net/8/A/A/1_caizhigui.jpg'); INSERT INTO `news` VALUES(5, ' 在Android中操作JSON数据\r\n ', ' 在Android中操作JSON数据-读取JSON格式数据/创建JSON格式数据 \r\n ', '2015-12-17 07:05:38', 'http://blog.csdn.net/caizhigui/article/details/50225547', 'http://avatar.csdn.net/8/A/A/1_caizhigui.jpg'); |
|
|
|
|
用Php开发工具(如PhpStorm或HBuider)写连个php文件 |
mysql_connect.php数据库连接 |
<?php /* * 数据库连接 * 返回值:title desc time content_url pic_url */ // 服务器地址,用户名,密码 $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){ die(mysql_error()); } // 放回数据库连接第一个参数数据库,第二个参数就是前面的连接 mysql_select_db("newsdemo", $con); ?>
|
获取表数据getNewsJSON.php |
<?php /* * 获得JSON数据 * 返回值:title desc time content_url pic_url */ // 包含前面的数据库连接文件 require 'mysql_connect.php'; $n = 0; //查询news表的结果 $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); ?>
|
Copy这连个php文件到服务器,如Tomcat的webapp/php目录,后就可以用浏览器测试如下: |
用浏览器测试一下php返回的情况 http://zhiguicai.comli.com/getNewsJSON.php
|
|
|
|
创建一个工程LearnJSONMysqlPHP |
||||||||||||||||||
创建一个表达news对象的类 |
||||||||||||||||||
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); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getContent_url() { return content_url; } public void setContent_url(String content_url) { this.content_url = content_url; } public String getPic_url() { return pic_url; } public void setPic_url(String pic_url) { this.pic_url = pic_url; } } |
||||||||||||||||||
创建一个类NewsAdapter extends BaseAdapter 并为其重写几个代码
|
||||||||||||||||||
public class NewsAdapter extends BaseAdapter { private Context context; private List<News> newsList; //通过构造方法把上下文对象传递进来 public NewsAdapter(Context context, List<News> newsList) { this.context = context; this.newsList = newsList; } @Override //列表项的个数 public int getCount() { return newsList.size(); } @Override public News getItem(int position) { return newsList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView==null){ //为列表项加载自定义布局 convertView= LayoutInflater.from(context).inflate(R.layout.json_mysql_php_news_layout,null); } ImageView ivPic=(ImageView) convertView.findViewById(R.id.ivPic); TextView tvTitle=(TextView) convertView.findViewById(R.id.tvTitle); TextView tvDesc=(TextView) convertView.findViewById(R.id.tvDesc); TextView tvTime=(TextView) convertView.findViewById(R.id.tvTime); 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; } }
|
||||||||||||||||||
主视图仅放一个Listview控件 |
||||||||||||||||||
<ListView android:id="@+id/tvNews" android:layout_width="match_parent" android:layout_height="match_parent">
|
||||||||||||||||||
创建一个列表项的布局文件news_layout.xml(采用相对布局),在NewsAdapter 的getView方法中要调用。 |
||||||||||||||||||
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/ivPic" android:layout_width="45dp" android:layout_height="45dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/tvTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/ivPic" android:text="标题" android:textSize="18sp" /> <TextView android:id="@+id/tvDesc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tvTitle" android:layout_toRightOf="@id/ivPic" android:text="描述" /> <TextView android:id="@+id/tvTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="时间" android:textSize="10sp" /> </RelativeLayout>
|
||||||||||||||||||
|
||||||||||||||||||
public class HttpUtils { //需要传入的参数Url及主线程的Handle,因为线程在运行的到数据后,需要通过handle通知主线程 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)); String line = ""; StringBuilder result = new StringBuilder(); while ( (line = reader.readLine()) != null ){ result.append(line); } Message msg = new Message(); msg.obj = result.toString(); handler.sendMessage(msg); //把接收到的信息通知主线程(传入进来的Handle线程) } catch (Exception e) { e.printStackTrace(); } } }).start(); } //第一个参数是要填充的ImageView对象,第二个参数是网络的图片地址 public static void setPicBitmap(final ImageView ivPic, final String pic_url){ new Thread(new Runnable() { @Override public void run() { try { HttpURLConnection conn = (HttpURLConnection) new URL(pic_url).openConnection(); conn.connect(); InputStream is = conn.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(is); //把输入流转换成Bitmap对象 ivPic.setImageBitmap(bitmap); is.close(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } }
|
||||||||||||||||||
public class JsonMysqlPhpActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { ListView lvNews; NewsAdapter adapter; private List<News> newsList; //News对象的集合 //public static final String GET_NEWS_URL = "http://localhost:8080/czg/getNewsJSON.php"; public static final String GET_NEWS_URL = "http://zhiguicai.comli.com/getNewsJSON.php"; //处理接收网络数据线程发来的消息,并解析JSON数据 private Handler getNewsHandler = new Handler(){ public void handleMessage(android.os.Message msg) { String jsonData = (String) msg.obj; System.out.println("收到的JSON数据包内容:"+jsonData); //开始解析收到的JSON数据 try { JSONArray jsonArray = new JSONArray(jsonData); for (int i=0;i<jsonArray.length();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"); newsList.add(new News(title, desc, time, content_url, pic_url)); } adapter.notifyDataSetChanged(); //数据解析后,通知adapter更新视图 } catch (Exception e) { e.printStackTrace(); } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_json_mysql_php); lvNews=(ListView) findViewById(R.id.tvNews); newsList = new ArrayList<News>(); //集合对象初始化 //this传递到NewsAdapter的构造方法中,NewsAdapter中需要访问到UI adapter=new NewsAdapter(this,newsList); lvNews.setAdapter(adapter); lvNews.setOnItemClickListener(this); HttpUtils.getNewsJSON(GET_NEWS_URL, getNewsHandler); } }
|