报错信息:NetworkOnMainThreadException
如果你架构了一个webservice,用android模拟器的浏览器打开网页没有问题,但是模拟器里的项目就是死活连不上,那你得好好看看你的HTTP请求是否放到了主线程里,android在4.0之后已经不允许在主线程执行http请求了。
遇到这个情况最好就开多一个线程吧。
有一个很不推荐的方法解决,就是强制执行:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
其他连接本地服务器的注意事项还有:
1.模拟器是没办法识别Localhost的,127.0.0.1是连接模拟器本身,如果要连接本地的电脑IP,需要使用10.0.2.2这个地址。
2.连接外网需要在manifest中增加上网的权限。
一个登录的小例子,使用了httpclient,在此就不贴多余的代码了:
客户端:
添加登录按钮的事件:判断帐号密码是否为空,获取帐号和密码并发送
new onClickListener(){
void onClick(view v){
String username=username.getText().toString();
String password=password.getText().toString();
if(null != username && null != password && username.length>0 && password.length>0){
//调用doLogin方法来发送帐号密码到服务器,并得到返回值
String ret =doLogin(username,password);
//如果返回值不为空,则在tv文本框显示结果
if(null != ret){
tv.setText("返回结果为:"+ret);
}else{
tv.setText("请求失败!")
}
}
}
}
private String doLogin(String username,String password){
try{
//创建参数List并添加值,实际犹如xxxxx:8080/doLogin?username=xx&password=xx
//注意是BasicNameValuePair
List<NameValuePair> params =new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username",username));
params.add(new BasicNameValuePair("password",password));
//创建post,切记模拟器不能识别localhost,要换成10.0.2.2
HttpPost post =new HttpPost("http://10.0.2.2:8080/TestServer/doLogin");
//为post设置Entity,通过UrlEncodedFormEntity这个方法把params转化为HttpEntity
post.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF-8));
//创建服务器响应对象response
HttpResponse httpResponse;
//创建了客户端对象Client并利用它执行了post,服务器根据传输的post做出响应的返回值,返回值赋予给response
httpResponse=new DefaultHttpClient().execute(post);
//得到响应对象的状态Code,SC_OK=200,也就是访问页面成功,404则是找不到页面
if(httpResponse.getStatusLine().getStatusCode == HttpStatus.SC_OK){
//Entity.Utils工具类的toString把httpResponse里的Entity转化为String,并返回该值
String result = EntityUtils.toString(httpResponse.getEntity());
return result;
}
}catch(..){
...
}
}
创建一个servlet:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取接收到的值
String username=request.getParameter("username");
String password=request.getParameter("password");
//设置编码
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "text/html;charset=UTF-8");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try {
//加载jdbc驱动
Class.forName("com.mysql.jdbc.Driver");
//连接数据库,这里我用的是mysql
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/TestServer","root","root");
//创建陈述对象
Statement st=conn.createStatement();
//编写sql语句
String sql="Select * from User Where username='"+username+"' and password='"+password+"'";
//使用陈述对象执行sql语句,并把返回值赋给rs
ResultSet rs=st.executeQuery(sql);
//如果返回值不为空,则用out传输过去“登陆成功”
if(rs.next()!=false){
out.print("登录成功");
System.out.print("登录成功");
}else{
out.print("帐号或密码错误!");
System.out.print("登录失败");
}
//关闭连接
rs.close();
st.close();
conn.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.flush();
out.close();
}