編輯:關於Android編程
前面相繼介紹了Android網絡編程裡的Socket傳輸圖片、HttpURLConnection,今天看HttpClient.
第一部分:JavaEE版的Eclipse配置Tomcat
【備注:開發後台服務器用Eclipse的JavaEE版最好的,但單就Tomcat來說(不寫jsp之類的),本文下面的服務器方面操作在普通版的Eclipse也是可以的。我這裡為了和ADT-bundle分開,特意重新安個JavaEE版的Eclipse。】
1、下載Eclipse的Tomcat插件:http://www.eclipsetotale.com/tomcatPlugin.html 將其解壓得到com.sysdeo.eclipse.tomcat_3.3.0文件夾。將它復制到eclipse的plugins文件夾下。 重啟Eclipse會看到上面有三個小貓,哈哈
vcWxvqOs5K/AwMb3yuTI6zpodHRwOi8vbG9jYWxob3N0OjgwODAvIL+0tb3QocOose3KvndpbmRvd3PJz7XEdG9tY2F0xeS6w8HLoaM8L3A+PHA+M6Gi0MK9qNK7uPZqYXZhuaSzzKOs1NrA78Pm0aHU8VRvbWNhdCBQcm9qZWN0uaSzzMjnzbzL+cq+OjwvcD48cD48aW1nIHNyYz0="/uploadfile/Collfiles/20140504/2014050408590624.png" alt="\" />
配置Tomcat和Server選項:
備注:新建工程這塊也可以在Web裡選擇新建Dynamic Web Project,這是標准的使用Servlet、JSP等技術開發動態網站的項目,需要JavaEE版的Eclipse。
第二部分:聯通浏覽器和Tomcat
即在浏覽器輸入一個網址,tomcat裡返回一句話,浏覽器收到並顯示。之所以弄這一步一是為了測試,二是後來會發現,Android裡的HttpClient就跟這個浏覽器一樣。
1.在WEB-INF/src文件夾下新建包名org.yanzi.testtomcat,在裡面新建一個類TestTomcat繼承自HttpServlet.並重寫裡面的doGet方法。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
// //用HTML格式給浏覽器返回數據
// out.println("");
// out.println("
2.在WEB-INF文件夾下新建文件wem.xml,內容如下:
關於上面的配置注意:a. servlet-name是servlet的名字,這個名字可以隨便起。只要servlet-name標簽裡名字一樣就可以了。b. servlet-class裡寫包名+類名。c. url-pattern這裡也是隨便寫的,是輸入浏覽器裡的地址。本博文中浏覽器的地址是:
http://localhost:8080/TestTomcat/login 這裡的8080是端口,是在tomcat安裝文件裡的conf裡的server.xml配置好的,用默認的就ok。除非此端口已被其他占用。 TestTomcat這裡指的是工程的名字,而非類的名字。最後的“/login”跟web.xml裡對應,注意後面不要再多加一個斜槓成這樣"/login/", 這是解析不了的。
3. 修改conf文件夾下的tomcat-users.xml文件,在裡面添加一個用戶:
默認的都是全被注釋掉的。
然後就可以點擊eclipse上的小貓頭像,開啟這個servlet服務了。浏覽器輸入http://localhost:8080/TestTomcat/login 可以看到:
在doGet()函數裡用html格式輸出,即:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
//用HTML格式給浏覽器返回數據
out.println("");
out.println("
看到效果:
這是因為用html格式給它設置了標題名字,並打印了一句話。這裡真想吐槽一下,最初我用百度浏覽器倒置了兩個小時都沒有出來,後來在google浏覽器裡一輸入就ok了。真心坑爹啊。另外,如果浏覽器在看視頻,貌似也是出不來的。大爺的,此點麼深究!!
第三部分:重寫TestTomcat裡的doPost()和doGet()方法。
因為我准備再手機上用doPost跟Tomcat通信,傳遞一個用戶名和密碼。Tomcat判斷後再返回結果。改好後的TestTomcat.java的完整文件如下:
package org.yanzi.testtomcat; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestTomcat extends HttpServlet { private static final long serialVersionUID = 1L; private static final int NAME_CODE_RIGHT = 0; // private static final int CODE_WRONG = 1; // private static final int NAME_WRONG = 2; // public TestTomcat(){ } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub if(req == null){ return; } resp.setContentType("text/html;charset=utf-8"); req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); PrintWriter out = resp.getWriter(); String name = req.getParameter("NAME"); String code = req.getParameter("CODE"); /* //浏覽器訪問,沒傳遞任何參數。用HTML格式給浏覽器返回數據 out.println(""); out.println(""); out.println("Tomcat Servlet測試 "); out.println(""); out.println(""); out.println("Hello,哥知道你是浏覽器訪問的."); out.println(""); out.println(""); out.println("Hello,第一個Tomcat!!!"); out.close();*/ //手機客戶端訪問 int ret = checkSubmit(name, code); out.print(ret); out.flush(); out.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub if(req == null){ return; } resp.setContentType("text/html;charset=utf-8"); req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); PrintWriter out = resp.getWriter(); String name = req.getParameter("NAME"); String code = req.getParameter("CODE"); int ret = checkSubmit(name, code); out.print(ret); out.flush(); out.close(); } /** * 判斷登錄名和密碼 * @param name * @param code * @return */ private int checkSubmit(String name, String code){ int ret = -2; if(name.equals("admin")){ if(code.equals("123")){ ret = NAME_CODE_RIGHT; }else{ ret = CODE_WRONG; } }else{ ret = NAME_WRONG; } return ret; } }
AndroidManifest.xml裡加權限:
activity_main.xml的內容:
package org.yanzi.testtomecat; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.DefaultClientConnection; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ScrollView; import android.widget.TextView; public class MainActivity extends Activity { public static final String URL = "http://192.168.16.8:8080/TestTomcat/login"; Button submitBtnPost = null; Button submitBtnGet = null; TextView infoTextView = null; EditText nameEdit = null; EditText codeEdit = null; ScrollView scrollView = null; boolean isPost = true; //默認采取post登錄方式 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); scrollView = (ScrollView)findViewById(R.id.info_scroll_view); submitBtnPost = (Button)findViewById(R.id.btn_submit_post); submitBtnGet = (Button)findViewById(R.id.btn_submit_get); infoTextView = (TextView)findViewById(R.id.tv_info); nameEdit = (EditText)findViewById(R.id.edit_name); codeEdit = (EditText)findViewById(R.id.edit_code); submitBtnPost.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub isPost = true; new SubmitAsyncTask().execute(URL); } }); submitBtnGet.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub isPost = false; new SubmitAsyncTask().execute(URL); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public class SubmitAsyncTask extends AsyncTask{ String info = ""; @Override protected String doInBackground(String... params) { // TODO Auto-generated method stub String url = params[0]; String reps = ""; if(isPost){ info = "HttpPost返回結果: "; reps = doPost(url); }else{ info = "HttpGet返回結果: "; reps = doGet(url); } return reps; } @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub infoTextView.append("\n" + info + result +"\n"); String res = result.trim(); if(res.equals("0")){ info = "驗證通過....."; }else if(res.equals("1")){ info = "密碼錯誤....."; }else if(res.equals("2")){ info = "用戶名錯誤....."; }else if(res.equals("-1")){ info = "返回結果異常!"; } infoTextView.append(info + "\n"); scrollView.fullScroll(ScrollView.FOCUS_DOWN); super.onPostExecute(result); } } private String doGet(String url){ String responseStr = ""; try { String name = nameEdit.getText().toString().trim(); String code = codeEdit.getText().toString().trim(); String getUrl = URL + "?NAME=" + name+"&"+"CODE=" + code; HttpGet httpRequest = new HttpGet(getUrl); HttpParams params = new BasicHttpParams(); ConnManagerParams.setTimeout(params, 1000); HttpConnectionParams.setConnectionTimeout(params, 3000); HttpConnectionParams.setSoTimeout(params, 5000); httpRequest.setParams(params); HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest); final int ret = httpResponse.getStatusLine().getStatusCode(); if(ret == HttpStatus.SC_OK){ responseStr = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8); }else{ responseStr = "-1"; } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return responseStr; } /** * 用Post方式跟服務器傳遞數據 * @param url * @return */ private String doPost(String url){ String responseStr = ""; try { HttpPost httpRequest = new HttpPost(url); HttpParams params = new BasicHttpParams(); ConnManagerParams.setTimeout(params, 1000); //從連接池中獲取連接的超時時間 HttpConnectionParams.setConnectionTimeout(params, 3000);//通過網絡與服務器建立連接的超時時間 HttpConnectionParams.setSoTimeout(params, 5000);//讀響應數據的超時時間 httpRequest.setParams(params); //下面開始跟服務器傳遞數據,使用BasicNameValuePair List paramsList = new ArrayList (); String name = nameEdit.getText().toString().trim(); String code = codeEdit.getText().toString().trim(); paramsList.add(new BasicNameValuePair("NAME", name)); paramsList.add(new BasicNameValuePair("CODE", code)); UrlEncodedFormEntity mUrlEncodeFormEntity = new UrlEncodedFormEntity(paramsList, HTTP.UTF_8); httpRequest.setEntity(mUrlEncodeFormEntity); HttpClient httpClient = new DefaultHttpClient(); HttpResponse httpResponse = httpClient.execute(httpRequest); final int ret = httpResponse.getStatusLine().getStatusCode(); if(ret == HttpStatus.SC_OK){ responseStr = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8); }else{ responseStr = "-1"; } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return responseStr; } }
1、核心在doGet()和doPost()兩個函數裡,可以看到用get方式比用post傳遞參數更方便,可以直接寫到url裡。使用get方式時傳遞數據在url裡寫的:
String name = nameEdit.getText().toString().trim();
String code = codeEdit.getText().toString().trim();
String getUrl = URL + "?NAME=" + name+"&"+"CODE=" + code;
post方式時是用BasicNameValuePair來弄的。其他流程都差不多。首先new一個HttpGet或HttpPost,然後設參數,共設三個,作用注釋裡有。然後設參數,傳數據,通過HttpResponse httpResponse = httpClient.execute(httpRequest);得到返回結果。
2、如果在Tomcat裡使用的是out.println(),則再解析數據時需要再得到的String上trim()一下,否則會錯。
3、Android客戶端URL地址為:
public static final String URL = "http://192.168.16.8:8080/TestTomcat/login";
這裡的IP就是電腦的IP加端口號就ok。
當然這僅是個最基本的示例,遺留問題:
1.JSON傳遞數據
2.每次鏈接都開一個DefaultHttpClient很不科學。
參考:
http://blog.chinaunix.net/uid-25799257-id-3774015.html
http://blog.chinaunix.net/uid-25799257-id-3774047.html
周末閒著沒事,寫了個手勢解鎖的view,實現起來也蠻快的,半天多一點時間就完事。把源碼和資源貼出來,給大家分享,希望對大家有用。效果,就跟手機上的九點手勢解鎖一樣,上個圖
上一篇文章裡把SwipeRefreshLayout的原理簡單過了一下,大致了解了其工作原理,不熟悉的可以去看一下:http://www.jb51.net/article/
本文實例介紹的是Android的Tab控件,Tab控件可以達到分頁的效果,讓一個屏幕的內容盡量豐富,當然也會增加開發的復雜程度,在有必要的時候再使用。Android的Ta
接觸過自定義控件的開發者一看,笑了,立馬關了網頁。但是…你真的知道怎麼繪制居中文本嗎?我不會?開玩笑,不就是:X=控件寬度/2 - 文本寬度/2;Y=控件高