安卓網絡編程

這幾天一直在搞跟網絡編程相關的東西,這裏整理了一下關於socket網絡編程以及http協議的基本用法。省的自己以後再用或者其他人學習方便。

首先是基於socket的網絡編程

android的網絡編程部分,基本上和java的網絡編程時一樣的,基本上也分成兩種,一種是基於socket的,另外一種是基於http協議的。

基於Socket的基本用法,跟Java裏面的用法一樣,簡單回顧一下:

一:服務端 
1:啓動一個服務器端的socket:ServerSocket server = new ServerSocket(1234); 
2:開始偵聽請求:Socket client = server.accept(); 
3:取得輸入和輸出流: 
4:然後就可以通過流來進行網絡傳輸了 
5:最好要記得關閉流和Server 
ServerSocket server=new ServerSocket(1234);
Socket client=server.accept();
InputStream in = client.getInputStream();
OutputStream out=client.getOutputStream();
byte bs[] = new byte[1024];
in.read(bs);
String str= new String(bs);
System.out.println(str);
out.write("Server send".getBytes());
out.flush();
client.close();
二:客戶端: 
1:發起一個socket連接:Socket server = new Socket("192.168.1.2",1234); 
2:取得輸入和輸出流: 
3:然後就可以通過流來進行網絡傳輸了 
4:最好要記得關閉流和Socket 
String str = "client send";
out.write(str.getBytes());
out.flush();
byte bs[] = new byte[1024];
in.read(bs);
System.out.println(new String(bs));
server.close();
當然這樣實現很不好,應該包裝成上層的流或者Reader、Writer來做。 

包裝成Reader和Writer的服務端示例:

ServerSocket server=new ServerSocket(1234);
Socket client=server.accept();
BufferedReader in=
new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
String str=in.readLine();
System.out.println(str);
out.println("Server send");
out.flush();

包裝成Reader和Writer的客戶端示例:

Socket server = new Socket("192.168.0.100", 1234);
BufferedReader in = new BufferedReader(new InputStreamReader(
server.getInputStream()));
PrintWriter out = new PrintWriter(server.getOutputStream());
String str = "client send";
out.println(str);
out.flush();
System.out.println(in.readLine());
server.close();

使用HttpURLConnection

基於Http協議的基本用法,可以使用HttpURLConnection,也可以使用Apache的Http操作包,具體的使用方式下面分別來示例。 

要讓應用使用網絡,需要在Manifest文件中添加權限:

<uses-permission android:name="android.permission.INTERNET" />
HttpURLConnection默認使用get的方式與後臺交互
HttpURLConnection conn = null;
try {
URL  u = new URL("http://192.168.0.100:8080/test.jsp?uuid=123");
conn = (HttpURLConnection)u.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
while((line=br.readLine())!=null){
Log.i("NetTest","lien="+line);
}
} catch (Exception e) {e.printStackTrace();}
finally{ conn.disconnect();}

請注意一點,在Android3.0以上的版本里面,已經不允許直接在Activity裏面進行網絡的處理了,建議使用後臺線程或者是乾脆新建一個線程來運行,比如:

Thread t =new Thread(new Runnable() {
public void run() {
//上面的代碼
}
});
t.start();

或者:

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork() // or
// .detectAll()
// for
// all
// detectable
// problems
.penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
.penaltyLog().penaltyDeath().build());
HttpURLConnection使用Post的方式與後臺交互,下載數據部分跟上一個示例是一樣的,麻煩在於上傳數據到服務器,需要進行設置和處理,如下:
URL  u = new URL("http://192.168.0.100:8080/test.jsp");
conn = (HttpURLConnection)u.openConnection();
//因爲這個是post請求,下面兩個需要設置爲true
conn.setDoOutput(true);
conn.setDoInput(true);
// 設置以POST方式
conn.setRequestMethod("POST");
// Post 請求不能使用緩存
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(true);
// 配置本次連接的Content-type,配置爲application/x-www-form-urlencoded的
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
//DataOutputStream流
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
//要上傳的參數
String content = "uuid=" + URLEncoder.encode("post測試", "utf-8");
//將要上傳的內容寫入流中
out.writeBytes(content);
//刷新、關閉
out.flush();
out.close();

使用Apache的Http操作包來實現以Get的方式與後臺交互,示例如下:

//封裝用於請求的 方法 對象
HttpGet get = new HttpGet("http://192.168.0.100:8080/test.jsp?uuid=uuid121&name=name222");
//創建一個Http的客戶端對象
HttpClient client = new DefaultHttpClient();
try{ //發送請求,並獲得返回對象
HttpResponse response = client.execute(get);
//從response對象裏面把返回值取出來
HttpEntity entity = response.getEntity();
//得到返回內容的流,接下來就是流式操作了
InputStream in = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuffer buffer = new StringBuffer();
String tempStr = "";
while((tempStr=reader.readLine())!=null){
buffer.append(tempStr);
}
in.close();//應該寫finally裏面去
reader.close();//應該寫finally裏面去
Log.i("javass",buffer.toString());
}catch(Exception err){err.printStackTrace();}

使用Apache的Http操作包來實現以Post的方式與後臺交互,示例如下:

//封裝用於請求的 方法 對象
HttpPost post = new HttpPost("http://192.168.0.100:8080/test.jsp");
//爲post組織參數
NameValuePair uuid = new BasicNameValuePair("uuid","postUuid");
NameValuePair name = new BasicNameValuePair("name","postname");
List<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(uuid);
list.add(name);
//把這些參數封裝到HttpEntity中
HttpEntity reqEntity = null;
reqEntity = new UrlEncodedFormEntity(list);
//然後把HttpEntity設置到post對象裏面去
post.setEntity(reqEntity);
//創建一個Http的客戶端對象
HttpClient client = new DefaultHttpClient();
//發送請求,並獲得返回對象
HttpResponse response = client.execute(post);
後面獲取response的Entity等的處理,跟get方式是完全一樣的,這裏就不去贅述了。 

操作JSON

在實際應用開發中,網絡間傳輸的數據經常是JSON格式的,除非十分有必要,不會去使用XML。因此必須要掌握Android如何處理JSON數據,Android已經自帶了JSON的處理包“org.json”。下面就來看看如何解析已經獲取的數據,獲取數據的過程就是前面講的獲取的網絡返回值。 

返回單個對象的情況,示例如下:

JSONObject j = new JSONObject(jsonData);
String uuid = j.getString(“uuid");

返回對象數組的情況,示例如下:

JSONArray ja = new JSONArray(jsonData);
for(int i=0;i<ja.length();i++){
JSONObject j = ja.getJSONObject(i);
String retUuid = j.getString("uuid");
String retName = j.getString("name");
Log.i("javass","ret jsonsss uuid="+retUuid+",name="+retName);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章