Android通过JSON数据格式和java服务后台进行数据交互

前言

进行综合设计的时候,要求做个javaweb项目并挂到服务器上,与此同时在Android上通过访问后台接口实现部分功能。经过了一番的摸索和踩坑,终于实现了和后台服务的通信登陆注册和信息列表显示功能。这是 github 地址,先看一下效果。
在这里插入图片描述

项目介绍

目录结构介绍

picture

功能介绍

登陆功能

首先在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 配置文件注册,同时网络请求也要配置允许设置。
picture

网络请求封装类

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":"每小时"}
]}

借助 JSONArrayJSONObject 两个对象将 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);
	}
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值