Android从4.0版本开始,就不建议Main线程直接进行网络通信。
所以,在用高版本开发网络通信,无论是socket的长连接,还是http的短连接,都使用多线程的方式去通信,以防止UI界面加载等待,或者卡死。
下面就说一种Android的HTTP通信,服务器段用的是SpringMVC。
为什么选择SpringMVC,因为当你的WebService使用SpringMVC的话,会出现服务器接收不到请求参数的问题。对于一些新手而言,这可能非常致命,那如果采用最基础的servlet去搭建服务器端的话,会占用大量的开发时间。
Android端:
此处,我存在两个界面,一个LogingActivity和MainActivity。 在LogingActivity请求服务器成功后,进入mainActivity。
Android的页面布局我就不粘出来了,只有两个输入框,和一个按钮。
public class LoginActivity extends Activity { private EditText name,psd; private Button login; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); name = (EditText) findViewById(R.id.ed_username); psd = (EditText) findViewById(R.id.ed_psd); login = (Button) findViewById(R.id.btnLogin); login.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //发送请求 //4.0开始不支持直接访问。 final Handler myHandler = new Handler(){ @Override public void handleMessage(Message msg) { String result = msg.obj.toString(); System.out.println(result); if(!result.equals("")){ Intent intent = new Intent(LoginActivity.this,MainActivity.class); startActivity(intent); }else{ Toast.makeText(LoginActivity.this, "错误", Toast.LENGTH_SHORT).show(); } super.handleMessage(msg); } }; new Thread(new Runnable() { @Override public void run() { LogingToServer login = new LogingToServer(); String result = login.doPost(name.getText().toString(), psd.getText().toString()); //发送消息 Message msg = new Message(); msg.obj = result; myHandler.sendMessage(msg); } }).start(); } }); } }
对于这一块的知识,网上有很多相关的资料,视频。可以去看一下。并不难。占用不了几分钟,我这里就不讲了。
MainActivity页面,也只是一个普通布局,随便写都可以,空白也行。
在上面的代码中,会看到我使用了一个类LogingToServer类,下面是这个类的代码
public class LogingToServer {
private String url = "http://192.168.2.21:8080/AndroidServer/user/login";
public String doGet(String name,String psd){
return doPost(name,psd);
}
public String doPost(String name,String psd){
String result = "";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpEntity entity;
HttpResponse response;
//设置头
String agent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3";
httpPost.setHeader("User-Agent", agent);
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
pairs.add(new BasicNameValuePair("userId", name));
pairs.add(new BasicNameValuePair("userPassword", psd));
for (NameValuePair nameValuePair : pairs) {
System.out.println(nameValuePair.getName() + "--------" + nameValuePair.getValue());
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(pairs,"UTF-8"));
response = httpClient.execute(httpPost);
entity = response.getEntity();
if(entity != null){
InputStream is = entity.getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line = "";
while((line = in.readLine()) != null){
buffer.append(line);
}
is.close();
result = buffer.toString();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
该处一定要注意我唯一写注释的地方,因为,这个地方关系到你 SpringMVC获取参数正不正常。
url改为自己webService路径即可。
下面是我服务端的代码。
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
@ResponseBody
public Map<String, Object> login(HttpServletRequest request,HttpServletResponse response,ModelAndView modelAndView,RedirectAttributes attr,User user){
System.out.println("-----------");
Map<String,Object> map = new HashMap<String, Object>();
map.put("code", "111111111");
return map;
}
}
在这里我接收参数用的是一个实体类。里面包含两个字段,也就是Android传的两个参数名。userId和userPassword。 如果你不太熟悉SpringMVC的话,那该实体类这两个字段名一定要与Android穿的两个参数名完全一样,否则接收不到。
Ok,自己测试一下吧,如果有什么不明白,可以留言。