編輯:關於Android編程
android中的網絡操作和java裡面沒有什麼區別,java裡面的很多網絡操作方法都可以搬到android中去使用,主要幾個點:
1、post和get請求的區別,大家可以在網上查閱有關資料進行了解,get主要以向地址中拼接字符串參數發送到服務器,長度有限制,並且請求參數暴露在地址欄中,不怎麼安全;post則主要是將請求參數轉換為相應的http協議請求體發送到服務器,相比get方式,參數的長度沒有限制,並且參數信息不會暴露給用戶;
2、我們在java web裡面通過浏覽器以post方式發送數據,浏覽器幫我們轉換為相應的http協議,也就是說浏覽器內部幫我們設置為相應的http請求體,然後發送到服務器,用戶通過浏覽器向服務器發送數據-->浏覽器轉換為http協議-->發送到服務器,如果我們用android做客戶端用java代碼編寫post請求,需要設置其請求體,而get方式請求則只需要拼接相應的參數地址,用戶通過android客戶端向服務器發送數據-->編碼設置為相應的http協議-->發送到服務器;
3、android裡面包含了apache的httpclient,相當與web裡面的浏覽器,我們還可以利用其api進行相應的請求操作,相比與純java代碼,它裡面封裝了很多東西,我們只需要根據業務需求選擇相應的api即可;如果我們在swing中使用apache的httpclient,則需要導入其相應的jar包
post請求:
java web:用戶通過浏覽器向服務器發送數據-->浏覽器轉換為http協議-->發送到服務器
java代碼:用戶通過android客戶端向服務器發送數據-->編碼設置為相應的http協議-->發送到服務器
httpclient:用戶通過android客戶端向服務器發送數據(httpclient幫我們轉換為相應的http協議)-->發送到服務器
代碼實現功能:裡面都有相應的注釋,我在我的工程裡面建立了一個專門處理Http上傳、下載的類:HttpUtil
1、從服務器獲取二進制數據,圖片、視頻等:
/**
* 從服務器上獲取二進制數據,例如圖片、視頻等
* @param serverUrl: 服務器地址
* @param newFileName:獲取到本地後新文件的地址+名稱 例如:C://test.png
*/
public static void getByteFromServer(String serverUrl,String newFileName)throws Exception{
URL url = new URL(serverUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");//通過Get方式請求
conn.setConnectTimeout(5 * 1000);//設置連接延遲,因為android系統內存有限,不能長時間去與服務器建立連接
InputStream inStream = conn.getInputStream();//通過輸入流獲取圖片數據
byte[] data = readInputStream(inStream);//得到圖片的二進制數據
File imageFile = new File(newFileName);
FileOutputStream outStream = new FileOutputStream(imageFile);
outStream.write(data);
outStream.close();
} /**
* 將輸入流轉換為字節數據
* @param inStream
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while( (len=inStream.read(buffer)) != -1 ){
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
} /**
* 從服務器上獲取文本信息,例如html、xml等信息
* @param serverUrl
* @return 文本字符串
*/
public static String getTxtFromServer(String serverUrl)throws Exception{
URL url = new URL(serverUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();//通過輸入流獲取txt數據
byte[] data = readInputStream(inStream);//得到txt的二進制數據
String txt = new String(data);
return txt;
}/**Get請求方式即是通過將參數放到地址中發送到服務器 * 向服務器發送Get請求 * @param path:服務器請求地址 * @param params:請求參數 * @param enc:編碼 * @return true:請求成功 false:請求失敗 * @throws Exception */ public static boolean sendGetRequest(String path, Mapparams, String enc) throws Exception{ StringBuilder sb = new StringBuilder(path); //?username=jack&password=123456&age=23 if(params!=null && !params.isEmpty()){ sb.append('?'); for(Map.Entry entry : params.entrySet()){ sb.append(entry.getKey()).append('=') .append(URLEncoder.encode(entry.getValue(), enc)).append('&'); } sb.deleteCharAt(sb.length()-1); } URL url = new URL(sb.toString()); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5 * 1000); if(conn.getResponseCode()==200){ //請求成功,可以調用上面的getByteFromServer方法得到相應的服務器數據 //byte[] b=readInputStream(conn.getInputStream()); return true; } return false; }
/**Post請求在浏覽器中是轉換了相應的http協議進行 * 而轉換後的http協議中包含了例如Content-Type、Content-Length等信息 * 所以通過android客戶端發送post請求需要將其設置為相應的http協議發送出去 * 向服務器發送一個post表單請求 * @param path:服務器地址 * @param params:請求參數 * @param enc:編碼 * @return true:請求成功 false:請求失敗 * @throws Exception */ public static boolean sendPostRequest(String path, Mapparams, String enc) throws Exception{ //username=jack&password=123456&age=23 StringBuilder sb = new StringBuilder(); if(params!=null && !params.isEmpty()){ for(Map.Entry entry : params.entrySet()){ sb.append(entry.getKey()).append('=') .append(URLEncoder.encode(entry.getValue(), enc)).append('&'); } sb.deleteCharAt(sb.length()-1); } byte[] entitydata = sb.toString().getBytes();//得到實體的二進制數據 URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(5 * 1000); conn.setUseCaches(false);//不進行緩存 conn.setDoOutput(true);//如果通過post提交數據,必須設置允許對外輸出數據 //設置http請求頭,向服務器發送post請求,Content-Type和Content-Length兩個參數必須要,其他可省略 //設置發送內容類型,為表單數據 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //設置發送內容長度 conn.setRequestProperty("Content-Length", String.valueOf(entitydata.length)); conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"); conn.setRequestProperty("Accept-Language", "zh-CN"); conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"); conn.setRequestProperty("Connection", "Keep-Alive"); OutputStream outStream = conn.getOutputStream(); outStream.write(entitydata); outStream.flush(); outStream.close(); if(conn.getResponseCode()==200){ //請求成功,可以調用上面的getByteFromServer方法得到相應的服務器數據 //byte[] b=readInputStream(conn.getInputStream()); return true; } return false; }
/**
* 向服務器發送xml數據
* @param path:服務器地址
* @param xml:xml字符串信息
* @param enc:編碼
* @return true:請求成功 false:請求失敗
* @throws Exception
*/
public static boolean sendPostXMLRequest(String path, String xml,String enc)throws Exception{
byte[] data = xml.getBytes();
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setConnectTimeout(5 * 1000);
conn.setDoOutput(true);//如果通過post提交數據,必須設置允許對外輸出數據
//設置發送內容類型,為xml數據
conn.setRequestProperty("Content-Type", "text/xml; charset="+enc);
//設置發送內容長度
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
if(conn.getResponseCode()==200){
//byte[] b=readInputStream(conn.getInputStream());
return true;
}
return false;
}/** * 通過httpClient發送get請求 * @param path:服務器地址 * @param params:參數名稱 * @param enc:編碼 * @return true:請求成功 false:請求失敗 * @throws Exception */ public static boolean sendGetRequestFromHttpClient(String path, Mapparams,String enc) throws Exception{ StringBuilder sb = new StringBuilder(path); //?username=jack&password=123456&age=23 if(params!=null && !params.isEmpty()){ sb.append('?'); for(Map.Entry entry : params.entrySet()){ sb.append(entry.getKey()).append('=') .append(URLEncoder.encode(entry.getValue(), enc)).append('&'); } sb.deleteCharAt(sb.length()-1); } //相當與浏覽器 HttpClient httpClient=new DefaultHttpClient(); //得到一個HttpGet對象 HttpGet get=new HttpGet(sb.toString()); //發送一個Get請求 HttpResponse response=httpClient.execute(get); if(response.getStatusLine().getStatusCode()==200){ //String str=EntityUtils.toString(response.getEntity());即可得到服務器數據信息 //InputStream inStream=httpEntity.getContent();即可得到服務器輸入流 return true; } return false; }
/** * 通過httpClient發送Post請求 * @param path:服務器地址 * @param params:參數名稱 * @param enc:編碼 * @return true:請求成功 false:請求失敗 * @throws Exception */ public static boolean sendPostRequestFromHttpClient(String path, Mapparams,String enc) throws Exception{ List paramPairs = new ArrayList (); if(params!=null && !params.isEmpty()){ for(Map.Entry entry : params.entrySet()){ paramPairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } } UrlEncodedFormEntity entitydata = new UrlEncodedFormEntity(paramPairs, enc);//得到經過編碼過後的實體數據 HttpPost post = new HttpPost(path); //form post.setEntity(entitydata); DefaultHttpClient client = new DefaultHttpClient(); //浏覽器 HttpResponse response = client.execute(post);//執行請求 if(response.getStatusLine().getStatusCode()==200){ //String str=EntityUtils.toString(response.getEntity());即可得到服務器數據信息 //InputStream inStream=httpEntity.getContent();即可得到服務器輸入流 return true; } return false; }
建立表單實體文件:
public class FormFile {
/* 上傳文件的數據 */
private byte[] data;
private InputStream inStream;
private File file;
/* 文件名稱 */
private String filname;
/* 請求參數名稱*/
private String parameterName;
/* 內容類型 */
private String contentType = "application/octet-stream";
public FormFile(String filname, byte[] data, String parameterName, String contentType) {
this.data = data;
this.filname = filname;
this.parameterName = parameterName;
if(contentType!=null) this.contentType = contentType;
}
public FormFile(String filname, File file, String parameterName, String contentType) {
this.filname = filname;
this.parameterName = parameterName;
this.file = file;
try {
this.inStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if(contentType!=null) this.contentType = contentType;
}
public File getFile() {
return file;
}
public InputStream getInStream() {
return inStream;
}
public byte[] getData() {
return data;
}
public String getFilname() {
return filname;
}
public void setFilname(String filname) {
this.filname = filname;
}
public String getParameterName() {
return parameterName;
}
public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
}/** * 向服務器提交的信息包含上傳文件信息 * 直接通過HTTP協議提交數據到服務器,實現如下面表單提交功能: ** @param path 上傳路徑(注:避免使用localhost或127.0.0.1這樣的路徑測試,因為它會指向手機模擬器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080這樣的路徑測試) * @param params 請求參數 key為參數名,value為參數值 * @param file 上傳文件 */ public static boolean sendPostRequest(String path, Map
osgi之ServiceListener的應用
前言我原想直接跳過這些osgi中基礎知識,直接從osgi應用的一些中級篇或者高級篇開始的,後來想到osgi中的ServiceListener、ServiceTracker
Android ToolBar使用
Android Toolbar:ToolBar是Android 5.0(API Level 21)之後用來取代ActionBar的ToolBar的優勢:Toolbar本身
Android開發:AsyncTask源代碼完全解析
從事Java開發以來,接觸過很多的開源代碼,自己能夠明白代碼但是想要表達出來卻有點困難,從今天開始,逐漸開始對一些開源代碼進行解析並記錄成blog分享出來,希望以此提升自
Android4.4 framework分析——startService的創建過程
我們常用context.startService()來啟動一個service,下面來分析一下這個service的啟動過程,下圖是service啟動的序列圖: st