Android通過JSON資料格式和java服務後臺進行資料互動
阿新 • • 發佈:2018-12-18
Android和JAVA後臺實現資料通訊
前言
進行綜合設計的時候,要求做個javaweb
專案並掛到伺服器上,與此同時在Android上通過訪問後臺介面實現部分功能。經過了一番的摸索和踩坑,終於實現了和後臺服務的通訊登陸註冊和資訊列表顯示功能。這是 github
地址,先看一下效果。
專案介紹
目錄結構介紹
功能介紹
登陸功能
首先在layout
目錄下新建xml檔案進行佈局和定義樣式,然後註冊事件進行監聽,通過intent
物件控制activity的跳轉,MainActivity類
public class MainActivity extends Activity implements OnClickListener{ //宣告全域性控制元件 private EditText mPhoneNumberEditText; private EditText mPassWordEditText; private Button mLoginButton, mRegisterButton; private RadioButton admin, user; private String originAddress = "http://47.97.193.151/parkingsystem2/Login"; //登陸請求的網址介面 Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); String result = ""; if ("OK".equals(msg.obj.toString())){ result = "success"; }else if ("Wrong".equals(msg.obj.toString())){ result = "fail"; }else { String data = msg.obj.toString(); // Toast.makeText(MainActivity.this, data, Toast.LENGTH_LONG).show(); try { JSONObject jsonObject = new JSONObject(data); String code = jsonObject.getString("code"); if (code.equals("1")) { result = jsonObject.getString("data"); //通過Bundle封裝資料在intent物件中,傳遞到不同的activity Bundle bundle = new Bundle(); bundle.putString("data", result); //通過Intent控制Activity跳轉 Intent intent = new Intent(); intent.setClass(MainActivity.this, ListActivity.class); intent.putExtras(bundle); finish(); startActivity(intent); }else { result = jsonObject.getString("data"); Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show(); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initEvent(); } //初始化控制元件方法 private void initView() { mPhoneNumberEditText = (EditText) findViewById(R.id.phoneNumberEditText); mPassWordEditText = (EditText) findViewById(R.id.passwordEditText); mLoginButton = (Button) findViewById(R.id.loginButton); mRegisterButton = (Button) findViewById(R.id.registerButton); admin = (RadioButton)findViewById(R.id.admin); user = (RadioButton)findViewById(R.id.user); } //註冊事件方法 private void initEvent() { mLoginButton.setOnClickListener(this); mRegisterButton.setOnClickListener(this); } private boolean isInputValid() { //檢查使用者輸入的合法性,這裡暫且預設使用者輸入合法 return true; } //實現介面onCreate方法 @Override public void onClick(View v) { switch (v.getId()){ case R.id.loginButton:{ login(); //呼叫登陸方法 break; } case R.id.registerButton: { register(); //呼叫註冊方法 break; } } } //跳轉到註冊介面 public void register() { Intent intent = new Intent(); intent.setClass(MainActivity.this, RegisterActivity.class); //跳轉 startActivity(intent); //啟動 finish(); } //登陸 public void login() { //取得使用者輸入的賬號和密碼 if (!isInputValid()){ return; } String number = mPhoneNumberEditText.getText().toString().trim(); String password = mPassWordEditText.getText().toString().trim(); if (number.isEmpty()) { Toast.makeText(MainActivity.this, "賬號不能為空!", Toast.LENGTH_LONG).show(); return; }else if (password.isEmpty()) { Toast.makeText(MainActivity.this, "密碼不能為空!", Toast.LENGTH_LONG).show(); return; }else if (!admin.isChecked() && !user.isChecked()) { Toast.makeText(MainActivity.this, "請選擇許可權!", Toast.LENGTH_LONG).show(); return; } HashMap<String, String> params = new HashMap<String, String>(); params.put(User.USERNAME, number); params.put(User.PASSWORD, password); if (admin.isChecked()) { params.put(User.POWER, "1"); }else if (user.isChecked()) { params.put(User.POWER, "2"); } try { //發起HTTP請求 String compeletedURL = HttpUtil.getURLWithParams(originAddress, params); //originAddress請求地址, params請求引數 HttpUtil.sendHttpRequest(compeletedURL, new HttpCallbackListener() { @Override public void onFinish(String response) { //請求回撥函式,response是響應的資料 Message message = new Message(); message.obj = response; mHandler.sendMessage(message); //給Handlder傳遞資料 } @Override public void onError(Exception e) { Message message = new Message(); message.obj = e.toString(); mHandler.sendMessage(message); } }); } catch (Exception e) { e.printStackTrace(); } } }
特別重要
在進行Activity跳轉時,需要在 AndroidMainfest.xml
配置檔案註冊,同時網路請求也要配置允許設定。
網路請求封裝類
public class HttpUtil { //封裝的傳送請求函式 public static void sendHttpRequest(final String address, final HttpCallbackListener listener) { if (!HttpUtil.isNetworkAvailable()){ //這裡寫相應的網路設定處理 return; } new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; try{ URL url = new URL(address); //使用HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //設定方法和引數 connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); connection.setDoInput(true); connection.setDoOutput(true); //獲取返回結果 InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null){ response.append(line); } //成功則回撥onFinish if (listener != null){ listener.onFinish(response.toString()); } } catch (Exception e) { e.printStackTrace(); //出現異常則回撥onError if (listener != null){ listener.onError(e); } }finally { if (connection != null){ connection.disconnect(); } } } }).start(); } //組裝出帶引數的完整URL public static String getURLWithParams(String address,HashMap<String,String> params) throws UnsupportedEncodingException { //設定編碼 final String encode = "UTF-8"; StringBuilder url = new StringBuilder(address); url.append("?"); //將map中的key,value構造進入URL中 for(Map.Entry<String, String> entry:params.entrySet()) { url.append(entry.getKey()).append("="); url.append(URLEncoder.encode(entry.getValue(), encode)); url.append("&"); } //刪掉最後一個& url.deleteCharAt(url.length() - 1); return url.toString(); } //判斷當前網路是否可用 public static boolean isNetworkAvailable(){ return true; } } 回撥監聽介面類 public interface HttpCallbackListener { void onFinish(String response); void onError(Exception e); }
註冊功能
註冊功能和登陸功能基本流程相同,只不過增加了兩個控制元件,請求的介面一樣,不過請求的引數不一樣,具體流程可以參考下 github
的原始碼
列表顯示功能
登陸成功後,後臺服務響應返回一個 json
資料格式的資料,需要解析 json
格式資料並顯示在列表上
{"code":1, "data":[ {"cardtype":"VIP","cartype":"小型車","id":1,"number":"111","sum":"¥1011","time":"每小時"}, {"cardtype":"VIP","cartype":"中型車","id":2,"number":"112","sum":"¥12","time":"每小時"}, {"cardtype":"VIP","cartype":"大型車","id":3,"number":"113","sum":"¥15","time":"每小時"}, {"cardtype":"普通卡","cartype":"小型車","id":4,"number":"114","sum":"¥15","time":"每小時"}, {"cardtype":"普通卡","cartype":"中型車","id":5,"number":"115","sum":"¥20","time":"每小時"}, {"cardtype":"普通卡","cartype":"大型車","id":6,"number":"116","sum":"¥25","time":"每小時"} ]}
藉助 JSONArray
和 JSONObject
兩個物件將 json
資料 通過雜湊值hash
存放在 ArrayList
物件上,然後通過 simpleAdapter
介面卡將 hash
的鍵list_item_activity.xml
檔案 的控制元件 id
項對應顯示列表
public class ListActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
ListView listView; //宣告一個ListView物件
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//獲取intent物件上的傳過來的資料
Bundle myBundle = this.getIntent().getExtras();
String data = myBundle.getString("data");
setContentView(R.layout.list_activity);
//存放json資料
List<HashMap<String, String>> list = new ArrayList<HashMap<String,String>>();
try {
JSONArray jsonArray = new JSONArray(data);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = (JSONObject)jsonArray.get(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put("id",jsonObject.getString("id"));
map.put("enterPort",jsonObject.getString("cardtype"));
map.put("exitPort",jsonObject.getString("cartype"));
map.put("parkName",jsonObject.getString("number"));
map.put("parkTel",jsonObject.getString("sum"));
map.put("parkTotal",jsonObject.getString("time"));
list.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
String[] str = new String[]{"id", "enterPort", "exitPort", "parkName", "parkTel", "parkTotal"}; //陣列存放對應上面hash的鍵
int[] rId = new int[]{R.id.park_id, R.id.enter, R.id.exit, R.id.parkname, R.id.phone, R.id.total}; //對應list_item.activity.xml檔案的控制元件id
SimpleAdapter simpleAdapter = new SimpleAdapter(ListActivity.this, list, R.layout.list_item_activity, str, rId); //引數,第一個是列表Activity的類,第二個引數是ArrayList資料,第三個引數是list_item_activity的layout的id,第四和第五對應上面的兩個資料,分別為hash鍵陣列和控制元件id陣列
listView = (ListView)this.findViewById(R.id.listview);
listView.setAdapter(simpleAdapter);
}
}