Android客户端分为User,HttpUtil,HttpCallbackListener,MainActivity四个部分。User model与服务端的一样,一方面是用于本地用户信息的存储model,另一方面也是为了保证构造URL时使用的key一致。
HttpUtil封装了发送Http请求的过程和构造URL的函数,HttpCallbackListener是用于发送请求后的回调接口,MainActivity就是用于测试的Activity交互界面了。
不再贴出,见上一篇 Android 客户端与服务器端进行数据交互(一、安卓客户端)
回调接口定义了两个函数,一个是正常结束时回调的onFinish,一个是出现异常时的onError
//请求回调接口
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
}
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 params) throws UnsupportedEncodingException {
//设置编码
final String encode = "UTF-8";
StringBuilder url = new StringBuilder(address);
url.append("?");
//将map中的key,value构造进入URL中
for(Map.Entry 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界面,包括了两个输入框和一个按钮。
布局效果图如下
<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首先将输入框中的用户名和密码取出,构造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 params = new HashMap();
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消息机制等等。不过都是最基础的使用级别,应该不难理解。
希望这篇文章对新手有所帮助,同时我自己在写的过程中也有了更深的体会。
转载请注明出处http://blog.csdn.net/u012145166/article/details/51334688
下载源码,请猛戳这里