安卓客户端与服务器的通信及ListView、adapter、fastjson的使用

来源:互联网 发布:巨石监控分析软件 编辑:程序博客网 时间:2024/05/16 00:30


在安卓开发的过程中,网络通信模块必不可少,尤其对于任何一个具有商用价值的应用,都离不开网络通信。今天我来谈谈我对安卓中网络访问、以及常见的ListView用法。

加入我们实现如下这个功能,但界面上显示的文字都是通过网络来获取的,在后续的文章里,我还会谈谈图片的两种加载方式,以及上传到服务器等,这里先掠过。




后台的服务器端的代码实现比较简单,下面会给出源码,这里不再涉及。

下面重点看看安卓的代码实现:

这是主的布局代码: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);}@Overridepublic int getCount(){return userBeanList.size();}@Overridepublic Object getItem(int position){return userBeanList.get(position);}@Overridepublic long getItemId(int position){return position;}@Overridepublic 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;@Overrideprotected 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(){@Overridepublic 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(){@Overridepublic 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




0 0
原创粉丝点击