1. 程式人生 > >android模擬器連線不到本地伺服器

android模擬器連線不到本地伺服器

報錯資訊: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();
	}