<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
使用網路進行資料通訊前,需要先獲取網路狀態。
使用ConnectivityManager獲取網路狀態步驟:
1.獲取ConnectivityManager物件
2.獲取當前活動的網路NetworkInfo物件
3.判斷當前網路狀態是否為連線狀態
4.在AndroidMainfest.xml中新增存取當前網路狀態許可權
//使用ConnectivityManager檢查網路狀態步驟 private boolean checkNetworkState() { ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(CONNECTIVITY_SERVICE);//1.通過系統服務獲取ConnectivityManager類的物件 NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();//2.呼叫getActiveNetworkInfo()獲取當前活動的網路NetworkInfo物件 if (networkInfo==null || networkInfo.isConnected()==false) {//3.判斷當前網路狀態是否為連線狀態,如果當前沒有網路是活動的,則返回null return false; }else { return true; } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.httpurlexestud"> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><!--檢查網路狀態步驟4.新增存取當前網路狀態許可權--> <uses-permission android:name="android.permission.INTERNET"/><!--增加存取網路授權宣告--> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".WelcomeActivity"></activity> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
1.HTTP(Hyper Text Transfer Protocol) 即超文字傳輸協定,是一種詳細規定了使用者端和全球資訊網(www,World Wide Web)伺服器之間互相通訊的規則,通過因特網傳送全球資訊網檔案的資料傳送協定。
2.HTTP協定是一種請求/響應式的協定。當用戶端與伺服器端建立連線後,向伺服器端傳送的請求,稱作HTTP請求;當伺服器端接收到請求後會做出響應,稱為HTTP響應。
HttpURLConnection類位於java.net內,提供了基於HTTP的網路存取方法。
使用HttpURLConnection存取HTTP資源的主要操作步驟:
1.利用URL地址範例化URL類
2.由URL類建立HttpURLConnection物件
3.以GET/POST方式向伺服器傳送請求
4.接收伺服器響應
5.關閉連線
HTTP協定使用注意事項:
1.使用“ .setRequestMethod(" "); ”設定請求方式
2.使用“ .connect(); ”連線網路。請求行、請求頭的設定必須放在網路連線前
3.“ .getInputStream() ”只是得到一個流物件,並不是資料。我們需要從流中讀取資料,從流中讀取資料的操作必須放在子執行緒
4.“ .getInputStream() ”得到一個流物件,從這個流物件中只能讀取一次資料,第二次讀取時將會得到空資料
1.GET方式是以實體的方式得到由請求URL所指向的資源資訊,它向伺服器提交的引數跟在請求URL後面。使用GET方式存取網路URL的長度一般要小於1K
2.POST方式向伺服器傳送請求時需要在請求後附加實體,它向伺服器提交的引數在請求後的實體中。POST方式對URL的長度沒有限制
3.採用POST方式提交資料時,使用者在瀏覽器中看不到向伺服器提交的請求引數,因此POST方式要比GET方式相對安全。
4.GET重點在從伺服器上獲取資源,POST重點在向伺服器傳送資料。
5.GET傳輸的資料量小,因為受URL長度限制,但效率較高;POST沒有此限制,可以傳輸大量資料,所以上傳檔案時只能用POST方式。
6.GET方式只能支援ASCII字元,向伺服器傳的中文字元可能會亂碼;POST支援標準字元集,可以正確傳遞中文字元。
注意事項:
1.所有內容都需要存取網路才能進行傳送或者獲取,因此需要組態檔AndroidMainfest.xml檔案中新增存取網路的許可權(第一部分裡已給出程式碼)。
2.實際開發中,手機端與伺服器端進行互動的過程中,避免不了要提交中文到伺服器,這時就會出現中文亂碼的情況。因此,無論是GET方式還是POST方式提交引數時都要對引數進行編碼。需要注意的是,編碼方式必須與伺服器解碼方式一致。同樣,在獲取伺服器返回的中文字元時,也需要用指定格式進行解碼。
(1)以GET方式提交資料
/*一、GET方式步驟: 1.把使用者名稱和密碼拼接成以get方式向伺服器傳送請求的URL字串 2.使用url的openConnection()方法獲得HttpURLConnection物件 3.設定HttpURLConnection物件的請求方式、超時等,並呼叫connect()建立連線 4.得到響應碼並判斷連線正常後,通過getInputStream()方法獲得攜帶伺服器返回資訊的輸入流,從流中讀取出伺服器返回值,並向handler傳送訊息 5.斷開連線*/ String urlStr = "http://192.192.192.192:8080/TestServer/servlet/Login?name="+ URLEncoder.encode(name)+ "&pass="+URLEncoder.encode(pwd);//將使用者名稱和密碼拼在指定資源路徑後面,並對使用者名稱和密碼進行編碼 try {//使用try-catch-finally捕獲異常 url = new URL(urlStr);//在URL的構造方法中傳入要存取資源的路徑 uc = (HttpURLConnection) url.openConnection();//返回一個HttpURLConnection物件 uc.setRequestMethod("GET");//設定GET請求方式 uc.setConnectTimeout(5000);//設定超時時間 uc.connect();//連線 int code = uc.getResponseCode();//得到響應碼(獲取HTTP狀態碼) if (code == HttpURLConnection.HTTP_OK) {//4.得到響應碼並判斷連線正常後,通過getInputStream()方法獲得攜帶伺服器返回資訊的輸入流,從流中讀取出伺服器返回值,並向handler傳送訊息 System.out.println(uc.getResponseCode());//控制檯輸出 InputStream inputStream = uc.getInputStream();//得到響應流(通過getInputStream()方法獲取攜帶伺服器返回資訊的輸入流) int i = inputStream.read(); System.out.println(i);//控制檯顯示是0還是1,以ASCII碼形式顯示 //通過Message和handler.sendMessage()將返回結果傳遞給UI執行緒 Message message = Message.obtain();//從伺服器返回的資料,1.獲取可用的Message物件 message.arg1 =i;//2.通過message的arg1傳遞引數 handler.sendMessage(message);//傳送至主介面顯示 }else { System.out.println(uc.getResponseCode());//控制檯輸出 Message message = Message.obtain(); message.arg1 =2; handler.sendMessage(message); } }catch (Exception e) { e.printStackTrace(); }finally { if (uc != null) { uc.disconnect();//關閉HTTP連線 } }
(2)以POST方式提交資料
/*二、POST方式步驟: 1.通過URL字串建立URL物件 2.使用url的openConnection()方法獲得HttpURLConnection物件 3.設定HttpURLConnection物件的請求方式、超時、請求頭資料提交方式等,並呼叫connect()建立連線 4.通過getOutputStream()獲得輸出流往伺服器寫資料 5.得到響應碼並判斷連線正常後,通過getInputStream()方法獲得攜帶伺服器返回資訊的輸入流,從流中讀取出伺服器返回值,並向handler傳送訊息 6.斷開連線*/ String urlStr = "http://192.192.192.192:8080/TestServer/servlet/Login"; try {//使用try-catch-finally捕獲異常 url = new URL(urlStr);//在URL的構造方法中傳入要存取資源的路徑 uc = (HttpURLConnection) url.openConnection();//返回一個HttpURLConnection物件 uc.setRequestMethod("POST");//設定POST請求方式 uc.setConnectTimeout(5000);//設定超時時間 String data = "name="+ URLEncoder.encode(name) + "&pass="+URLEncoder.encode(pwd); uc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");//設定請求頭資料提交方式,這裡以form表單形式提交 uc.setRequestProperty("Content-Length", data.length()+"");//設定請求頭,設定提交資料的長度 //POST方式,實際是瀏覽器把資料寫給了伺服器 uc.setDoOutput(true);//設定允許向外寫資料 uc.connect();//連線 //4.通過getOutputStream()獲得輸出流往伺服器寫資料 OutputStream outputStream = uc.getOutputStream();//通過getOutputStream()獲得輸出流 outputStream.write(data.getBytes()); int code = uc.getResponseCode();//獲取HTTP狀態碼 if (code == HttpURLConnection.HTTP_OK) {//5.得到響應碼並判斷連線正常後,通過getInputStream()方法獲得攜帶伺服器返回資訊的輸入流,從流中讀取出伺服器返回值,並向handler傳送訊息 System.out.println(uc.getResponseCode());//控制檯輸出 InputStream inputStream = uc.getInputStream();//得到響應流(通過getInputStream()方法獲取攜帶伺服器返回資訊的輸入流) int i = inputStream.read(); System.out.println(i);//控制檯顯示是0還是1,以ASCII碼形式顯示 //通過Message和handler.sendMessage()將返回結果傳遞給UI執行緒 Message message = Message.obtain();//從伺服器返回的資料,1.獲取可用的Message物件 message.arg1 =i;//2.通過message的arg1傳遞引數 handler.sendMessage(message);//傳送至主介面顯示 }else { System.out.println(uc.getResponseCode());//控制檯輸出 Message message = Message.obtain();//從伺服器返回的資料,1.獲取可用的Message物件 message.arg1 =2;//2.通過message的arg1傳遞引數 handler.sendMessage(message);//傳送至主介面顯示 } }catch (Exception e) { e.printStackTrace(); }finally { if (uc != null) { uc.disconnect();//關閉HTTP連線 } }
(一)實驗效果如圖所示
(二)實驗步驟
MainActivity.java檔案
1.在MainActivity.java中使用ConnectivityManager獲取網路狀態,完成網路狀態判斷方法checkNetworkState()的實現,具體步驟和程式碼在第一部分中已經給出
2.在 “登入”按鈕的事件監聽方法btnLogin.setOnClickListener()中,新建執行緒並使用HttpURLConnection存取伺服器進行使用者名稱和密碼的驗證,並將結果傳送給Handler物件
重寫run()方法中採用GET或POST方法提交資料,程式碼在第四部分已經給出
btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final String name=edName.getText().toString(); final String pwd=edPwd.getText().toString(); if(checkNetworkState()!=true){//判斷是否聯網 Toast.makeText(MainActivity.this,"網路沒有開啟,請開啟網路後再試。",Toast.LENGTH_LONG).show(); }else { if (name.equals("")) { Toast toast = Toast.makeText(MainActivity.this, "輸入使用者名稱", Toast.LENGTH_LONG); toast.show(); }else if (pwd.equals("")) { Toast toast = Toast.makeText(MainActivity.this, "輸入密碼", Toast.LENGTH_LONG); toast.show(); }else { //新建執行緒,並通過GET或post方式把使用者名稱和密碼向伺服器傳送請求並將結果傳送給Handler物件 new Thread(new Runnable() { @Override public void run() {//重寫run()方法 } }).start(); } } } });
3.在onCreate()方法外部,實現Handler的handleMessage()方法,根據伺服器返回結果判斷是否登入成功
final Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { //通過msg中傳遞資料判斷是否登入成功,若成功則實現介面跳轉到WelcomeActivity int i = msg.arg1; if (i==49) {//介面跳轉 Intent intent = new Intent(MainActivity.this, WelcomeActivity.class); startActivity(intent); }else if (i==48) {//Toast提示使用者名稱或密碼錯誤 Toast.makeText(MainActivity.this, "使用者名稱或密碼錯誤!", Toast.LENGTH_LONG).show(); }else {//Toast提示連線失敗 Toast.makeText(MainActivity.this, "網路連線失敗!", Toast.LENGTH_LONG).show(); } } };
WelcomeActivity.java檔案
4.完成DownloadTask類中各個方法的實現。doInBackground()方法中使用HttpURLConnection存取伺服器並下載圖片,下載過程中實時釋出下載進度,下載完成後返回Bitmap物件
class DownloadTask extends AsyncTask<String, Integer, Bitmap> {//分別代表:執行後臺任務傳遞的引數、更新的進度值的型別(都是整形) 、返回結果型別 @Override protected void onPreExecute() {//UI元件初始化設定 super.onPreExecute(); textView.setVisibility(View.VISIBLE); progressBar.setVisibility(View.VISIBLE); progressBar.setProgress(0);//設定進度條初始值為0 } @Override protected Bitmap doInBackground(String... strings) { URL url; HttpURLConnection urlConnection = null; Bitmap bitmap = null; pbValue=0;//初始值為0 try { /*url = new URL(strings[0]);//在URL構造方法中傳入要存取資源的路徑*/ url = new URL(urlStr); urlConnection = (HttpURLConnection) url.openConnection();//根據url傳送一個http的請求 urlConnection.setRequestMethod("GET");//設定GET請求方式 urlConnection.setConnectTimeout(5000);//設定超時時間 urlConnection.connect();//連線 if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK /*urlConnection.getResponseCode() == 200*/ ) {//得到響應碼,判斷連線是否正常 System.out.println(urlConnection.getResponseCode());//控制檯輸出 InputStream inputStream = urlConnection.getInputStream();//通過getInputStream()方法獲得攜帶伺服器返回資訊的輸入流 System.out.println(inputStream);//控制檯顯示是0還是1,以ASCII碼形式顯示 int maxSize = urlConnection.getContentLength();//通過urlConnection的getContentLength()獲取下載圖片的總大小 byte[] buffer = new byte[1024*8]; int len = -1; int process =0; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); while((len = inputStream.read(buffer)) != -1) {//通過inputStream.read(buffer)和while迴圈讀取資料,並通過ByteArrayOutputStream將資料寫入 process += len; byteArrayOutputStream.write(buffer, 0, len); Thread.sleep(50);//每隔50ms通過publishProgress()釋出進度值 pbValue = (int) ((((double)process)/maxSize)*progressBar.getMax());//計算資料下載的完成百分比 publishProgress(pbValue);//釋出進度 } /*byteArrayOutputStream.flush();*/ //資料讀取完成後通過BitmapFactory.decodeByteArray()將ByteArrayOutputStream物件out中資料轉換成Bitmap物件並返回 byte[] result = byteArrayOutputStream.toByteArray(); bitmap = BitmapFactory.decodeByteArray(result, 0, maxSize); /*bitmap = BitmapFactory.decodeByteArray(byteArrayOutputStream.toByteArray(), 0, maxSize);*/ } }catch (Exception e) { e.printStackTrace(); }finally { if (urlConnection != null) { urlConnection.disconnect();//關閉HTTP連線 } return bitmap; } } @Override protected void onProgressUpdate(Integer... values) {//下載過程中更新TextView和進度條的進度值 super.onProgressUpdate(values); textView.setText("已下載"+ values[0]+"%"); progressBar.setProgress(values[0]); } @Override protected void onPostExecute(Bitmap bitmap) {//下載完成後更新TextView和進度條 super.onPostExecute(bitmap); Toast.makeText(WelcomeActivity.this, "載入完畢", Toast.LENGTH_SHORT).show(); textView.setText("恭喜!下載完成!"); progressBar.setVisibility(View.INVISIBLE);//下載完成後進度條消失 imageView.setImageBitmap(bitmap); } }
5.在“下載圖片”按鈕的事件監聽方法btnGetPic.setOnClickListener ()中,新建DownloadTask類的非同步任務並呼叫execute(urlStr)方法執行網路圖片的下載任務
btnGetPic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new DownloadTask().execute(urlStr);//建立DownloadTask範例物件,並呼叫其execute()方法 } });
完整程式碼請從這裡下載
注意事項:
1.我上傳的壓縮包中包含兩個檔案,TestServer要匯入myeclipse中,HttpUrlExeStud匯入Android Studio中
2.TestServer下存在一個Login檔案,其中
if(name!=null && pass!=null && name.equals("JMX") && pass.equals("666"))
包含了我的使用者名稱和密碼,你可以進行更換,建議使用者名稱設定為英文
3.TestServer必須執行起來,右擊TestServer專案,點選Run As – 3 MyEclipse Server Application,彈出如下介面則表示成功
4.HttpUrlExeStud下MainActivity.java的GET、POST方法和WelcomeActivity.java分別包含這幾行程式碼
String urlStr = "http://192.192.192.192:8080/TestServer/servlet/Login?name="+URLEncoder.encode(name)+"&pass="+URLEncoder.encode(pwd);
String urlStr = "http://192.192.192.192:8080/TestServer/servlet/Login";
final String urlStr="http://192.192.192.192:8080/TestServer/pic/bamboo1.jpg";
其中192.192.192.192是我的ip地址,實際執行時需要替換成你自己的ip地址。可以通過win+R,鍵入cmd,輸入ipconfig的方式獲取到計算機ip資訊
到此這篇關於Android使用HttpURLConnection實現網路存取流程的文章就介紹到這了,更多相關Android HttpURLConnection內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45