編輯:關於Android編程
在Android的網絡通訊中,通常會使用Socket進行設備間數的數據通訊,使用Http來對網絡數據進行請求。
1、Socket(套接字)
不管是有過Java開發經驗還是.NET開發經驗的同學都應該對Socket有或多或少的了解,常見的TCP或者UDP協議其實都是基於Socket來實現的。
Socket是用於描述網絡上的一個設備中的一個進程或者應用程序的,Socket由IP地址和端口號兩部分組成。IP地址用來定位設備,端口號用來定位應用程序或者進程,比如我們常見的運行在80端口上的HTTP協議。Socket的常見格式為:192.168.1.1:1234。
那麼應用程序是如何通過Socket來與網絡中的其他設備進行通訊的呢?通常情況下,Socket通信有兩部分,一部分為監聽的Server端,一部分為主動請求連接的Client端。Server端會一直監聽Socket中的端口直到有請求為止,當Client端對該端口進行連接請求時,Server端就給予應答並返回一個Socket對象,以後在Server端與Client端的數據交換就可以使用這個Socket來進行操作了。
2、Android中使用Socket進行數據交換
ServerSocket
建立服務端(Server)時,需要使用ServerSocket對象,這個對象會自動對其構造函數中傳入的端口號進行監聽,並在收到連接請求後,使用ServerSocket.accept()方法返回一個連接的的Socket對象。這個方法並不需要我們像在.NET中那樣使用Start方法,它會自動進行監聽的。
Socket
不管建立客戶端(Client)還是在進行其他數據交換方面的操作時,都需要使用Socket類。Socket類在進行初始化時需要出入Server端的IP地址和端口號,並返回連接到Server端的一個Socket對象,如果是連接失敗,那麼將返回異常。同ServerSocket,也是自動進行連接請求的。
,並返回連接到Server端的一個Socket對象,如果是連接失敗,那麼將返回異常。同ServerSocket,也是自動進行連接請求的。
通過上面兩個步驟後,Server端和Client端就可以連接起來了,但是僅僅連接起來是沒有任何作用的,數據交換才是我們的目的,這時候就需要用到IO流中的OutputStream類和InputStream類。
OutputStream——可寫流
當應用程序需要對流進行數據寫操作時,可以使用Socket.getOutputStream()方法返回的數據流進行操作。
InputStream——可讀流
當應用程序要從流中取出數據時,可以使用Socket.getInputStream()方法返回的數據流進行操作。
[java]
View Code
package LiB.Demo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketHelper {
private static ServerSocket serverSocket = null;
private static Socket client = null;
private final static int port = 9048;
private static BufferedReader br= null;
private static BufferedWriter bw = null;
/**
* 創建一個SocketServer對象用來建立服務器
* @throws IOException
*/
public static void CreateServer() throws IOException
{
serverSocket = new ServerSocket(port,10);
System.out.println("start listening...");
}
/**
* 創建一個Socket對象用來連接SocketServer對象
* @param dstName Server對象的ip地址
* @return
* @throws IOException
*/
public static Socket CreateClient(String dstName) throws IOException
{
Socket socket = new Socket(dstName, port);
//Socket sockets = new Socket("192.168.8.12",port);
return socket;
}
/**
* 返回一個已經連接到服務器上的Socket對象
* @throws IOException
*/
public static void GetClinetSocket() throws IOException
{
client = serverSocket.accept();
System.out.println("get a connected client");
}
/**
* 向socket對象所獲取的流中發送數據
* @param socket
* @param msg
* @throws IOException
*/
public static void SendMsg(Socket socket , String msg) throws IOException
{
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(msg);
bw.flush();
bw.close();
}
/**
* 獲取socket對象流中數據
* @param socket
* @param msg
* @return
* @throws IOException
*/
public static String ReceiveMsg(Socket socket, String msg) throws IOException
{
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String receiveMsg = "Receive msg:"+ br.readLine();
br.close();
return receiveMsg;
}
/**
* 釋放socket對象
* @throws IOException
*/
public static void Close() throws IOException
{
if(client != null)
{
client.close();
}
if(serverSocket != null)
{
serverSocket.close();
}
}
}
View Code
package LiB.Demo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketHelper {
private static ServerSocket serverSocket = null;
private static Socket client = null;
private final static int port = 9048;
private static BufferedReader br= null;
private static BufferedWriter bw = null;
/**
* 創建一個SocketServer對象用來建立服務器
* @throws IOException
*/
public static void CreateServer() throws IOException
{
serverSocket = new ServerSocket(port,10);
System.out.println("start listening...");
}
/**
* 創建一個Socket對象用來連接SocketServer對象
* @param dstName Server對象的ip地址
* @return
* @throws IOException
*/
public static Socket CreateClient(String dstName) throws IOException
{
Socket socket = new Socket(dstName, port);
//Socket sockets = new Socket("192.168.8.12",port);
return socket;
}
/**
* 返回一個已經連接到服務器上的Socket對象
* @throws IOException
*/
public static void GetClinetSocket() throws IOException
{
client = serverSocket.accept();
System.out.println("get a connected client");
}
/**
* 向socket對象所獲取的流中發送數據
* @param socket
* @param msg
* @throws IOException
*/
public static void SendMsg(Socket socket , String msg) throws IOException
{
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(msg);
bw.flush();
bw.close();
}
/**
* 獲取socket對象流中數據
* @param socket
* @param msg
* @return
* @throws IOException
*/
public static String ReceiveMsg(Socket socket, String msg) throws IOException
{
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String receiveMsg = "Receive msg:"+ br.readLine();
br.close();
return receiveMsg;
}
/**
* 釋放socket對象
* @throws IOException
*/
public static void Close() throws IOException
{
if(client != null)
{
client.close();
}
if(serverSocket != null)
{
serverSocket.close();
}
}
}3、HTTP通訊
在開始前先簡單介紹下HTTP協議中的兩種不同的請求方式——GET和POST。GET方式在進行數據請求時,會把數據附加到URL後面傳遞給服務器,比如常見的:http://XXX.XXX.XXX/XX.aspx?id=1,POST方式則是將請求的數據放到HTTP請求頭中,作為請求頭的一部分傳入服務器。所以,在進行HTTP編程前,首先要明確究竟使用的哪種方式進行數據請求的。
在Android中,可以有兩種方式可以用來進行Http編程:1、HttpURLConnection;2、HttpClient。
HttpURLConnection
HttpURLConnection是繼承自URLConnection的一個抽象類,在HTTP編程時,來自HttpURLConnection的類是所有操作的基礎,獲取該對象的代碼如下:
[java]
View Code
public HttpURLConnection urlconn= null;
private void Init() throws IOException
{
if (urlStr=="")
{
urlStr="http://www.baidu.com";
}
URL url = new URL(urlStr);
//打開一個URL所指向的Connection對象
urlconn = (HttpURLConnection)url.openConnection();
}
View Code
public HttpURLConnection urlconn= null;
private void Init() throws IOException
{
if (urlStr=="")
{
urlStr="http://www.baidu.com";
}
URL url = new URL(urlStr);
//打開一個URL所指向的Connection對象
urlconn = (HttpURLConnection)url.openConnection();
}
HttpURLConnection對網絡資源的請求在默認情況下是使用GET方式的,所以當使用GET方式時,不需要我們做太多的工作:
[java]
View Code
public HttpURLConnection urlconn= null;
private void Init() throws IOException
{
if (urlStr=="")
{
urlStr="http://www.baidu.com";
}
URL url = new URL(urlStr);
//打開一個URL所指向的Connection對象
urlconn = (HttpURLConnection)url.openConnection();
}
/**
* Http中的get請求,在Url中帶有請求的參數,請求的URL格式通常為:"http://XXX.XXXX.com/xx.aspx?param=value"
* 在android中默認的http請求為get方式
* @return
* @throws IOException
*/
public String HttpGetMethod() throws IOException
{
if(urlconn == null)
{
Init();
}
String result = StreamDeal(urlconn.getInputStream());
urlconn.disconnect();
return result;
}
View Code
public HttpURLConnection urlconn= null;
private void Init() throws IOException
{
if (urlStr=="")
{
urlStr="http://www.baidu.com";
}
URL url = new URL(urlStr);
//打開一個URL所指向的Connection對象
urlconn = (HttpURLConnection)url.openConnection();
}
/**
* Http中的get請求,在Url中帶有請求的參數,請求的URL格式通常為:"http://XXX.XXXX.com/xx.aspx?param=value"
* 在android中默認的http請求為get方式
* @return
* @throws IOException
*/
public String HttpGetMethod() throws IOException
{
if(urlconn == null)
{
Init();
}
String result = StreamDeal(urlconn.getInputStream());
urlconn.disconnect();
return result;
}當我們需要使用POST方式時,就需要使用setRequestMethod()來設置請求方式了。
[java]
View Code
/**
* Http中的post請求,不在Url中附加任何參數,這些參數都會通過cookie或者session等其他方式以鍵值對的形式key=value傳送到服務器上,完成一次請求
* 請求的URL格式通常為:"http://XXX.XXXX.com/xx.aspx"
* @param param 請求的鍵名
* @param value 請求的數據值
* @throws IOException
*/
public String HttpPostMethod(String key,String value) throws IOException
{
if (urlconn==null)
{
Init();
}
//設置該URLConnection可讀
urlconn.setDoInput(true);
//設置該URLConnection可寫
urlconn.setDoOutput(true);
//使用POST方式來提交數據
urlconn.setRequestMethod("POST");
//不運行緩存
urlconn.setUseCaches(false);
//當使用POST方式進行數據請求時,我們可以手動執行connect動作,當然,這個動作其實在getOutputStream()方法中會默認執行的
//上面那些設置URLConnection屬性的動作,一定要在connect動作執行前,因為一旦動作已經執行,熟悉設置就沒有任何作用了
urlconn.connect();
//使用POST方式時,我們需要自己構造部分Http請求的內容,因此我們需要使用OutputStream來進行數據寫如操作
OutputStreamWriter writer = new OutputStreamWriter(urlconn.getOutputStream());
String urlQueryStr = key+"="+URLEncoder.encode(value, "Utf-8");
writer.write(urlQueryStr);
writer.flush();
writer.close();
//獲取返回的內容
String result = StreamDeal(urlconn.getInputStream());
return result;
}
View Code
/**
* Http中的post請求,不在Url中附加任何參數,這些參數都會通過cookie或者session等其他方式以鍵值對的形式key=value傳送到服務器上,完成一次請求
* 請求的URL格式通常為:"http://XXX.XXXX.com/xx.aspx"
* @param param 請求的鍵名
* @param value 請求的數據值
* @throws IOException
*/
public String HttpPostMethod(String key,String value) throws IOException
{
if (urlconn==null)
{
Init();
}
//設置該URLConnection可讀
urlconn.setDoInput(true);
//設置該URLConnection可寫
urlconn.setDoOutput(true);
//使用POST方式來提交數據
urlconn.setRequestMethod("POST");
//不運行緩存
urlconn.setUseCaches(false);
//當使用POST方式進行數據請求時,我們可以手動執行connect動作,當然,這個動作其實在getOutputStream()方法中會默認執行的
//上面那些設置URLConnection屬性的動作,一定要在connect動作執行前,因為一旦動作已經執行,熟悉設置就沒有任何作用了
urlconn.connect();
//使用POST方式時,我們需要自己構造部分Http請求的內容,因此我們需要使用OutputStream來進行數據寫如操作
OutputStreamWriter writer = new OutputStreamWriter(urlconn.getOutputStream());
String urlQueryStr = key+"="+URLEncoder.encode(value, "Utf-8");
writer.write(urlQueryStr);
writer.flush();
writer.close();
//獲取返回的內容
String result = StreamDeal(urlconn.getInputStream());
return result;
}
HttpClient
這個類並不是來自Android的,而是來自org.apache.http。和HttpURLConnection相同,HttpClient也存在GET和POST兩種方式。
HttpGet
在HttpClient中,我們可以非常輕松使用HttpGet對象來通過GET方式進行數據請求操作,當獲得HttpGet對象後我們可以使用HttpClient的execute方法來向我們的服務器發送請求。在發送的GET請求被服務器相應後,會返回一個HttpResponse響應對象,利用這個響應的對象我們能夠獲得響應回來的狀態碼,如:200、400、401等等。
[java]
View Code
public String HttpGetMethod()
{
String result = "";
try
{
HttpGet httpRequest = new HttpGet(urlStr);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpRequest);
if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK)
{
result = EntityUtils.toString(httpResponse.getEntity());
}
else
{
result = "null";
}
return result;
}
catch(Exception e)
{
return null;
}
}
View Code
public String HttpGetMethod()
{
String result = "";
try
{
HttpGet httpRequest = new HttpGet(urlStr);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpRequest);
if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK)
{
result = EntityUtils.toString(httpResponse.getEntity());
}
else
{
result = "null";
}
return result;
}
catch(Exception e)
{
return null;
}
}HttpPost
當我們使用POST方式時,我們可以使用HttpPost類來進行操作。當獲取了HttpPost對象後,我們就需要向這個請求體傳入鍵值對,這個鍵值對我們可以使用NameValuePair對象來進行構造,然後再使用HttpRequest對象最終構造我們的請求體,最後使用HttpClient的execute方法來發送我們的請求,並在得到響應後返回一個HttpResponse對象。其他操作和我們在HttpGet對象中的操作一樣。
[java]
View Code
public String HttpPostMethod(String key,String value)
{
String result = "";
try
{
// HttpPost連接對象
HttpPost httpRequest = new HttpPost(urlStr);
// 使用NameValuePair來保存要傳遞的Post參數
List<NameValuePair> params = new ArrayList<NameValuePair>();
// 添加要傳遞的參數
params.add(new BasicNameValuePair(key, value));
// 設置字符集
HttpEntity httpentity = new UrlEncodedFormEntity(params, "Utf-8");
// 請求httpRequest
httpRequest.setEntity(httpentity);
// 取得默認的HttpClient
HttpClient httpclient = new DefaultHttpClient();
// 取得HttpResponse
HttpResponse httpResponse = httpclient.execute(httpRequest);
// HttpStatus.SC_OK表示連接成功
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 取得返回的字符串
result = EntityUtils.toString(httpResponse.getEntity());
return result;
} else {
return "null";
}
}
catch(Exception e)
{
return null;
}
}
View Code
public String HttpPostMethod(String key,String value)
{
String result = "";
try
{
// HttpPost連接對象
HttpPost httpRequest = new HttpPost(urlStr);
// 使用NameValuePair來保存要傳遞的Post參數
List<NameValuePair> params = new ArrayList<NameValuePair>();
// 添加要傳遞的參數
params.add(new BasicNameValuePair(key, value));
// 設置字符集
HttpEntity httpentity = new UrlEncodedFormEntity(params, "Utf-8");
// 請求httpRequest
httpRequest.setEntity(httpentity);
// 取得默認的HttpClient
HttpClient httpclient = new DefaultHttpClient();
// 取得HttpResponse
HttpResponse httpResponse = httpclient.execute(httpRequest);
// HttpStatus.SC_OK表示連接成功
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 取得返回的字符串
result = EntityUtils.toString(httpResponse.getEntity());
return result;
} else {
return "null";
}
}
catch(Exception e)
{
return null;
}
}
事先說明:定位功能在安卓6.0需要用戶手動確認權限後才能使用若需在安卓6.0適配WebView的定位功能,則需要在WebView中手動增加用戶權限訪問詳細可百度安卓6.0
翻譯工作耗時費神,如果你覺得本文翻譯得還OK,請點擊文末的“頂”;如有錯訛,敬請指正。謝謝。 Eclip
給大家分享一個高仿微信的PopupWindow、就是微信的掃一掃那個功能窗口、下面有應用運行效果圖、更加直觀的展示了Demo的效果、源代碼是通過兩種方法實現的、大家可以下
這裡分享一個Android的非常經典實用而且簡單方便的第三方UI控件庫:BottomView(小米的米UI也用到了這個) 實現功能: 可以在底部彈出的Vie