編輯:關於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中基礎知識,直接從osgi應用的一些中級篇或者高級篇開始的,後來想到osgi中的ServiceListener、ServiceTracker
Android Toolbar:ToolBar是Android 5.0(API Level 21)之後用來取代ActionBar的ToolBar的優勢:Toolbar本身
從事Java開發以來,接觸過很多的開源代碼,自己能夠明白代碼但是想要表達出來卻有點困難,從今天開始,逐漸開始對一些開源代碼進行解析並記錄成blog分享出來,希望以此提升自
我們常用context.startService()來啟動一個service,下面來分析一下這個service的啟動過程,下圖是service啟動的序列圖: st