做应用型的APP肯定是要和网络交互的,那么本节就来实战一把Android访问网络API,还是使用上节的DEMO:
一、准备API:
一般都采用Json作为数据交换格式,目前各种语言均能输出Json串。
假如使用PHP输出一段简单的Json,可以这么写:
<?php $arr = array ('users'=>array('mady','123')); echo json_encode($arr); ?>
输出的Json如下:
{"users":["mady","123"]}
也可以使用VS创建一个API直接序列化一个数组,或者其他任何方式只要数据格式正确就没问题。
二、实现网络API访问:
首先访问网络需要授权,也就是安装时提醒打对勾的那部分:
打开Bin/res/AndroidManifest.xml在根节点下面加入一个授权申请节点:
<uses-permission android:name="android.permission.INTERNET"/>
然后是访问网络,这里有一段从网上来的访问类:
import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; public class HttpUtils { /** * @param path 请求的服务器URL地址 * @param encode 编码格式 * @return 将服务器端返回的数据转换成String */ public static String sendPostMessage(String path, String encode) { String result = ""; HttpClient httpClient = new DefaultHttpClient(); try { HttpPost httpPost = new HttpPost(path); HttpResponse httpResponse = httpClient.execute(httpPost); if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { HttpEntity httpEntity = httpResponse.getEntity(); if(httpEntity != null) { result = EntityUtils.toString(httpEntity, encode); } } } catch (Exception e) { e.printStackTrace(); } finally { httpClient.getConnectionManager().shutdown(); } return result; } }
还有一段从网上来的Json解析类,使用Android自带的解析库:
import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; public class JsonUtil { /** * @param citiesString 从服务器端得到的JSON字符串数据 * @return 解析JSON字符串数据,放入List当中 */ public static List<String> parseCities(String citiesString) { List<String> cities = new ArrayList<String>(); try { JSONObject jsonObject = new JSONObject(citiesString); JSONArray jsonArray = jsonObject.getJSONArray("users"); for(int i = 0; i < jsonArray.length(); i++) { cities.add(jsonArray.getString(i)); } } catch (Exception e) { e.printStackTrace(); } return cities; } }
最后需要注意的就是在Android中访问网络必须是异步方式,同步方式直接报错,所以需要增加异步访问:
public class MyAsyncTask extends AsyncTask<String, Void, List<String>> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected List<String> doInBackground(String... params) { List<String> cities = new ArrayList<String>(); String citiesString = HttpUtils.sendPostMessage(params[0], "utf-8"); cities = JsonUtil.parseCities(citiesString); return cities; } @Override protected void onPostExecute(List<String> result) { TextView lblInfo=(TextView)findViewById(R.id.form_title); EditText txt_login_name=(EditText)findViewById(R.id.txt_login_name); EditText txt_login_pass=(EditText)findViewById(R.id.txt_login_pwd); String loginName=txt_login_name.getText().toString().trim(); String loginPass=txt_login_pass.getText().toString().trim(); if(loginPass.equals(result.get(1))&&loginName.equals(result.get(0))) { lblInfo.setText("登录成功!"); } else { lblInfo.setText("登录失败!"); } super.onPostExecute(result); } }
分为访问前、访问中、访问后(估计是方便增加进度条),我们在访问后增加处理代码即可,然后在上节的按钮点击事件下调用:
private final String CITY_PATH_JSON = "http://192.168.1.6:89/Login2.php"; public void btn_click(View v) { new MyAsyncTask().execute(CITY_PATH_JSON); }
唯一需要的说明:访问后的Result类型就是访问中的返回值类型
唯二需要哦的说明:API必须架设在另外的机器上,而且必须使用IP访问,因为localhost和127都被模拟器自己用了.
先看看登录的用户名和密码是什么,访问下API:
运行APP:
输入正确的信息: