SSH服务器与Android通信(2)--Android客户端接收数据
基本原理是Android客户端通过HttpClient向服务器发出请求,服务器向Android客户端返回JSON字符串,Android客户端解析JSON字符串获得数据。
1. 新建一个Android项目,主要文件如下:
其中MainActivity是UI,CommThread是通信线程,负责和服务器通信,Util是工具类,Var存放变量。
2. Var.java:
package com.hzhi.school.util; import java.util.ArrayList; import java.util.List; public class Var { // 访问的URL public static String strHost = new String("http://192.168.1.100:8080/School/"); public static String strAct = new String("aclasquery"); public static String strURL = strHost + strAct; // 列表 public static List lstId = new ArrayList(); public static List lstName = new ArrayList(); public static List lstComm = new ArrayList(); // 屏幕的尺寸 public static int wid_scr; public static int hei_scr; // 消息类型 public static final int msg_connect = 1; public static final int msg_error = 2; public static final int msg_con_start = 3; public static final int msg_con_stop = 4; }
3. Util.java:
package com.hzhi.school.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; public class Util { // 构造类 public Util(){ } // 将InputStream格式转化为StringBuilder格式 public static StringBuilder is2sb (InputStream is) { String ln = ""; StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); try{ while ((ln=br.readLine()) != null){ sb.append(ln); } }catch(Exception e){ e.printStackTrace(); } return sb; } // JSON转换成List public static void json2list(String strJson) throws JSONException { JSONObject jsonObject = new JSONObject(strJson); JSONArray jsonClas = jsonObject.getJSONArray("Classes"); for (int i=0; i<jsonClas.length(); i++){ Var.lstId.add(i, jsonClas.getJSONObject(i).getString("id")); Var.lstName.add(i, jsonClas.getJSONObject(i).getString("name")); Var.lstComm.add(i, jsonClas.getJSONObject(i).getString("comment")); } } }
4. CommThread.java:
package com.hzhi.school.comm; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.os.Bundle; import android.os.Message; import android.util.Log; import com.hzhi.school.MainActivity; import com.hzhi.school.util.Util; import com.hzhi.school.util.Var; public class CommThread extends Thread{ // 消息变量 private Message msg; private Bundle bdl; // 构造函数 public void run(){ InputStream resIS; StringBuilder resSB; String resStr; resIS = getIS(Var.strURL); if (resIS == null) { return; } else { resSB = Util.is2sb(resIS); resStr = resSB.toString(); try{ Util.json2list(resStr); sendMessage(Var.msg_connect,""); }catch (Exception e){ e.printStackTrace(); sendMessage(Var.msg_error,e.toString()); } } } // 通过GET方法获取信息 public InputStream getIS (String url){ InputStream is=null; try{ // 取得默认HttpClient实例 HttpClient hc = new DefaultHttpClient(); // 连接到服务器 HttpResponse hr = hc.execute(new HttpGet(url)); // 获取数据内容 is = hr.getEntity().getContent(); }catch (Exception e){ e.printStackTrace(); sendMessage(Var.msg_error,e.toString()); } return is; } // 发送消息(用于更新UI) public void sendMessage(int x, String s){ msg = new Message(); bdl = new Bundle(); bdl.putString("1",s); msg.what = x; msg.setData(bdl); MainActivity.mainHandler.sendMessage(msg); } }
使用HttpClient向服务器发出请求,服务器返回的是一个InputStream,调用Util里面的函数将InputStream转换成StringBuilder,获得JSON字符串,再解析JSON字符串,获得数据。
5. MainActivity.java:
package com.hzhi.school; import java.util.ArrayList; import java.util.List; import android.app.ListActivity; import android.app.ProgressDialog; import android.content.Context; import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.hzhi.school.comm.CommThread; import com.hzhi.school.util.Var; public class MainActivity extends ListActivity{ static list_clas_adaptor myAdaptor; static Context mCtx; static ProgressDialog progressDialog; static Toast toast; CommThread myThread; static int numGet = 0; ListView lv; int id; item_clas it; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_clas); mCtx = getApplicationContext(); getScreen(); myAdaptor = new list_clas_adaptor(this); progressDialog = ProgressDialog.show(MainActivity.this, "连接", "正在连接服务器:" + Var.strURL, true, false); setListAdapter(myAdaptor); myThread = new CommThread(); myThread.start(); } protected void onListItemClick(ListView l, View v, int position, long id) { id = Integer.parseInt((String) myAdaptor.list_data.get(position).txtNum.getText()); it = (item_clas) myAdaptor.getItem((int)id); super.onListItemClick(l, v, position, id); } // 获得课程列表 public static void getData(){ myAdaptor.list_data.clear(); if (Var.lstId.size()>0){ for (int i=0; i<Var.lstId.size(); i++){ myAdaptor.addItem(Var.lstId.get(i).toString(), Var.lstName.get(i).toString(), Var.lstComm.get(i).toString(), 1); } } numGet++; } // 消息处理Handler public static Handler mainHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { // 出错 case Var.msg_error: toast = Toast.makeText(mCtx, "错误:" + msg.getData().getString("1"), Toast.LENGTH_LONG); toast.show(); break; // 已连接成功 case Var.msg_connect: progressDialog.dismiss(); getData(); myAdaptor.notifyDataSetChanged(); toast = Toast.makeText(mCtx, "连接服务器并返回数据成功!", Toast.LENGTH_LONG); toast.show(); break; } super.handleMessage(msg); } }; // 获得屏幕尺寸 public void getScreen(){ Var.wid_scr = getWindowManager().getDefaultDisplay().getWidth(); Var.hei_scr = getWindowManager().getDefaultDisplay().getHeight(); } } //课程列表 class list_clas_adaptor extends BaseAdapter implements OnClickListener{ public Context ctx; public List<item_clas> list_data; public String s1, s2; public list_clas_adaptor(Context context){ ctx =context; list_data = new ArrayList<item_clas>(); } @Override public int getCount() { // TODO Auto-generated method stub return list_data.size(); } @Override public Object getItem(int id) { // TODO Auto-generated method stub s2 = String.valueOf(id); for (int i=0; i<list_data.size(); i++){ s1 = (String) list_data.get(i).txtNum.getText(); if (s1.equals(s2)) return list_data.get(i); } return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return list_data.indexOf(position); } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub item_clas my_item; if (convertView == null) { my_item = new item_clas(ctx, (String)list_data.get(position).txtNum.getText(), (String)list_data.get(position).txtName.getText(), (String)list_data.get(position).txtComm.getText() ,1); } else { my_item = (item_clas)convertView; my_item.txtNum.setText(list_data.get(position).txtNum.getText()); my_item.txtName.setText(list_data.get(position).txtName.getText()); my_item.txtComm.setText(list_data.get(position).txtComm.getText()); } // 点击删除按钮 my_item.btnDel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { } }); // 点击修改按钮 my_item.btnMdf.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { }
}); return my_item; } public void addItem(String num, String name, String comm, int x) { list_data.add(new item_clas(ctx, num, name, comm, x)); } @Override public void onClick(View v) { } } // clas列表的一行 class item_clas extends LinearLayout{ public TextView txtNum; public TextView txtName; public TextView txtComm; public TextView txtMdf; public TextView txtDel; public Button btnMdf; public Button btnDel; public item_clas(Context ctx, String num, String name, String comm, int x) { super(ctx); this.setOrientation(HORIZONTAL); int hei = 60; txtNum = new TextView(ctx); txtNum.setText(num); txtNum.setGravity(Gravity.CENTER); txtNum.setTypeface(Typeface.DEFAULT_BOLD, Typeface.BOLD); addView(txtNum, new LinearLayout.LayoutParams((int)(Var.wid_scr*0.1),hei)); txtName = new TextView(ctx); txtName.setText(name); txtName.setGravity(Gravity.CENTER); txtName.setTypeface(Typeface.DEFAULT_BOLD, Typeface.BOLD); addView(txtName, new LinearLayout.LayoutParams((int)(Var.wid_scr*0.2),hei)); txtComm = new TextView(ctx); txtComm.setText(comm); Gravity g = new Gravity(); txtComm.setGravity(Gravity.LEFT); addView(txtComm, new LinearLayout.LayoutParams((int)(Var.wid_scr*0.4),hei)); if (x==0){ txtDel = new TextView(ctx); txtDel.setText("删除"); txtDel.setGravity(Gravity.CENTER); addView(txtDel, new LinearLayout.LayoutParams((int)(Var.wid_scr*0.15),hei)); Log.i("addView", txtDel.getText().toString()); txtMdf = new TextView(ctx); txtMdf.setText("更新 "); txtMdf.setGravity(Gravity.CENTER); addView(txtMdf, new LinearLayout.LayoutParams((int)(Var.wid_scr*0.15),hei)); Log.i("comm=", comm); Log.i("addView", txtMdf.getText().toString()); } else{ btnDel = new Button(ctx); btnDel.setText("删除"); btnDel.setGravity(Gravity.CENTER); btnDel.setTypeface(Typeface.DEFAULT_BOLD, Typeface.BOLD); btnDel.setFocusable(false); addView(btnDel, new LinearLayout.LayoutParams((int)(Var.wid_scr*0.15),hei)); btnMdf = new Button(ctx); btnMdf.setText("更新"); btnMdf.setGravity(Gravity.CENTER); btnMdf.setTypeface(Typeface.DEFAULT_BOLD, Typeface.BOLD); btnMdf.setFocusable(false); addView(btnMdf, new LinearLayout.LayoutParams((int)(Var.wid_scr*0.15),hei)); } } }
MainActivity调用CommThread访问服务器,获得数据后通过BaseAdaptor显示出来。在item_clas类中,由于点击每一行会被系统误以为是在点击Button,所以要给Button加上:
setFocusable(false);
运行结果: