Android 客戶端與伺服器端進行資料互動(二、登入客戶端)
概要
Android客戶端分為User,HttpUtil,HttpCallbackListener,MainActivity四個部分。User model與服務端的一樣,一方面是用於本地使用者資訊的儲存model,另一方面也是為了保證構造URL時使用的key一致。
HttpUtil封裝了傳送Http請求的過程和構造URL的函式,HttpCallbackListener是用於傳送請求後的回撥介面,MainActivity就是用於測試的Activity互動介面了。
User model
HttpCallbackListener
回撥介面定義了兩個函式,一個是正常結束時回撥的onFinish,一個是出現異常時的onError
//請求回撥介面
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
}
HttpUtil
HttpUtil是一個進行了二次封裝的Http工具類,包括了傳送http請求的sendHttpRequest函式,組裝URL的getURLWithParams函式和網路狀態檢查函式。
組裝後的URL大概的樣子就像這樣”http://www.baidu.com?username=codingma&password=123456
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;
}
}
主活動
MainActivity就是最簡單的測試UI介面,包括了兩個輸入框和一個按鈕。
佈局效果圖如下
佈局xml
<?xml version="1.0" encoding="utf-8"?>
<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:gravity="center_horizontal|center_vertical"
android:orientation="vertical"
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="com.pku.codingma.zhisms.ui.loginAndRegister.LoginActivityFragment"
tools:showIn="@layout/activity_main">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="手機號:"
android:inputType="phone"
android:layout_weight="1"/>
<EditText
android:id="@+id/phoneNumberEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="密碼:"
android:layout_weight="1"/>
<EditText
android:id="@+id/passwordEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:layout_weight="5"/>
</LinearLayout>
<Button
android:id="@+id/loginButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="@color/colorPrimaryDark"
android:text="login"/>
</LinearLayout>
MainActivity
MainActivity首先將輸入框中的使用者名稱和密碼取出,構造HashMap。再將其傳入HttpUtil.getURLWithParams函式中,構造出完整的URL,然後使用HttpUtil.sendHttpRequest傳送請求,同時定義好回撥介面要做的事情(即發出一條Message訊息)。最後通過Handler和Message訊息機制,根據請求返回結果做出對應的處理。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private EditText mPhoneNumberEditText;
private EditText mPassWordEditText;
private Button mLoginButton;
//用於接收Http請求的servlet的URL地址,請自己定義
private String originAddress = "http://localhost:8080/Server/servlet/LoginServlet";
//用於處理訊息的Handler
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 {
result = msg.obj.toString();
}
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}
private void initView() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mPhoneNumberEditText = (EditText) findViewById(R.id.phoneNumberEditText);
mPassWordEditText = (EditText) findViewById(R.id.passwordEditText);
mLoginButton = (Button) findViewById(R.id.loginButton);
}
private void initEvent() {
mLoginButton.setOnClickListener(this);
}
public void login() {
//檢查使用者輸入的賬號和密碼的合法性
if (!isInputValid()){
return;
}
//構造HashMap
HashMap<String, String> params = new HashMap<String, String>();
params.put(User.PHONENUMBER, mPhoneNumberEditText.getText().toString());
params.put(User.PASSWORD, mPassWordEditText.getText().toString());
try {
//構造完整URL
String compeletedURL = HttpUtil.getURLWithParams(originAddress, params);
//傳送請求
HttpUtil.sendHttpRequest(compeletedURL, new HttpCallbackListener() {
@Override
public void onFinish(String response) {
Message message = new Message();
message.obj = response;
mHandler.sendMessage(message);
}
@Override
public void onError(Exception e) {
Message message = new Message();
message.obj = e.toString();
mHandler.sendMessage(message);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean isInputValid() {
//檢查使用者輸入的合法性,這裡暫且預設使用者輸入合法
return true;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.loginButton:
login();
break;
}
}
}
總結
Android端的稍微複雜一些,涉及Http請求傳送,回撥介面,一些有效性檢查,Handler訊息機制等等。不過都是最基礎的使用級別,應該不難理解。
相關推薦
Android 客戶端與伺服器端進行資料互動(二、登入客戶端)
概要 Android客戶端分為User,HttpUtil,HttpCallbackListener,MainActivity四個部分。User model與服務端的一樣,一方面是用於本地使用者資訊的儲存model,另一方面也是為了保證構造URL時使用的key一
Android 客戶端與伺服器端進行資料互動(一、登入伺服器端)
概要 安卓APP要實現很多功能(比如登入註冊、發表評論等)時都必須要使用到網路資料互動。所以在學習了這部分內容後,就將其以最常見的登入過程為例整理出來,也方便跟我一樣的新手能迅速學習上手。 預期效果圖如下,輸入手機號和密碼,點選Login按鈕,上傳資料到伺
使用sftp在客戶端與伺服器之間進行檔案傳輸
知識點:sftp 步驟: 一、 登入伺服器 使用命令格式:sftp 伺服器主機名 二、 在客戶端與伺服器之間進行檔案傳輸 命令put: 上傳到伺服器 put haha.txt 命令get: 下載到客戶端
Android移動端與伺服器api介面加密示例(AES,MD5,Token)
移動端介面安全流程: 獲取token步驟: * 1.拿到從後臺返回的AES加密後的token * 2.根據約定祕鑰進行解密,並把token儲存下來 AES祕鑰由移動端和後臺商議決定 後臺驗證步驟: * 1.取出timestamp 驗證是否是過期請求
伺服器和客戶端的json資料互動(http/socket兩種方式)
一、首先是Http方式 伺服器端: @WebServlet("/service") public class ServiceServlet extends HttpServlet { private static final long serialV
Android手機通過wifi進行資料傳輸(二)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
ssm ajax 前後端資料互動 (包括出現的406錯誤)
廢話 我哥從我大一的時候,就告訴我要寫部落格,我感覺好對不起他,現在大三了,才開始寫第一篇。。。 剛把ssm教程看完,然後就想用ajax實現前後端分離。於是乎,我搞了兩天才成功。。。 一、搭建環境 首先是ssm的一堆配置檔案,我很迷。。 都是從視訊裡扒下來的,對裡面的東西還不太瞭
Android實現Fragment與Activity之間的資料互動
1概念 1 為什麼 因為Fragment和Activity一樣是具有生命週期,不是一般的bean通過建構函式傳值,會造成異常。 2 參考連結 Activity和Fragment傳遞資料的兩種方式 【Fragment精深系列4】Frag
微信小程式之前端與java後臺進行資料互動
最近小程式挺火的,準備寫個小程式試試,我會將我遇到的問題和我認為有用的記錄下來,但是隻瞭解java,並不太懂PHP,雖然說語言都是相通的(我也不知道誰說的),反正還是用Java寫後臺吧,1.申請伺服器+域名3.準備使用ssm框架進行後臺開發,先進行前端後臺資料互動試試後臺ja
Java學習——前後端資料互動(二)
以下是前端頁面資料傳遞後Java後臺。 前段時間在前行前後端資料互動的時候,點選提交沒有響應。原因是因為下面這個地方出錯了。js目錄的指向不對。 這裡最前面的一個表示該檔案所屬的資料夾的上一級目錄的父目錄。如果是兩級的話則加兩個..表示上兩級的父目錄。 接著又是一步步除錯
unity3D中使用Socket進行資料通訊(二)
上一篇部落格主要介紹了使用socket搭建服務端和客戶端程式,這一篇來說說socket的資料傳輸,我們使用socket的目的是解決點對點之間的資料傳輸,之前提到了socket中一個重要的概念:埠。而socket傳輸資料的方式就是埠與埠之間以流(stream)的方式傳輸資料,s
微信小程式填坑之路之springmvc與小程式的資料互動(json)
springmvc框架寫到現在終於牽扯到小程式了(所以別說我“不務正業”),對於一個應用程式來說,它的本質其實就是無數個對資料進行增刪改查的操作,這裡起到至關重要的就是資料,於是這篇帖子的目的就是實現小程式與後臺資料的互動。小程式使用的是wx.request的api來提交和接
【jsp/servlet】jsp資料互動(二)
本章目標: 掌握application的原理及應用 掌握物件的作用域 掌握cookie的原理及應用 使用jsp訪問資料庫 1、application物件 類似於系統的“全域性變數”,用於同一個伺服器內的所有使用者之間的資料共享,對於整個web伺服器,a
JSP資料互動(二)
1.cookie是由伺服器端生成,傳送給客戶端瀏覽器的,瀏覽器會將其儲存在某個目錄下的文字檔案中。 2.通過cookie,可以實現瀏覽器與伺服器之間的資料傳遞。 3.session與cookie均能實現資訊的儲存,但是二者的區別如下: (1)session是在伺服器端儲存使
第三章 JSP資料互動(二)
1,編寫一個JSP頁面,統計網頁被訪問次數 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HT
OpenStack入門以及一些資料之(二、neutron網路)
L1 L1 是物理層,主要是涉及硬體的一些電氣特性,與偏軟體的 Neutron 虛擬網路從知識脈絡上關係甚少,不展開。 L2 FLAT L2 資料鏈路層通過交換機裝置進行幀轉發。交換機在接收到幀之後(L2 層叫幀,L3 層叫包)先解析出幀頭中的 MAC 地址,再在轉發表中查詢是否有對應 MAC
資料結構(揹包、佇列和棧)
一.揹包 揹包是一種不支援從中刪除元素的集合資料型別,目的是幫助用例收集元素並迭代所有收集到的元素,也可以檢查揹包是否為空,或者獲取揹包中元素的數量。揹包裡面的元素的順序不確定。 要理解揹包的概念,可以想象一個喜歡收集彈珠球的人。他將所有的彈珠球都放在一個揹包裡,一次一個,並且會不時在所有的彈珠球中尋
重學資料結構(二、棧)
@[Toc] # 1、棧的定義和特點 棧(Stack)又稱堆疊, 是限制在表的一端進行插入和刪除運算的線性表。 如果要拿一個東西對比,羽毛球筒比較合適。 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200826204653672.png?#pic_
伺服器端與客戶端使用Json進行資料互動
伺服器端: 引入相應的包:json-lib-2.2-jdk15.jar Action: public String findAll() throws IOException{ List<News> news = newsService.findAll(); //
Android客戶端與伺服器端的json資料互動(很詳細)
Android客戶端與伺服器端的json資料互動,主要是通過json形式的資料互動,就是json的寫入和解析。 先看效果圖,我最討厭講東西,一個圖沒有的。 算了,看來我不是寫部落格的材料,寫不下去了,要排版之類的麻煩,大家還是直接去下載原始碼,裡面有大量的注