版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
武漢大學谷歌聯(lián)合實驗室Android-網絡編程主要內容1、網絡編程概述2、Android對網絡通信的支持3、HTTP通信4、Socket通信1、網絡編程概述—網絡通信協(xié)議及接口網絡通信協(xié)議就是對計算機之間通信的信息格式、能被收/發(fā)雙方接受的傳送信息內容的一組定義。即連接不同操作系統(tǒng)和不同硬件體系結構的互聯(lián)網絡提供通信支持,是一種網絡通用語言。網絡通信接口為了使兩個結點能進行對話,必須在它們之間建立通信工具(即接口),使彼此之間能進行信息交換。接口包括兩部分:硬件裝置:實現(xiàn)結點之間的信息傳送軟件裝置:規(guī)定雙方進行通信的約定協(xié)議通信協(xié)議的分層思想為什么要分層由于結點之間聯(lián)系復雜,在制定協(xié)議時,把復雜成份分解成一些簡單的成份,再將它們復合起來。最常用的復合方式是層次方式,即同層間可以通信,上一層可以調用下一層,而與再下一層沒有關系。各層互不影響,利于系統(tǒng)的開發(fā)和擴展。通信協(xié)議的分層規(guī)定把用戶應用程序作為最高層,把物理通信線路作為最底層,將期間的協(xié)議處理分為若干層,規(guī)定每層處理的任務,也規(guī)定每層的接口標準。參考模型數(shù)據封裝數(shù)據拆封IP協(xié)議IP協(xié)議就是為計算機網絡相互連接進行通信而設計的協(xié)議。在因特網中,它是能使連接到網上的所有計算機網絡實現(xiàn)相互通信的一套規(guī)則,規(guī)定了計算機在因特網上進行通信時應當遵守的規(guī)則。任何廠家生產的計算機系統(tǒng),只要遵守IP協(xié)議就可以與因特網互連互通。TCP協(xié)議和UDP協(xié)議TCP協(xié)議
TCP是專門設計用于在不可靠的因特網上提供可靠的、端到端的字節(jié)流通信的協(xié)議。它是一種面向連接的協(xié)議,TCP連接的是字節(jié)流而非報文流。UDP協(xié)議:
UDP向應用程序提供了一種發(fā)送封裝的原始IP數(shù)據報的方法,并且發(fā)送時無需建立連接。是一種不可靠的連接。TCP/UDP區(qū)別編程時區(qū)別:利用TCP協(xié)議進行通信的兩個應用程序是有主次之分,一個稱為服務器程序,另外一個稱為為客戶機程序,兩者功能和編寫方法大不一樣。利用UDP通信的兩個程序是平等的,沒有主次之分,2個程序代碼可以是完全一樣的??蛻舳?服務器模式又稱為智能服務器/智能客戶端體系結構服務器和客戶端共同承擔計算客戶端向另一臺計算機請求服務的計算機服務器處理客戶端請求的計算機優(yōu)點服務器和客戶端分攤工作服務器可以同時為數(shù)千臺客戶端服務多個客戶端可以同時訪問服務器2、Android對網絡通信的支持Android平臺為網絡通信提供了豐富的API,有3種網絡接口。分別是:.*(標準JAVA接口)提供與聯(lián)網有關的類,包括流和數(shù)據包套接字、Internet協(xié)議,常見HTTP處理。例如:URL以及URLConnection/HttpURLConnection對象、設置連接參數(shù)、連接到服務器、向服務器寫數(shù)據、從服務器讀取數(shù)據等通信。org.apache(Apache接口)JDK的已經提供了訪問HTTP協(xié)議的基本功能,但遠遠不夠。開源項目HttpClient。主要包括創(chuàng)建HttpClient以及Get/Post、HttpRequest等對象,設置連接參數(shù),執(zhí)行HTTP操作,處理服務器返回結果等功能。.*(Android網絡接口)通過對Apache中HttpClient的封裝來實現(xiàn)的一個HTTP編程接口。同時還提供了HTTP請求隊列管理以及HTTP連接池管理等等。2、Android對網絡通信的支持Android平臺將Apache旗下的Http通信相關的org.apache.http包也納入到系統(tǒng)來。2).ssl包中主要類/接口說明1)包中主要類/接口說明類/接口功能說明ServerSocket表示用于等待客戶端連接的服務方的套接字Socket提供一個客戶端的TCP套接字DatagramSocket實現(xiàn)一個用于發(fā)送和接收數(shù)據報的UDP套接字數(shù)據包IntetAddress表示IP地址UnkownHostException位置主機異常HttpURLConnection用于管理Http鏈接(RFC2068)的資源連接管理器URL用于指定互聯(lián)網上1個資源的位置信息(RFC1783)類/接口功能說明HttpsURLConnection用于管理Https連接(RFC2818)的資源連接管理器SSLSocket提供安全協(xié)議的套接字SSLServerSocket基于SSL、TLS等協(xié)議的安全服務套接字SSLContextSSL上下文環(huán)境APITrustManagerFactory信任管理器KeyManagerFactory密鑰管理器2、Android對網絡通信的支持關于這方面更多地內容:參考Android的SDKorg.apacke.http.impl.client包主要類/接口說明類/接口功能說明DefaultHttpClient表示一個Http客戶端默認實現(xiàn)接口org.apacke.http.client.methods包中主要類/接口說明類/接口功能說明HttpGet/HttpPost/HttpPut/HttpHead表示Http的各種方法org.apacke.http包中主要類/接口說明HttpResponse一個Http響應StatusLine狀態(tài)行Header表示Http頭部字段HeaderElementHttp頭部值中的一個元素NameValuesPair封裝了屬性:值對的類HttpEntity一個可以同Http消息進行接收或發(fā)送的實體3)其他包中主要類/接口說明3、HTTP通信對于大部分應用程序而言JDK本身提供的網絡功能已遠遠不夠,這時就需要Android提供的ApacheHttpClient了。它是一個開源項目,功能更加完善,為客戶端的Http編程提供高效、最新、功能豐富的工具包支持。通過Apache提供的http包工具進行Http通信,兩種形式:GET和POST。Get和POST請求主要有幾種區(qū)別:1、Post請求可以向服務器傳送數(shù)據,而且數(shù)據放在HTMLHEADER內一起傳送到服務端URL地址,數(shù)據對用戶丌可見。而get是把參數(shù)數(shù)據隊列加到提交的URL中,值和表單內各個字段一一對應。2、get傳送的數(shù)據量較小,丌能大于2KB。post傳送的數(shù)據量較大,一般被默認為丌受限制。3、get安全性非常低,post安全性較高。1、首先加入權限:<uses-permissionandroid:name="android.permission.INTERNET"/>2、新建HttpClient對象,并做超時時間設置:HttpClienthttpClient=newDefaultHttpClient();//新建HttpClient對象HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),3000);//設置連接超時HttpConnectionParams.setSoTimeout(httpClient.getParams(),3000);//設置數(shù)據讀取時間超時ConnManagerParams.setTimeout(httpClient.getParams(),3000);//設置從連接池中取連接超時3、使用Get請求,并獲取HttpResponse響應:HttpGethttpget=newHttpGet(url);//獲取請求HttpResponseresponse=httpClient.execute(httpget);//執(zhí)行請求,獲取響應結果if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){//響應通過Stringresult=EntityUtils.toString(response.getEntity(),"UTF-8");}//注意做異常處理3、HTTP通信4、使用Post請求,并獲取HttpResponse響應:HttpClienthttpClient=newDefaultHttpClient();//新建HttpClient對象HttpPosthttpPost=newHttpPost(url);//新建HttpPost對象List<NameValuePair>params=newArrayList<NameValuePair>();//使用NameValuePair來保存要傳遞的Post參數(shù)params.add(newBasicNameValuePair("username","hello"));//添加要傳遞的參數(shù)params.add(newBasicNameValuePair("password","eoe"));try{HttpEntityentity=newUrlEncodedFormEntity(params,HTTP.UTF_8);//設置字符集httpPost.setEntity(entity);//設置參數(shù)實體HttpResponsehttpResp=httpClient.execute(httpPost);//獲取HttpResponse實例if(httpResp.getStatusLine().getStatusCode()==HttpStatus.SC_OK){//響應通過Stringresult=EntityUtils.toString(httpResp.getEntity(),"UTF-8");}else{ //響應未通過}}catch{}3、HTTP通信然后介紹使用標準java接口進行Http通信,分成兩種形式:GET和POST。1、其默認使用get請求:URLpathUrl=newURL(url); //創(chuàng)建一個URL對象HttpURLConnectionurlConnect=(HttpURLConnection)pathUrl.openConnection(); //打開一個HttpURLConnection連接urlConnect.setConnectTimeout(3000); //設置連接超時時間urlConnect.connect();InputStreamReaderin=newInputStreamReader(urlConnect.getInputStream()); //得到讀取的內容BufferedReaderbuffer=newBufferedReader(in); //為輸出創(chuàng)建BufferedReaderStringinputLine=null;while(((inputLine=buffer.readLine())!=null)){ //利用循環(huán)來讀取數(shù)據}3、HTTP通信2、使用post請求:Stringparams="username="+URLEncoder.encode("hello","UTF-8")+"&password="+URLEncoder.encode("eoe","UTF-8");byte[]postData=params.getBytes();URLpathUrl=newURL(url);//創(chuàng)建一個URL對象HttpURLConnectionurlConnect=(HttpURLConnection)pathUrl.openConnection();urlConnect.setConnectTimeout(3000);//設置連接超時時間urlConnect.setDoOutput(true);//post請求必須設置允許輸出urlConnect.setUseCaches(false);//post請求丌能使用緩存urlConnect.setRequestMethod("POST");//設置post方式請求urlConnect.setInstanceFollowRedirects(true);urlConnect.setRequestProperty("Content-Type","application/x-www-form-urlencode");//配置請求Content-TypeurlConnect.connect();//開始連接DataOutputStreamdos=newDataOutputStream(urlConnect.getOutputStream());//發(fā)送請求參數(shù)dos.write(postData);dos.flush();dos.close();if(urlConnect.getResponseCode()==200){//請求成功byte[]data=readInputStream(urlConnect.getInputStream());}3、HTTP通信4、Socket通信—什么是Socket
它實際上是網絡通信的一種接口,基于不同的協(xié)議,有各種不同的Socket,比如有基于TCP協(xié)議的Socket和基于UDP協(xié)議的Socket以及基于藍牙協(xié)議的Socket,Android中使用的是Java的Socket模型。Socket在計算機行業(yè)通常稱為”套接字“,用于描述IP地址和端口,是一個通信鏈的句柄。這是一個比較抽象的概念。計算機是擁有端口的,每一個端口都可以有一個應用程序來進行通訊的使用,比如:80端口是HTTP協(xié)議所使用的端口,21端口是FTP協(xié)議所使用的端口,端口是計算機和外界通訊的接口,這些接口都是邏輯的接口,端口號取值的范圍是零到256乘以256減1,1024以下的端口都是操作系統(tǒng)使用的保留端口,以上的端口我們可以自由的來使用,不要和其他應用程序的端口沖突。應用程序可以通過“套接字”向網絡發(fā)送請求或者應答網絡的請求,這時候就把Socket分成了兩部分,一部分是服務器端的Socket,這個Socket主要用來接收來自網絡的請求,它一直監(jiān)聽在某一個端口上。一部分是客戶端的Socket,這個Socket主要用來向網絡發(fā)送數(shù)據。Socket通訊模型UDP協(xié)議和TCP協(xié)議UDP協(xié)議和TCP協(xié)議是互聯(lián)網使用最廣的兩種協(xié)議,都是基于IP的協(xié)議。第一個區(qū)別是UDP協(xié)議是一個不太靠譜的協(xié)議,UDP協(xié)議把數(shù)據都打成數(shù)據包,數(shù)據包上自帶通訊地址,也就是說我要把這個數(shù)據包發(fā)送到網絡上的哪一個地址,通過網絡把這個數(shù)據包發(fā)送出去,至于這個數(shù)據包是否發(fā)送到目的地,是否服務器端接收到了這個數(shù)據包,這個協(xié)議并不保證,就像中國的郵政,你是把信寄出去了,但是郵政系統(tǒng)不保證對方能收到你寄送的信。TCP發(fā)送數(shù)據的時候要求接收方接收到數(shù)據之后給一個回應,也就是你是否收到了,TCP可靠一些,當我們發(fā)送一些比較重要的數(shù)據的時候一般都使用TCP協(xié)議。另外一個區(qū)別是UDP協(xié)議發(fā)送的一個數(shù)據包它的容量是有限的,而TCP協(xié)議則沒有這樣一個限制。并不是說UDP協(xié)議一定就不如TCP協(xié)議,在不同的領域有不同的使用,UDP協(xié)議好處是速度相對快些。TCP協(xié)議相對慢些。Socket通訊流程創(chuàng)建服務端的步驟如下:1、指定端口實例化一個ServerSocket;2、調用ServerSocket的accept方法以在等待連接期間造成阻塞;3、獲取位于底層的Socket流以進行讀寫操作;4、將數(shù)據封裝成流;5、對Socket進行讀寫;6、關閉打開的流。創(chuàng)建客戶端的步驟如下:1、通過IP地址和端口實例化Socket,請求連接服務器;2、獲取Socket上的流以進行讀寫;3、把流包裝進輸入/輸出(比如:BufferedReader/PrintWriter戒者DataOutputStream/DataInputStream等)的實例;4、對Socket進行讀寫;5、關閉打開的流。Socket與ServerSocketSocket是TCP/IP協(xié)議上的一種通信,在通信的兩端各建立一個Socket,從而在通信的兩端之間形成網絡虛擬鏈路。一旦建立了虛擬的網絡鏈路,兩端的程序就可以通過虛擬鏈路進行通信。ClientA
發(fā)信息給ClientB,
A的信息首先發(fā)送信息到服務器Server,Server接受到信息后再把A的信息廣播發(fā)送給所有的Clients.首先要在服務器建立一個ServerSocket,ServerSocket對象用于監(jiān)聽來自客戶端的Socket連接,如果沒有連接,它將一直處于等待狀態(tài)。Socketaccept():如果接收到一個客戶端Socket的連接請求,該方法將返回一個與客戶端Socket對應的SocketSocket與ServerSocketServer示例://創(chuàng)建一個ServerSocket,用于監(jiān)聽客戶端Socket的連接請求
ServerSocketss=newServerSocket(30000);//采用循環(huán)不斷接受來自客戶端的請求
while(true){//每當接受到客戶端Socket的請求,服務器端也對應產生一個SocketSockets=ss.accept();//下面就可以使用Socket進行通信了...}客戶端通??墒褂肧ocket的構造器來連接到指定服務器Client示例://創(chuàng)建連接到服務器、30000端口的SocketSockets=newSocket("14",30000);//下面就可以使用Socket進行通信了...這樣Server和Client就可以進行一個簡單的通信了Socket通信模型基于TCP協(xié)議的Socket使用ServerSocket創(chuàng)建TCP服務器端服務器端編程步驟:1、創(chuàng)建服務器端套接字并綁定到一個端口上(0-1023是系統(tǒng)預留的,最好大于1024)
2、套接字設置監(jiān)聽模式等待連接請求
3、接受連接請求后進行通信
4、返回,等待贏一個連接請求使用ServerSocket創(chuàng)建TCP服務器端ServerSocket類的對象用于監(jiān)聽來自客戶端的Socket連接,如果沒有連接,它將一直處于等待狀態(tài)。ServerSocket包含一個監(jiān)聽來自客戶端連接請求的方法。Socketaccept():如果接收到一個客戶端Socket的連接請求,該方法將返回一個與連接客戶端Socket對應的Socket,否則該方法將一直處于等待狀態(tài),線程也被阻塞。通常情況下,服務器不應該只接收一個客戶端請求,而應該不斷地接收來自客戶端的所有請求。當ServerSocket使用完畢后,應使用ServerSocket的close()方法來關閉該ServerSocket。使用ServerSocket創(chuàng)建TCP服務器端為了創(chuàng)建ServerSocket對象,ServerSocket類提供以下及格構造方法:ServerSocket(intport):用指定的端口port來創(chuàng)建一個ServerSocket,該端口應該是一個有效的端口整數(shù)值0~65535.使用該構造方法創(chuàng)建的ServerSocket沒有指定Ip地址,則該ServerSocket將會綁定到本機默認的Ip地址。通常端口號推薦使用1024以上的端口,以避免與其他應用程序的通用端口沖突。ServerSocket(int
port,int
backlog):增加一個用來改變連接隊列長度的參數(shù)。ServerSocket(int
port,int
backlog,InetAddressaddr):在機器存在多個Ip地址的情況下,允許通過addr這個參數(shù)來指定將ServerSocket綁定到指定的Ip地址。由于手機無線上網的Ip地址通常是由移動運營公司動態(tài)分配的,一般不會有自己固定的Ip地址,因此很少在手機上運行服務器端,服務器端通常運行在有固定Ip的服務器上。使用Socket進行通信客戶端編程步驟:
1、創(chuàng)建客戶端套接字(指定服務器端IP地址與端口號)
2、連接(Android創(chuàng)建Socket時會自動連接)
3、與服務器端進行通信
4、關閉套接字使用Socket進行通信Socket類常用的構造方法:用服務器端的IP地址對象和端口號建立SocketpublicSocket(InetAddress
address,int
port):用服務器端的機器名和端口號建立SocketpublicSocket(String
host,int
port)例如:
//創(chuàng)建連接到本機、端口為8899的SocketSockets=newSocket(“39”,8899);//下面就可以使用Socket進行通信了。。。。。。。。。。。。。。。說明:當程序執(zhí)行上面代碼時,該代碼將會連接到指定服務器,讓服務器的ServerSocket的accept()方法向下執(zhí)行,于是服務器端和客戶端就產生一對互相連接的Socket。使用Socket進行通信當客戶端、服務器端產生了對應的Socket之后,就通過Socket進行通信。Socket提供如下兩個方法來獲取輸入流和輸出流。取得Socket對象的輸入流publicInputStreamgetInputStream():返回該Socket對象對應的輸入流,讓程序通過該輸入流從Socket中取出數(shù)據。取得Socket對象的輸出流publicOutputStreamgetOutputStream():返回該Socket對象對應的輸出流,讓程序通過該輸出流向Socket中輸出數(shù)據。關閉socketpublicvoidclose()throwsIOException示例服務器端:public
classSimpleServer{public
static
voidmain(String[]args)throwsIOException{System.out.println("Howareyou...");//創(chuàng)建一個ServerSocket,用于監(jiān)聽客戶端Socket的連接請求ServerSocketss=newServerSocket(20000);//采用循環(huán)不斷接受來自客戶端的請求while(true){//每當接受到客戶端Socket的請求,服務器端也對應產生一個SocketSockets=ss.accept();OutputStreamos=s.getOutputStream();os.write("Howareyou!\n".getBytes("utf-8"));//關閉輸出流,關閉Socketos.close();s.close();}}}示例客戶端:public
classSimpleClientextendsActivity{EditTextshow;public
voidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);show=(EditText)findViewById(R.id.show);try{Socketsocket=newSocket("39",20000);//將Socket對應的輸入流包裝成BufferedReaderBufferedReaderbr=newBufferedReader(newInputStreamReader(socket.getInputStream()));Stringline=br.readLine();//進行普通IO操作show.setText("來自服務器的數(shù)據:"+line);br.close();socket.close();}catch(IOExceptione){e.printStackTrace();}}}布局main.xml:xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android=""android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><EditTextandroid:id="@+id/show"android:layout_width="fill_parent"android:layout_height="wrap_content"android:editable="false"android:cursorVisible="false"/></LinearLayout>示例說明:android:cursorVisible屬性的作用:設定光標為顯示/隱藏,默認顯示。運行效果圖:說明:該android應用需要訪問互聯(lián)網,因此還需要為該應用賦予訪問網絡的權限,即在項目清單文件中添加授權訪問互聯(lián)網的權限:<uses-permissionandroid:name="android.permission.INTERNET"/>示例多線程實際應用中的客戶端可能需要和服務器保持長時間通信,即服務器需要不斷地讀取客戶端數(shù)據,并想客戶端寫入數(shù)據,客戶端也需要不斷地讀取服務器數(shù)據,并向服務器寫入數(shù)據。使用傳統(tǒng)的BufferedReader的readLine方法讀取數(shù)據時,在該方法成功返回之前,線程被阻塞,程序無法繼續(xù)執(zhí)行?;谶@個原因,服務器應該為每個Socket單獨啟動一條線程,每條線程負責與一個客戶端進行通信。下面以一個簡單C/S聊天室為例,來實現(xiàn)多個客戶端通信。多線程服務器端實現(xiàn)服務器端提供兩個類,一個是創(chuàng)建ServerSocket監(jiān)聽的主類,一個是負責處理每個Socket通信的線程類。多線程服務器端主類因為服務器端應該包含多條線程,每個Socket對應一條線程,該線程負責讀取Socket對應輸入流的數(shù)據(即從客戶端發(fā)送過來的數(shù)據),并將讀到的數(shù)據向每個Socket輸出來發(fā)送一遍(即將一個客戶端發(fā)送的數(shù)據廣播給其它的客戶端),因此需要在服務器端使用List來保存所有的Socket。另外讓服務器端只負責接收客戶端Socket的連接請求,每當客戶端Socket連接到該ServerSocket之后,程序將對應的Socket加入到List集合中,并為該Socket啟動一條線程,該線程就負責處理該Socket的所有通信任務。(1)定義保存所有Socket的集合(2)創(chuàng)建ServerSocket監(jiān)聽(3)采用循環(huán)不斷接收來自客戶端的連接請求(4)將接收客戶端請求產生的Socket添加到集合中(5)客戶端連接后啟動一條線程為該客戶端服務多線程//定義保存所有Socket的ArrayListpublic
staticArrayList<Socket>socketList=newArrayList<Socket>();
public
static
voidmain(String[]args)throwsIOException{ServerSocketss=newServerSocket(30000);while(true){//此行代碼會阻塞,將一直等待別人的連接Sockets=ss.accept();socketList.add(s);//每當客戶端連接后啟動一條ServerThread線程為該客戶端服務newThread(newServerThread(s)).start();}}多線程服務器端線程類服務器端線程類不斷讀取客戶端的數(shù)據,在此聲明一個方法來讀取客戶端的數(shù)據,當服務器線程類讀取到客戶端的數(shù)據之后,程序遍歷Socket集合,并將該數(shù)據向集合中的每一個Socket發(fā)送一次。如果讀取數(shù)據過程中捕獲到IOException異常,則表明該Socket對應的客戶端Socket出現(xiàn)了問題,程序就將該Socket從集合中刪除。
多線程(1)定義當前線程所處理的Socket及Socket所對應的輸入流//定義當前線程所處理的SocketSockets=null;//該線程所處理的Socket所對應的輸入流BufferedReaderbr=null;(2)聲明構造器,并初始化該Socket對應的輸入流publicServerThread(Sockets)throwsIOException{this.s=s;//初始化該Socket對應的輸入流br=newBufferedReader(newInputStreamReader(s.getInputStream(),"utf-8"));}(4)定義讀取客戶端數(shù)據的方法(5)重寫run方法,將把從Socket中讀到的數(shù)據向集合中的每一個Socket轉發(fā)一遍多線程(3)定義讀取客戶端數(shù)據的方法privateStringreadFromClient(){try{returnbr.readLine();}catch(IOExceptione){////如果捕捉到異常,表明該Socket對應的客戶端已經關閉,刪除該Socket。MyServer.socketList.remove(s);}return
null;}(4)重寫run方法,將把從Socket中讀到的數(shù)據向集合中的每一個Socket轉發(fā)一遍public
voidrun(){Stringcontent=null;//采用循環(huán)不斷從Socket中讀取客戶端發(fā)送過來的數(shù)據while((content=readFromClient())!=null){//遍歷socketList中的每個Socket,并將讀到的內容向每個Socket發(fā)送一次for(Sockets:MyServer.socketList){OutputStreamos=s.getOutputStream();os.write((content+"\n").getBytes("utf-8"));}}}多線程客戶端實現(xiàn)
每個客戶端應該包含兩條線程:一條負責生存主界面,并響應用戶動作,并將用戶輸入的數(shù)據寫入Socket對應的輸出流中;另一條負責讀取Socket對應輸入流中的數(shù)據(從服務器發(fā)送過來的數(shù)據),并負責將這些數(shù)據在程序主界面上顯示處理。多線程布局main.xml<LinearLayoutandroid:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"><EditTextandroid:id="@+id/input"android:layout_width="240px"android:layout_height="wrap_content"/><Buttonandroid:id="@+id/send"android:layout_width="fill_parent"android:layout_height="wrap_content"android:paddingLeft="8px"android:text="發(fā)送"/></LinearLayout><EditTextandroid:id="@+id/show"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="top"android:editable="false"android:cursorVisible="false"/>多線程客戶端端主類
客戶端的Activity負責生成程序主界面,并為程序的按鈕單擊事件綁定監(jiān)聽器,當用戶單擊按鈕時向服務器發(fā)送信息。(1)聲明控件對象、輸出來對象和Handler對象EditTextinput,show;Buttonsend;OutputStreamos;Handlerhandler;多線程(2)獲取控件實例及聲明Socket對象
input=(EditText)findViewById(R.id.input);show=(EditText)findViewById(R.id.show);send=(Button)findViewById(R.id.send);Socketsocket;(3)Android不允許子線程訪問界面組件,定義一個handler來處理來自子線程的消息handler=newHandler(){public
voidhandleMessage(Messagemsg){//如果消息來自于子線程if(msg.what==0x123){//將讀取的內容追加顯示在文本框中show.append("\n"+msg.obj.toString());}}};多線程(4)建立Socket,與ServerSocket建立連接,并啟動客戶端線程不斷讀取來自服務器端的數(shù)據
s=newSocket("39",30000);//客戶端啟動ClientThread線程不斷讀取來自服務器的數(shù)據newThread(newClientThread(s,handler)).start();os=s.getOutputStream();(5)為發(fā)送按鈕添加事件,將用戶在文本框內輸入的內容寫入網絡,然后清空input文本框
send.setOnClickListener(newOnClickListener(){ publicvoidonClick(Viewv){//將用戶在文本框內輸入的內容寫入網絡os.write((input.getText().toString()+"\r\n").getBytes("utf-8"));//清空input文本框input.setText(""); }});多線程程序的子線程負責讀取來自網絡的數(shù)據,讀到數(shù)據之后便通過Handler對象發(fā)送一條消息。(1)聲明該線程負責處理的Socket以及該線程處理的Socket所對應的輸入流//該線程負責處理的SocketprivateSockets;privateHandlerhandler;//該線程所處理的Socket所對應的輸入流BufferedReaderbr=null;(2)定義構造器publicClientThread(Sockets,Handlerhandler)throwsIOException{this.s=s;this.handler=handler;br=newBufferedReader(newInputStreamReader(s.getInputStream()));}多線程(3)不斷讀取Socket輸入的內容public
voidrun(){Stringcontent=null;while((content=br.readLine())!=null){//每當讀到來自服務器的數(shù)據之后,發(fā)送消息通知程序界面顯示該數(shù)據Messagemsg=newMessage();msg.what=0x123;msg.obj=content;handler.sendMessage(msg);}}WebViewWebView是一個開發(fā)的瀏覽器組件,是基于WebKit內核開發(fā)出來的,如Safari、GoogleChrome瀏覽器都是通過WebView實現(xiàn)的,而在Android系統(tǒng)中,默認提供了WebView組件的支持。除了支持各個瀏覽器的“前進”、“后退”等功能之外,最為強大的是在WebView組件之中也支持JavaScript的操作。
Webview瀏覽網頁Webview的用法與普通ImageView用法基本類似,它提供了大量方法來執(zhí)行瀏覽器操作,例如如下常用方法:clearCache(booleanincludeDiskFiles)//清除緩存clearHistory()//清除歷史前進和后退getSettings()//獲取WebSettinggoBack()//返回上一頁面goForward()//前一頁面loadUrl(Stringurl)//打開一個頁面reload()//重新加載當前頁面stopLoading()//停止加載setScrollBarStyle(intstyle)//指定loadData("HTMLString")//加載HTML
默認情況下WebView不支持javascript,和ajax效果:如下可以啟用javascript和Ajax:WebSettings
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年浙教版九年級地理下冊階段測試試卷
- 2025年粵教新版九年級歷史上冊月考試卷含答案
- 2025年中圖版選擇性必修3歷史上冊月考試卷含答案
- 2025年滬教版八年級歷史下冊階段測試試卷含答案
- 2025年人教新起點高一語文上冊月考試卷
- 遵義醫(yī)藥高等??茖W?!冬F(xiàn)代漢語語法研究》2023-2024學年第一學期期末試卷
- 二零二五年度出租車行業(yè)駕駛員安全責任合同范本4篇
- 二零二五年度出租車公司車輛調度合同3篇
- 房屋贈與合同范本(2篇)
- 2025年度農機保險代理銷售合同范本4篇
- 蛋糕店服務員勞動合同
- 土地買賣合同參考模板
- 2025高考數(shù)學二輪復習-專題一-微專題10-同構函數(shù)問題-專項訓練【含答案】
- 新能源行業(yè)市場分析報告
- 2025年天津市政建設集團招聘筆試參考題庫含答案解析
- 巖土工程勘察.課件
- 中餐烹飪技法大全
- 新型電力系統(tǒng)研究
- 滋補類用藥的培訓
- 北師大版高三數(shù)學選修4-6初等數(shù)論初步全冊課件【完整版】
- 高職《勞動教育》指導綱要
評論
0/150
提交評論