前言,Android的網絡通信的方式有兩種:使用Socket或者HTTP,今天這一篇我們詳細講解使用HTTP實現的網絡通信,HTTP又包括兩種方式編程方式:
(1)HttpUrlConnection;
(2)HttpClient;
? ?好了,我們直接進行講解,當然之前也會有一部分有關Android網絡通信的其他知識,我們也應該了解。
?
一.獲取網絡狀態的方法
(1)MainActivity.java中的關鍵代碼
1 2 3 4 5 6 7 8 | //網絡管理類,可以判斷是否能上網,以及網絡類型 ???????????? ConnectivityManager cm=(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); ???????????? NetworkInfo info=cm.getActiveNetworkInfo(); ???????????? if (info!= null ){ ???????????????? Toast.makeText(MainActivity. this ,? "連網正常" +info.getTypeName(), Toast.LENGTH_SHORT).show(); ???????????? } else { ???????????????? Toast.makeText(MainActivity. this ,? "未連網" , Toast.LENGTH_SHORT).show(); ???????????? } |
(2)注意:一定要在主配置文件中增加這個權限
? ?它是application的兄弟標簽:
1 | <uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE" /> |
(3)OK,我們看一下我們的設備的上網狀態和類型吧:
?
二.使用URL訪問網頁源碼
(1)MainActivity.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | package ?com.example.l0903_urldata; import ?java.io.BufferedReader; import ?java.io.IOException; import ?java.io.InputStream; import ?java.io.InputStreamReader; import ?java.net.MalformedURLException; import ?java.net.URL; import ?android.app.Activity; import ?android.os.Bundle; /** ? * 訪問網頁源碼 ? * @author asus ? * ? */ public ?class ?MainActivity? extends ?Activity { ???? @Override ???? protected ?void ?onCreate(Bundle savedInstanceState) { ???????? super .onCreate(savedInstanceState); ???????? setContentView(R.layout.activity_main); ???????? try ?{ ???????????? //訪問百度的html文件的源碼 ???????????? InputStream is= new ?URL( "http://www.baidu.com" ).openStream(); ???????????? //讀取數據的包裝流 ???????????? BufferedReader br= new ?BufferedReader( new ?InputStreamReader(is)); ???????????? //str用于讀取一行數據 ???????????? String str= null ; ???????????? //StringBuffer用于存儲所欲數據 ???????????? StringBuffer sb= new ?StringBuffer(); ???????????? while ((str=br.readLine())!= null ){ ???????????????? sb.append(str); ???????????? } ???????????? System.out.println(sb.toString()); ???????? }? catch ?(MalformedURLException e) { ???????????? e.printStackTrace(); ???????? }? catch ?(IOException e) { ???????????? e.printStackTrace(); ???????? } ???? } } |
(2)注意:有關網絡的操作都需要在主配置文件里添加下面這個權限:
1 | <uses-permission android:name= "android.permission.INTERNET" /> |
?
三.WebView 控件的簡單使用
? ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package ?com.example.l0903_webview; import ?android.app.Activity; import ?android.os.Bundle; import ?android.webkit.WebView; /** ? * 就是一個瀏覽器控件 ? * 其實沒什么用 ? * @author asus ? * ? */ public ?class ?MainActivity? extends ?Activity { ???? private ?WebView wv; ???? @Override ???? protected ?void ?onCreate(Bundle savedInstanceState) { ???????? super .onCreate(savedInstanceState); ???????? setContentView(R.layout.activity_main); ???????? wv=(WebView) findViewById(R.id.webView1); ???????? //WebView控件的方法,loadUrl用于加載指定的網絡地址 ???????? wv.loadUrl( "http://www.baidu.com" ); ???? } } |
? ?運行效果:
?
四.使用HttpUrlConnection的編寫方式實現Android的網絡通信
1.首先,自己先搭建一個服務器:
?
?
2.下面是客戶端的事了:
(1)通過get方式:
? ?MainActivity.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | package ?com.example.l0903_httpurlcnectionget; import ?java.io.BufferedReader; import ?java.io.IOException; import ?java.io.InputStream; import ?java.io.InputStreamReader; import ?java.net.HttpURLConnection; import ?java.net.MalformedURLException; import ?java.net.URL; import ?android.app.Activity; import ?android.os.Bundle; import ?android.view.View; import ?android.view.View.OnClickListener; import ?android.widget.EditText; import ?android.widget.TextView; /** ? * 通過Get方法獲取服務器的數據 ? * 直接在地址中用"?+鍵值+value"的方式來使用 ? * 所以傳遞的參數直接顯示出來,不安全 ? * @author asus ? * ? */ public ?class ?MainActivity? extends ?Activity { ???? private ?HttpURLConnection conn; ???? private ?URL url; ???? private ?InputStream is; ???? private ?TextView tv; ???? private ?EditText et; ???? private ?String name; ???? @Override ???? protected ?void ?onCreate(Bundle savedInstanceState) { ???????? super .onCreate(savedInstanceState); ???????? setContentView(R.layout.activity_main); ???????? tv=(TextView) findViewById(R.id.textView1); ???????? et=(EditText) findViewById(R.id.editText1); ???????? findViewById(R.id.button1).setOnClickListener( new ?OnClickListener() { ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ????????????? @Override ???????????? public ?void ?onClick(View v) { ???????????????? name=et.getText().toString(); ???????????????? //定義訪問的服務器地址,10.0.2.2是Android的訪問的本地服務器地址 ???????????????? String urlDate= "http://10.0.2.2:8080/My_Service/webdate.jsp?name=" +name; ???????????????? try ?{ ???????????????????? //封裝訪問服務器的地址 ???????????????????? url= new ?URL(urlDate); ???????????????????? try ?{ ???????????????????????? //打開對服務器的連接 ???????????????????????? conn=(HttpURLConnection) url.openConnection(); ???????????????????????? //連接服務器 ???????????????????????? conn.connect(); ???????????????????????? /**讀入服務器數據的過程**/ ???????????????????????? //得到輸入流 ???????????????????????? is=conn.getInputStream(); ???????????????????????? //創建包裝流 ???????????????????????? BufferedReader br= new ?BufferedReader( new ?InputStreamReader(is)); ???????????????????????? //定義String類型用于儲存單行數據 ???????????????????????? String line= null ; ???????????????????????? //創建StringBuffer對象用于存儲所有數據 ???????????????????????? StringBuffer sb= new ?StringBuffer(); ???????????????????????? while ((line=br.readLine())!= null ){ ???????????????????????????? sb.append(line); ???????????????????????? } ???????????????????????? //用TextView顯示接收的服務器數據 ???????????????????????? tv.setText(sb.toString()); ???????????????????????? System.out.println(sb.toString()); ???????????????????? }? catch ?(IOException e) { ???????????????????????? e.printStackTrace(); ???????????????????? } ???????????????? }? catch ?(MalformedURLException e) { ???????????????????? e.printStackTrace(); ???????????????? } ???????????? } ???????? }); ???? } } |
? ?權限(同上面第二個,所有與網絡有關的操作都需要添加,下面的就不再贅述了)
? ?運行效果:
?
(2)通過post方式(安全)
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | package ?com.example.l0903_httpurlconectionpost; import ?java.io.BufferedReader; import ?java.io.DataOutputStream; import ?java.io.IOException; import ?java.io.InputStream; import ?java.io.InputStreamReader; import ?java.io.OutputStream; import ?java.net.HttpURLConnection; import ?java.net.MalformedURLException; import ?java.net.URL; import ?java.net.URLEncoder; import ?android.app.Activity; import ?android.os.Bundle; import ?android.view.View; import ?android.view.View.OnClickListener; import ?android.widget.EditText; import ?android.widget.TextView; /** ? * 通過Post方法傳遞參數 ? * 安全 ? * @author asus ? * ? */ public ?class ?MainActivity? extends ?Activity { ???? private ?HttpURLConnection conn; ???? private ?URL url; ???? private ?InputStream is; ???? private ?OutputStream os; ???? private ?EditText et; ???? private ?TextView tv; ???? @Override ???? protected ?void ?onCreate(Bundle savedInstanceState) { ???????? super .onCreate(savedInstanceState); ???????? setContentView(R.layout.activity_main); ???????? et=(EditText) findViewById(R.id.editText1); ???????? tv=(TextView) findViewById(R.id.tv); ???????? findViewById(R.id.button1).setOnClickListener( new ?OnClickListener() { ?????????????????????????????????????????????????????????????????????????????????? ????????????? @Override ???????????? public ?void ?onClick(View v) { ???????????????? // TODO Auto-generated method stub ???????????????? String urlDate= "http://10.0.2.2:8080/My_Service/webdate.jsp" ; ???????????????? try ?{ ???????????????????? url= new ?URL(urlDate); ???????????????????? try ?{ ???????????????????????? //打開服務器 ???????????????????????? conn=(HttpURLConnection) url.openConnection(); ???????????????????????? //設置輸入輸出流 ???????????????????????? conn.setDoOutput( true ); ???????????????????????? conn.setDoInput( true ); ???????????????????????? //設置請求的方法為Post ???????????????????????? conn.setRequestMethod( "POST" ); ???????????????????????? //Post方式不能緩存數據,則需要手動設置使用緩存的值為false ???????????????????????? conn.setUseCaches( false ); ???????????????????????? //連接數據庫 ???????????????????????? conn.connect(); ???????????????????????? /**寫入參數**/ ???????????????????????? os=conn.getOutputStream(); ???????????????????????? //封裝寫給服務器的數據(這里是要傳遞的參數) ???????????????????????? DataOutputStream dos= new ?DataOutputStream(os); ???????????????????????? //寫方法:name是key值不能變,編碼方式使用UTF-8可以用中文 ???????????????????????? dos.writeBytes( "name=" +URLEncoder.encode(et.getText().toString(),? "UTF-8" )); ???????????????????????? //關閉外包裝流 ???????????????????????? dos.close(); ???????????????????????? /**讀服務器數據**/ ???????????????????????? is=conn.getInputStream(); ???????????????????????? BufferedReader br= new ?BufferedReader( new ?InputStreamReader(is)); ???????????????????????? String line= null ; ???????????????????????? StringBuffer sb= new ?StringBuffer(); ???????????????????????? while ((line=br.readLine())!= null ){ ???????????????????????????? sb.append(line); ???????????????????????? } ???????????????????????? tv.setText(sb.toString()); ???????????????????????? System.out.println(sb.toString()); ???????????????????? }? catch ?(IOException e) { ???????????????????????? e.printStackTrace(); ???????????????????? } ???????????????? }? catch ?(MalformedURLException e) { ???????????????????? e.printStackTrace(); ???????????????? } ???????????? } ???????? }); ?????????????????????????????????????????????????????????????????????????? ????? } } |
?
?
五.使用HttpClient的編寫方式實現Android的網絡通信
1.服務器同上;
2.使用get的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | package ?com.example.l0903_http_get; import ?java.io.BufferedReader; import ?java.io.IOException; import ?java.io.InputStream; import ?java.io.InputStreamReader; import ?org.apache.http.HttpEntity; import ?org.apache.http.HttpResponse; import ?org.apache.http.client.ClientProtocolException; import ?org.apache.http.client.HttpClient; import ?org.apache.http.client.methods.HttpGet; import ?org.apache.http.impl.client.DefaultHttpClient; import ?android.app.Activity; import ?android.os.Bundle; public ?class ?MainActivity? extends ?Activity { ???? private ?HttpGet get; ???? private ?HttpClient cliet; ???? private ?HttpResponse response; ???? private ?HttpEntity entity; ???? private ?InputStream is; ???? @Override ???? protected ?void ?onCreate(Bundle savedInstanceState) { ???????? super .onCreate(savedInstanceState); ???????? setContentView(R.layout.activity_main); ???????? get= new ?HttpGet( "http://10.0.2.2:8080/My_Service/webdate.jsp?name=ooooooo" ); ???????? cliet= new ?DefaultHttpClient(); ???????? try ?{ ???????????? response=cliet.execute(get); ???????????? entity=response.getEntity(); ???????????? is=entity.getContent(); ???????????? BufferedReader br= new ?BufferedReader( new ?InputStreamReader(is)); ???????????? String line= null ; ???????????? StringBuffer sb= new ?StringBuffer(); ???????????? while ((line=br.readLine())!= null ){ ???????????????? sb.append(line); ???????????? } ???????????? System.out.println(sb.toString()); ???????? }? catch ?(ClientProtocolException e) { ???????????? e.printStackTrace(); ???????? }? catch ?(IOException e) { ???????????? e.printStackTrace(); ???????? } ??????????????????????????????????????????????? ????? } } |
?
3.使用post的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | package ?com.example.l0903_http_post; import ?java.io.BufferedReader; import ?java.io.IOException; import ?java.io.InputStream; import ?java.io.InputStreamReader; import ?java.io.UnsupportedEncodingException; import ?java.util.ArrayList; import ?java.util.List; import ?org.apache.http.HttpEntity; import ?org.apache.http.HttpResponse; 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.HttpPost; import ?org.apache.http.impl.client.DefaultHttpClient; import ?org.apache.http.message.BasicNameValuePair; import ?android.app.Activity; import ?android.os.Bundle; public ?class ?MainActivity? extends ?Activity { ???? //創建請求對象 ???? private ?HttpPost post; ???? //創建客戶端對象 ???? private ?HttpClient cliet; ???? //創建發送請求的對象 ???? private ?HttpResponse response; ???? // ???? private ?UrlEncodedFormEntity urlEntity; ???? //創建接收返回數據的對象 ???? private ?HttpEntity entity; ???? //創建流對象 ???? private ?InputStream is; ???? @Override ???? protected ?void ?onCreate(Bundle savedInstanceState) { ???????? super .onCreate(savedInstanceState); ???????? setContentView(R.layout.activity_main); ???????? //包裝請求的地址 ???????? post= new ?HttpPost( "http://10.0.2.2:8080/My_Service/webdate.jsp" ); ???????? //創建默認的客戶端對象 ???????? cliet= new ?DefaultHttpClient(); ???????? //用list封裝要向服務器端發送的參數 ???????? List<BasicNameValuePair> pairs= new ?ArrayList<BasicNameValuePair>(); ???????? pairs.add( new ?BasicNameValuePair( "name" ,? "llllllllll" )); ???????? try ?{ ???????????? //用UrlEncodedFormEntity來封裝List對象 ???????????? urlEntity= new ?UrlEncodedFormEntity(pairs); ???????????? //設置使用的Entity ???????????? post.setEntity(urlEntity); ???????????? try ?{ ???????????????? //客戶端開始向指定的網址發送請求 ???????????????? response=cliet.execute(post); ???????????????? //獲得請求的Entity ???????????????? entity=response.getEntity(); ???????????????? is=entity.getContent(); ???????????????? //下面是讀取數據的過程 ???????????????? BufferedReader br= new ?BufferedReader( new ?InputStreamReader(is)); ???????????????? String line= null ; ???????????????? StringBuffer sb= new ?StringBuffer(); ???????????????? while ((line=br.readLine())!= null ){ ???????????????????? sb.append(line); ???????????????? } ???????????????? System.out.println(sb.toString()); ???????????? }? catch ?(ClientProtocolException e) { ???????????????? e.printStackTrace(); ???????????? }? catch ?(IOException e) { ???????????????? e.printStackTrace(); ???????????? } ???????? }? catch ?(UnsupportedEncodingException e) { ???????????? e.printStackTrace(); ???????? } ???????????????????????????????????????????? ????????????????????????????????????????????? ????? } } |
?
4.實現HttpClient通信與AsyncTask異步機制的結合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | package ?com.example.l0903_http_asynctask_get; import ?java.io.BufferedReader; import ?java.io.IOException; import ?java.io.InputStream; import ?java.io.InputStreamReader; import ?org.apache.http.HttpEntity; import ?org.apache.http.HttpResponse; import ?org.apache.http.client.ClientProtocolException; import ?org.apache.http.client.HttpClient; import ?org.apache.http.client.methods.HttpGet; import ?org.apache.http.impl.client.DefaultHttpClient; import ?android.app.Activity; import ?android.app.ProgressDialog; import ?android.os.AsyncTask; import ?android.os.Bundle; import ?android.widget.TextView; /** ? * ? * @author asus ? * ? */ public ?class ?MainActivity? extends ?Activity { ???? private ?TextView tv; // 創建請求對象 ???? private ?HttpGet httpGet; ???? // 創建客戶端對象 ???? private ?HttpClient httpClient; ???? // 發送請求的對象 ???? private ?HttpResponse httpResponse; ???? // 接收返回數據 ???? private ?HttpEntity httpEntity; ???? // 創建流 ???? private ?InputStream in; ???? private ?ProgressDialog pd; ???? @Override ???? protected ?void ?onCreate(Bundle savedInstanceState) { ???????? super .onCreate(savedInstanceState); ???????? setContentView(R.layout.activity_main); ???????? tv = (TextView) findViewById(R.id.tv); ???????? AsyncTask<String, Void, String> asyncTask =? new ?AsyncTask<String, Void, String>() { ???????????? @Override ???????????? protected ?String doInString...? params) { ???????????????? String urlstr = params[ 0 ]; ???????????????? httpGet =? new ?HttpGet(urlstr); ???????????????? httpClient =? new ?DefaultHttpClient(); ???????????????? try ?{ ???????????????????? // 向服務器端發送請求 ???????????????????? httpResponse = httpClient.execute(httpGet); ???????????????????? httpEntity = httpResponse.getEntity(); ???????????????????? in = httpEntity.getContent(); ???????????????????? BufferedReader br =? new ?BufferedReader( ???????????????????????????? new ?InputStreamReader(in)); ???????????????????? String line =? null ; ???????????????????? StringBuffer sb =? new ?StringBuffer(); ???????????????????? while ?((line = br.readLine()) !=? null ) { ???????????????????????? sb.append(line); ???????????????????? } ???????????????????? System.out.println(sb.toString()); ???????????????????? return ?sb.toString(); ???????????????? }? catch ?(ClientProtocolException e) { ???????????????????? e.printStackTrace(); ???????????????? }? catch ?(IOException e) { ???????????????????? e.printStackTrace(); ???????????????? } ???????????????? return ?null ; ???????????? } ???????????? @Override ???????????? protected ?void ?onPostExecute(String result) { ???????????????? if ?(result !=? null ) { ???????????????????? tv.setText(result); ???????????????????? pd.dismiss(); // 消除dialog ???????????????? } ???????????????? super .onPostExecute(result); ???????????? } ???????? }; ???????? pd = ProgressDialog.show( this ,? "請稍后。。。" ,? "正在請求數據" ); ???????? asyncTask.execute( "http://10.0.2.2:8080/My_Service/webdate.jsp?name=haha&age=hh" ); ???? } } |
運行效果:
?