1登錄案例
[1]使用httpurlconnection實現get請求
1.
2.
3. //[1]獲取用戶名和密碼
4. final String name = et_name.getText().toString().trim();
5. final String pwd = et_pwd.getText().toString().trim();
6. //[2]判斷用戶名密碼是否爲空
7. if (TextUtils.isEmpty(name)||TextUtils.isEmpty(pwd)) {
8. Toast.makeText(getApplicationContext(), “用戶名密碼不能爲空”, Toast.LENGTH_LONG).show();
9. }else {
10. //[3]把用戶名和密碼提交到服務器 get形式提交數據就是以組拼url地址的形式提交
11. //http://localhost:8080/login/LoginServlet?username=abc&password=123
12.
13. //創建一個子線程
14. new Thread() {
15. public void run() {
16. try {
17. String path = “http://192.168.81.95:8080/login/LoginServlet?username=“+name+”&password=”+pwd+”“;
18. //[1.2]創建URL 對象指定我們要訪問的 網址(路徑)
19. URL url = new URL(path);
20. //[1.3]拿到httpurlconnection對象 用於發送或者接收數據
21. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
22. //[1.4]設置發送get請求
23. conn.setRequestMethod(“GET”);//get要求大寫 默認就是get請求
24. //[1.5]設置請求超時時間
25. conn.setConnectTimeout(5000);
26. //[1.6]獲取服務器返回的狀態碼
27. int code = conn.getResponseCode();
28. //[1.7]如果code == 200 說明請求成功
29. if (code == 200) {
30. //[1.8]獲取服務器返回的數據
31. InputStream in = conn.getInputStream(); //流裏面的數據是
32.
33. //[1.9]把in轉換成String
34. String content = StreamTools.readInputSream(in);
35.
36. //[2.0]顯示一個土司給用戶友好提示
37. showToast(content);
38.
39. }
40.
41. } catch (Exception e) {
42. e.printStackTrace();
43.
44. }
45.
46.
47. }
48. }.start();
49.
50.
51.
52.
53. }
54.
55.
56.
57.
[2]使用httpurlconnection類實現post請求
總結和post區別
1)請求路徑不同
2)自己要組拼請求體的內容
3)設置post請求 conn.setRequestMethod("POST");
4)數據是以流的形式寫給服務器
1.
2.
3.
4. //[1]獲取用戶名和密碼
5. final String name = et_name.getText().toString().trim();
6. final String pwd = et_pwd.getText().toString().trim();
7. //[2]判斷用戶名密碼是否爲空
8. if (TextUtils.isEmpty(name)||TextUtils.isEmpty(pwd)) {
9. Toast.makeText(getApplicationContext(), “用戶名密碼不能爲空”, Toast.LENGTH_LONG).show();
10. }else {
11. //[3]把用戶名和密碼提交到服務器 get形式提交數據就是以組拼url地址的形式提交
12. //http://localhost:8080/login/LoginServlet?username=abc&password=123
13.
14. //創建一個子線程
15. new Thread() {
16. public void run() {
17. try {
18. //★★★★區別一 訪問的路徑不同 http://192.168.81.95:8080/login/LoginServlet
19. String path = “http://192.168.81.95:8080/login/LoginServlet“;
20.
21. //★★★★區別一 post請求是以請求體的形式提交
22. String data = “username=”+name+”&password=”+pwd+”“;
23.
24. //[1.2]創建URL 對象指定我們要訪問的 網址(路徑)
25. URL url = new URL(path);
26. //[1.3]拿到httpurlconnection對象 用於發送或者接收數據
27. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
28. //[1.4]設置發送get請求 //★★★★區別三 設置post請求
29. conn.setRequestMethod(“POST”);//get要求大寫 默認就是get請求
30. //[1.5]設置請求超時時間
31. conn.setConnectTimeout(5000);
32.
33. //[1.5.1]//★★★★區別四 官方提示要進行post請求 要多設置個參數
34. conn.setDoOutput(true); //設置一個標記 允許conn像服務器輸出數據 數據是以流的形式寫給服務器
35. conn.getOutputStream().write(data.getBytes());
36.
37. //[1.6]獲取服務器返回的狀態碼
38. int code = conn.getResponseCode();
39. //[1.7]如果code == 200 說明請求成功
40. if (code == 200) {
41. //[1.8]獲取服務器返回的數據
42. InputStream in = conn.getInputStream(); //流裏面的數據是
43.
44. //[1.9]把in轉換成String
45. String content = StreamTools.readInputSream(in);
46.
47. //[2.0]顯示一個土司給用戶友好提示
48. showToast(content);
49.
50. }
51.
52. } catch (Exception e) {
53. e.printStackTrace();
54.
55. }
56.
57.
58. }
59. }.start();
60.
61.
62.
63.
64. }
65.
66.
67.
68.
69.
2.httpclient方式提交數據
[1]這個類其實就是一個開源項目 是谷歌工程師把它加到了Android開發環境中 所以不需要在導入jar包
[2]這個類是一個接口 不能new對象要找實現子類
[3]谷歌工程師命名技巧 : base… default….simple….
[4]對http協議封裝 可以執行http的請求
使用httpclient方式實現get請求 代碼如下
1.// [4]創建httpclient實例 由於這個類是一個接口所以我們 實現類
2. DefaultHttpClient client = new DefaultHttpClient();
3. // [4.1]創建httpGet實現類
4. HttpGet get = new HttpGet(path);
5. // [4.2]拿着client對象執行一個get請求
6. HttpResponse response = client.execute(get);
7. // [4.3]獲取服務器返回的狀態碼
8. int code = response.getStatusLine().getStatusCode();
9. if (code == 200) {
10. // [4.4]獲取服務器返回的數據
11. InputStream in = response.getEntity().getContent();
12. // [4.5]把in轉換成String
13. String content = StreamTools.readInputSream(in);
14. // [4.6]展示土司
15. showToast(content);
16.
17. }
使用httpclient實現post請求
1.
2. try {
3. // ★★★★區別一 訪問的路徑不同
4. // http://192.168.81.95:8080/login/LoginServlet
5. String path = “http://192.168.81.95:8080/login/LoginServlet“;
6. // [4]創建httpclient實例 由於這個類是一個接口所以我們 實現類
7. DefaultHttpClient client = new DefaultHttpClient();
8. // [4.1]創建httpPost實現類
9. HttpPost post = new HttpPost(path);
10.
11. //[4.2]
12. //準備parameters 他是list
13. List parameters = new ArrayList();
14. //[4.3]封裝name的數據 第一個參數:要和你Servlet request獲取數據參數的key一樣 第二個參數
15. BasicNameValuePair nameValuePair = new BasicNameValuePair(“username”, name);
16. BasicNameValuePair pwdValuePair = new BasicNameValuePair(“password”, pwd);
17. //[4.4]把nameValuePair 和 pwdValuePair加入daolist集合
18. parameters.add(nameValuePair);
19. parameters.add(pwdValuePair);
20. //[4.5]準備UrlEncodedFormEntity
21. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters);
22. //[4.6]封裝請求的數據 編程思想:參數需要什麼就準備什麼
23. post.setEntity(entity);
24.
25. // [4.2]拿着client對象執行一個post請求
26. HttpResponse response = client.execute(post);
27. // [4.3]獲取服務器返回的狀態碼
28. int code = response.getStatusLine().getStatusCode();
29. if (code == 200) {
30. // [4.4]獲取服務器返回的數據
31. InputStream in = response.getEntity().getContent();
32. // [4.5]把in轉換成String
33. String content = StreamTools.readInputSream(in);
34. // [4.6]展示土司
35. showToast(content);
36.
37. }
38.
39.
40.
41. } catch (Exception e) {
42. e.printStackTrace();
43.
44. }
45.
46.
3 asyncHttpclient實現數據的提交
使用開源項目 思路 new 對象 調用方法
使用get方式提交數據
1.
2.
3. //[1]獲取用戶名和密碼
4. final String name = et_name.getText().toString().trim();
5. final String pwd = et_pwd.getText().toString().trim();
6. //[2]創建asynchttpclient對象
7. AsyncHttpClient client = new AsyncHttpClient();
8. String path = “http://192.168.81.95:8080/login/LoginServlet?username=”
9. + name + “&password=” + pwd + “”;
10. //[3]執行get請求 url就是你要請求的地址
11. client.get(path, new AsyncHttpResponseHandler() {
12. //請求成功
13. @Override
14. public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
15. Toast.makeText(getApplicationContext(), new String(responseBody), Toast.LENGTH_LONG).show();
16.
17. }
18. //請求失敗
19. @Override
20. public void onFailure(int statusCode, Header[] headers,
21. byte[] responseBody, Throwable error) {
22.
23. }
24. });
25.
26.
27.
使用post實現數據提交代碼如下
1.
2.
3. // [1]獲取用戶名和密碼
4. final String name = et_name.getText().toString().trim();
5. final String pwd = et_pwd.getText().toString().trim();
6. //[2]創建asynchttpclient對象
7. AsyncHttpClient client = new AsyncHttpClient();
8. String path = “http://192.168.81.95:8080/login/LoginServlet“;
9. RequestParams params = new RequestParams();
10. params.put(“username”, name);
11. params.put(“password”, pwd);
12.
13. //[3]執行post請求
14. client.post(path, params, new AsyncHttpResponseHandler() {
15.
16. @Override
17. public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
18. Toast.makeText(getApplicationContext(), new String(responseBody), Toast.LENGTH_LONG).show();
19. }
20.
21. @Override
22. public void onFailure(int statusCode, Header[] headers,
23. byte[] responseBody, Throwable error) {
24.
25. }
26. });
27.
28.
4 多線程下載
[1]服務器上有一個文件 把文件下載到客戶端
[2]爲什麼開多個線程 因爲可以提高下載速度
[3]不是開的線程越多下載越快 10000 3 手機迅雷 手雷 建議開3-5個
[4]還受真實服務器帶寬的影響
[5]開多個線程可以提供下載速度 就是cpu搶佔了更多的資源
5 如何實現多線程下載
注意的問題最後拿.exe 安裝文件做測試
元數據 : 數據的數據 我買了一個小汽車
計算每個線程下載的開始位置和結束位置
實現的步驟
[1]獲取文件大小
1.
2. //一 獲取feiq的文件大小
3. try {
4. //[1.2]創建URL 對象指定我們要訪問的 網址(路徑)
5. URL url = new URL(path);
6. //[1.3]拿到httpurlconnection對象 用於發送或者接收數據
7. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
8. //[1.4]設置發送get請求
9. conn.setRequestMethod(“GET”);//get要求大寫 默認就是get請求
10. //[1.5]設置請求超時時間
11. conn.setConnectTimeout(5000);
12. //[1.6]獲取服務器返回的狀態碼
13. int code = conn.getResponseCode();
14. //[1.7]如果code == 200 說明請求成功
15. if (code == 200) {
16. //[1.8]獲取文件的大小
17. int length = conn.getContentLength();
}
[2]在客戶端創建一個大小和服務器一模一樣的文件
1.RandomAccessFile raf = new RandomAccessFile(“temp.exe”, “rw”);
2.raf.setLength(length);
[3]假設開三個線程 算出每個線程下載大小
int blockSize = length / threadCount;
[4]算出每個線程下載的開始位置和結束位置
1.for (int i = 0; i < threadCount; i++) {
2. int startIndex = i*blockSize; //每個線程下載的開始位置
3. int endIndex = (i+1)*blockSize-1; //每個線程下載的結束位置
4. //判斷是否是最後一個線程
5. if (i == threadCount-1) {
6. endIndex = length-1;
7. }
8.
9. }
[5]在for循環裏面開啓多個線程去服務器下載數據 把數據寫到temp.exe文件裏
1.
2. //定義線程 去服務器下載數據
3. private static class DownLoadThread extends Thread{
4. private int startIndex;
5. private int endIndex;
6. private int threadId; //代表線程的id
7. public DownLoadThread(int startIndex,int endIndex,int threadId){
8. this.startIndex = startIndex;
9. this.endIndex = endIndex;
10. this.threadId = threadId;
11.
12. }
13.
14. @Override
15. public void run() {
16.
17. try {
18. //[1.2]創建URL 對象指定我們要訪問的 網址(路徑)
19. URL url = new URL(path);
20. //[1.3]拿到httpurlconnection對象 用於發送或者接收數據
21. HttpURLConnection conn = (HttpURLConnection) url
22. .openConnection();
23. //[1.4]設置發送get請求
24. conn.setRequestMethod(“GET”);//get要求大寫 默認就是get請求
25. //[1.5]設置請求超時時間
26. conn.setConnectTimeout(5000);
27.
28. //[1.5.1]設置一個range頭 告訴服務器每個線程下載的開始位置和結束位置
29. conn.setRequestProperty(“Range”, “bytes=”+startIndex+”-“+endIndex);
30.
31. //[1.6]獲取服務器返回的狀態碼
32. int code = conn.getResponseCode();
33. //[1.7]如果code == 200 說明請求成功 206代表請求部分資源成功
34. if (code == 206) {
35. //[1.8]獲取服務器返回的數據 數據是流的形式返回
36. InputStream in = conn.getInputStream();
37.
38. //[1.9]把數據寫到temp.exe裏面
39. RandomAccessFile raf = new RandomAccessFile(“temp.exe”, “rw”);
40. raf.seek(startIndex);//每個線程從開始位置寫
41.
42. int len = 0;
43. byte[] buffer = new byte[1024];
44. while((len = in.read(buffer))!=-1){
45. raf.write(buffer, 0, len);
46. }
47. raf.close();//關閉流
48. in.close();
49.
50. System.out.println(“線程id:”+threadId+”下載完了”);
51.
52. }
53.
54. } catch (Exception e) {
55. e.printStackTrace();
56.
57. }
58.
59. }
60. }
61.
[6]實現斷點續傳的邏輯
原理:就是把當前線程下載的位置給記錄起來 下次在下載的時候 如果中斷過 就繼續上次斷的位置繼續下
-
- total+=len; //代表當前線程下載的大小
- int currentThreadPosition = startIndex + total; //當前線程下載的位置 把這個位置存到一個普通的文本文件中
-
- //把當前線程下載的位置存到txt中
- RandomAccessFile raff = new RandomAccessFile(getFileName(path)+threadId+”.txt”, “rwd”); //rwd 這個模式直接把數據同步到底層設備
- raff.write(String.valueOf(currentThreadPosition).getBytes());
raff.close();
把當前線程下載的位置記錄下來後 如果中斷過 ,然後把上次下載的位置讀取出來 繼續上次的位置 繼續下
1.if (file.exists()&&file.length()>0) {
2. //說明中斷過 就把上次下載的位置讀出來
3. FileInputStream fis = new FileInputStream(file);
4. BufferedReader bufr = new BufferedReader(new InputStreamReader(fis));
5. String lastDownLoadPosition = bufr.readLine(); //就是上次下載 的位置
6. //改變當前線程下載的開始位置
7. startIndex = Integer.parseInt(lastDownLoadPosition);
8. bufr.close();
9.
10. System.out.println(“線程id:”+threadId+”真實下載的位置:”+startIndex+”—-“+endIndex);
11. }
12.
6 Android下實現多線程下載
與進度相關的控件都可以在子線程直接更新ui. progressBar progressDialog
軟件存在的問題: 好的軟件不是開發出來的 是不斷調試出來 安智市場 類似 360手機助手 豌豆莢 91
4000多行.
[1]反饋 什麼軟件 我都沒有sd卡 文件下載到哪裏了
[2]下載的軟件 也不判斷一下是否是wifi狀態 下載了幾個文件之後 手機流量的沒有了
[3]三星的手機上能夠正常運行 小米手機
[4]下載的文件 也不判斷一下下載的文件是否攜帶病毒
[5]………
7 使用開源項目實現多線程下載
[1]導包
[2]實現代碼如下
1.
2. //獲取下載文件的路徑
3. String path = et_path.getText().toString().trim();
4. //[1]創建HttpUtils 對象的實例
5. HttpUtils http = new HttpUtils();
6. //[2]調用下載的方法 target把下載文件的數據存儲到什麼位置上 autoResume 是否支持斷點續傳
7. http.download(path, “/mnt/sdcard/test.exe”, true, new RequestCallBack() {
8.
9. //下載成功後調用
10. @Override
11. public void onSuccess(ResponseInfo responseInfo) {
12. Toast.makeText(getApplicationContext(),”下載成功”,1).show();
13. }
14.
15. //更新進度條的進度
16. @Override
17. public void onLoading(long total, long current, boolean isUploading) {
18.
19. pb.setMax((int) total);//設置進度條的最進度
20. pb.setProgress((int) current); //設置進度條的當前進度
21.
22. }
23.
24.
25. //下載失敗
26. @Override
27. public void onFailure(HttpException error, String msg) {
28.
29. }
30. });
31.
32.
33.
[3]在實際開發中 什麼情況用開源項目 QQ影音 公司新聞客戶端 什麼情況自己寫.
2天網絡編程總結
網頁源碼查看器: httpurlconnection 用於發送和接收數據
消息機制 handler
圖片查看器 要把流轉換成bitmap 通過位圖工廠類
新聞客戶端 綜合案例 listview 數據適配器 聯網獲取數據 在子線程更新ui xml解析
smartImageView
自定義了一個開源項目
登錄案例 使用httpurlconnection的方式實現數據提交 掌握
httpclient 這個類實現數據的提交 瞭解
asynchttpclient 開源項目實現數據的提交 掌握
多線程下載的邏輯
斷點續傳
移植Android項目
使用開源項目xutils實現多線程下載