安卓客户端与服务器的通信及ListView、adapter、fastjson的使用
2015-04-27 17:03
447 查看
在安卓开发的过程中,网络通信模块必不可少,尤其对于任何一个具有商用价值的应用,都离不开网络通信。今天我来谈谈我对安卓中网络访问、以及常见的ListView用法。
加入我们实现如下这个功能,但界面上显示的文字都是通过网络来获取的,在后续的文章里,我还会谈谈图片的两种加载方式,以及上传到服务器等,这里先掠过。
后台的服务器端的代码实现比较简单,下面会给出源码,这里不再涉及。
下面重点看看安卓的代码实现:
这是主的布局代码:activity_listview.xml
这是ListView的子项布局代码:activity_listview_item.xml
下面先来理解Adapter:MyListViewAdapter
上面的注释写得比较清楚,这个类的作用就是一个适配器的作用,它是数据与ListView的中间桥梁,可以想象电脑的电源适配器,就应该理解了。它负责处理的是组成ListView的每一个子项布局。
再来看看Activity组件的实现:MainActivity
该类中主要用到了网络的访问,使用的是Runnable对象。在安卓4.0及以后的版本中,禁止在主线程(UI)线程中直接访问网络uo,必须通过子线程才能访问网络。具体的网络连接实现如下所示:DataNetworkUtil
采用的是HttpClient,这个实现比价简单,也可以使Android Api中提供的URLConnection方式。
特别需要注意的是在安卓全局配置文件中需要添加网络访问的权限,以及模拟器的地址是10.0.2.2,而不能使用localhost.
下面给出该源码的下载链接,包括前台安卓和后台的服务器程序。
http://download.csdn.net/detail/u012191462/8638223
加入我们实现如下这个功能,但界面上显示的文字都是通过网络来获取的,在后续的文章里,我还会谈谈图片的两种加载方式,以及上传到服务器等,这里先掠过。
后台的服务器端的代码实现比较简单,下面会给出源码,这里不再涉及。
下面重点看看安卓的代码实现:
这是主的布局代码:activity_listview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ListView android:id="@+id/lv" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
这是ListView的子项布局代码:activity_listview_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/userNo" android:layout_width="0dp" android:layout_height="60dp" android:layout_weight="3" android:textSize="15pt" /> <TextView android:id="@+id/userName" android:layout_width="0dp" android:layout_height="60dp" android:layout_weight="6" android:paddingLeft="13dp" android:textColor="#ff0000" android:textSize="15pt" /> </LinearLayout>
下面先来理解Adapter:MyListViewAdapter
package com.azer.shop.listviewtest.adapter; 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; import com.azer.shop.listviewtest.R; import com.azer.shop.listviewtest.bean.UserBean; /** * 设置ListView中每一个子项的布局及其内容显示 * * @author fiver_ * */ public class MyListViewAdapter extends BaseAdapter { @SuppressWarnings("unused") //上下文对象 private Context context; private List<UserBean> userBeanList; private LayoutInflater layoutInflater; public MyListViewAdapter(Context context, List<UserBean> userBeanList) { this.context = context; this.userBeanList = userBeanList; layoutInflater = LayoutInflater.from(context); } @Override public int getCount() { return userBeanList.size(); } @Override public Object getItem(int position) { return userBeanList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Holder hold; //降低手机的内存开销 if (convertView == null || convertView.getTag() == null) { //加载ListView中每一个子项的布局, //因为ListView是有许多相同的模块组成的,activity_listview_item布局就是子模块,由它组成了ListView视图 convertView = layoutInflater.inflate(R.layout.activity_listview_item, null); hold = new Holder(); hold.userNo = (TextView) convertView.findViewById(R.id.userNo); hold.userName = (TextView) convertView.findViewById(R.id.userName); convertView.setTag(hold); } else { hold = (Holder) convertView.getTag(); } UserBean userBean = userBeanList.get(position); hold.userNo.setText(userBean.getUserNo()); hold.userName.setText(userBean.getUserName()); return convertView; } /** * 封装item布局中的控件,也体现了面向对象的思想 * * @author fiver_ * */ private static class Holder { private TextView userNo; private TextView userName; } }
上面的注释写得比较清楚,这个类的作用就是一个适配器的作用,它是数据与ListView的中间桥梁,可以想象电脑的电源适配器,就应该理解了。它负责处理的是组成ListView的每一个子项布局。
再来看看Activity组件的实现:MainActivity
package com.azer.shop.listviewtest.activity; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import android.widget.Toast; import com.azer.shop.listviewtest.R; import com.azer.shop.listviewtest.adapter.MyListViewAdapter; import com.azer.shop.listviewtest.bean.UserBean; import com.azer.shop.listviewtest.config.UriAddress; import com.azer.shop.listviewtest.fastjson.UserBeanJSon; import com.azer.shop.listviewtest.utils.DataNetworkUtil; /** * 安卓listView的使用及与服务器通信相关的操作 * * @author fiver_ * @since 2015-04-27 * */ public class MainActivity extends Activity { //ListView视图组件 private ListView listView; //自定义Adapter数据适配器 private MyListViewAdapter myListViewAdapter; //用于存放从网络上获取的值 private List<UserBean> userBeanList; //判断网络的连接状态,默认是false,表示不通 private boolean judgeResultIsNull; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_listview); findViewById(); initData(); } /** * 初始化控件 * */ private void findViewById() { listView = (ListView) findViewById(R.id.lv); } private void initData() { //访问网络 new Thread(runnable).start(); } //网络线程,通过地址访问后台获取后台的数据 Runnable runnable = new Runnable() { @Override public void run() { //用于存放向后台发送的数据,以键值对的形式 Map<String, String> params = new HashMap<String, String>(); //传一些参数给后台 params.put("userId", "sa"); String result = ""; try { byte[] b = DataNetworkUtil.getUri(UriAddress.NAMESPACE + UriAddress.GETINFO, params); if (b != null) { result = new String(b); judgeResultIsNull = true; } else { //网络连接不通 judgeResultIsNull = false; } } catch (Exception e) { e.printStackTrace(); } userBeanList = UserBeanJSon.getuserBean(result); //从网络线程回归到主线程,来修改activity中的布局内容 runOnUiThread(new Runnable() { @Override public void run() { if(userBeanList!=null && userBeanList.size()>0) { //将获取到的数据通过构造函数填充到适配器中 myListViewAdapter = new MyListViewAdapter(MainActivity.this, userBeanList); //将适配器与ListView视图进行适配填充 listView.setAdapter(myListViewAdapter); } else if(judgeResultIsNull == false) { Toast.makeText(MainActivity.this, "网络连接异常!!", Toast.LENGTH_LONG).show(); } else { Toast.makeText(MainActivity.this, "没有相关的用户信息!!", Toast.LENGTH_LONG).show(); } } }); } }; }
该类中主要用到了网络的访问,使用的是Runnable对象。在安卓4.0及以后的版本中,禁止在主线程(UI)线程中直接访问网络uo,必须通过子线程才能访问网络。具体的网络连接实现如下所示:DataNetworkUtil
package com.azer.shop.listviewtest.utils; import java.io.IOException; import java.util.Map; import java.util.Map.Entry; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; public class DataNetworkUtil { @SuppressWarnings("unused") private static String URL_ENCODER = "UTF_8"; //"GBK"; public static byte[] getUri(String uri, Map<String, String> params) throws ClientProtocolException, IOException { byte[] result = null; StringBuilder sb = new StringBuilder(); sb.append(uri); if (null != params && params.size() != 0) { sb.append("?"); for (Entry<String, String> entry : params.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()); sb.append("&"); } sb.deleteCharAt(sb.length() - 1); } System.out.println("URI ==>> " + sb.toString()); // 创建一个http请求对象 HttpGet request = new HttpGet(sb.toString()); // 创建HttpParams以用来设置HTTP参数 HttpParams pas = new BasicHttpParams(); HttpClient httpClient = new DefaultHttpClient(pas); try { // 执行请求参数项 HttpResponse response = httpClient.execute(request); // 判断请求是否成功 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // 获得响应信息 result = EntityUtils.toByteArray(response.getEntity()); return result; } else { //服务器连接失败,则返回空; } } catch (Exception e) { e.printStackTrace(); } finally { //释放网络连接资源 httpClient.getConnectionManager().shutdown(); } return null; } }
采用的是HttpClient,这个实现比价简单,也可以使Android Api中提供的URLConnection方式。
特别需要注意的是在安卓全局配置文件中需要添加网络访问的权限,以及模拟器的地址是10.0.2.2,而不能使用localhost.
下面给出该源码的下载链接,包括前台安卓和后台的服务器程序。
http://download.csdn.net/detail/u012191462/8638223
相关文章推荐
- 使用ListView和AsyncTask、fastjson解析Json以及适配器BaseAdapter来实现下载网络的图片以及文字并显示出来
- 安卓使用FastJson解析Json数据并展示到ListView中
- 安卓客户端使用Json登陆php服务器的简单方法
- notifyDataSetChanged()刷新ListView(使用JSONArray绑定的Adapter)
- windows下使用php socket 和 html5 websocket实现服务器和客户端之间通信
- 安卓使用Gson解析服务器返回Json数组,以及java服务器怎样返回list集合的Json数据(原创)
- 使用Openfire配置安卓客户端聊天服务器
- 使用YII构建移动客户端的服务器:不只是输出Json那么简单
- 使用YII构建移动客户端的服务器:不只是输出Json那么简单
- Android使用Gson解析JSON连接服务器实现客户端登陆功能
- android客户端向服务器通信的三种方式的使用
- 使用C语言socket实现windows pc与ftp服务器通信---socket实现ftp客户端
- 章二、jersey+json搭建服务器以及使用jersey搭建客户端
- ajax利用json进行服务器与客户端的通信
- [2015/05/08] JSP服务器与安卓客户端通信 & 页面布局控件覆盖问题
- Android 使用Json实现服务器与客户端数据的交互
- Android 使用Mina的Nio实现客户端服务器通信
- 安卓--ListView和Adapter的关系和如何使用实例
- Java服务器与客户端的通信中对象流的使用
- 网络编程:使用Socket实现简单的服务器和客户端的通信