做应用型的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:
输入正确的信息: