Android 客户端与服务器端进行数据交互(二、登录客户端)

概要

Android客户端分为User,HttpUtil,HttpCallbackListener,MainActivity四个部分。User model与服务端的一样,一方面是用于本地用户信息的存储model,另一方面也是为了保证构造URL时使用的key一致。
HttpUtil封装了发送Http请求的过程和构造URL的函数,HttpCallbackListener是用于发送请求后的回调接口,MainActivity就是用于测试的Activity交互界面了。

User model

不再贴出,见上一篇 Android 客户端与服务器端进行数据交互(一、安卓客户端)

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消息机制等等。不过都是最基础的使用级别,应该不难理解。

希望这篇文章对新手有所帮助,同时我自己在写的过程中也有了更深的体会。
转载请注明出处http://blog.csdn.net/u012145166/article/details/51334688
下载源码,请猛戳这里

  • 29
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值