編輯:關於Android編程
創建一個客戶端對象
HttpClient client = new DefaultHttpClient();
創建一個get請求對象
HttpGet hg = new HttpGet(path);
發送get請求,建立連接,返回響應頭對象
HttpResponse hr = hc.execute(hg);
獲取狀態行對象,獲取狀態碼,如果為200則說明請求成功
if(hr.getStatusLine().getStatusCode() == 200){
//拿到服務器返回的輸入流
InputStream is = hr.getEntity().getContent();
String text = Utils.getTextFromStream(is);
}
//創建一個客戶端對象
HttpClient client = new DefaultHttpClient();
//創建一個post請求對象
HttpPost hp = new HttpPost(path);
往post對象裡放入要提交給服務器的數據
//要提交的數據以鍵值對的形式存在BasicNameValuePair對象中
List parameters = new ArrayList();
BasicNameValuePair bnvp = new BasicNameValuePair("name", name);
BasicNameValuePair bnvp2 = new BasicNameValuePair("pass", pass);
//BasicNameValuePair是NameValuePair的實現類
parameters.add(bnvp);
parameters.add(bnvp2);
//創建實體對象,指定進行URL編碼的碼表
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, "utf-8");
//為post請求設置實體
hp.setEntity(entity);
//創建異步的httpclient對象
AsyncHttpClient ahc = new AsyncHttpClient();
//發送get請求
ahc.get(path, new MyHandler());
注意AsyncHttpResponseHandler兩個方法的調用時機
class MyHandler extends AsyncHttpResponseHandler{
//http請求成功,返回碼為200,系統回調此方法
@Override
public void onSuccess(int statusCode, Header[] headers,
//responseBody的內容就是服務器返回的數據
byte[] responseBody) {
Toast.makeText(MainActivity.this, new String(responseBody), 0).show();
}
//http請求失敗,返回碼不為200,系統回調此方法
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
Toast.makeText(MainActivity.this, "返回碼不為200", 0).show();
}
}
使用RequestParams對象封裝要攜帶的數據
//創建異步httpclient對象
AsyncHttpClient ahc = new AsyncHttpClient();
//創建RequestParams封裝要攜帶的數據
RequestParams rp = new RequestParams();
rp.add("name", name);
rp.add("pass", pass);
//發送post請求
ahc.post(path, rp, new MyHandler());
原理:服務器CPU分配給每條線程的時間片相同,服務器帶寬平均分配給每條線程,所以客戶端開啟的線程越多,就能搶占到更多的服務器資源
發送http請求至下載地址
String path = "http://192.168.1.102:8080/editplus.exe";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
獲取文件總長度,然後創建長度一致的臨時文件
if(conn.getResponseCode() == 200){
//獲得服務器流中數據的長度
int length = conn.getContentLength();
//創建一個臨時文件存儲下載的數據
RandomAccessFile raf = new RandomAccessFile(getFileName(path), "rwd");
//設置臨時文件的大小
raf.setLength(length);
raf.close();
確定線程下載多少數據
//計算每個線程下載多少數據
int blockSize = length / THREAD_COUNT;
for(int id = 1; id <= 3; id++){
//計算每個線程下載數據的開始位置和結束位置
int startIndex = (id - 1) * blockSize;
int endIndex = id * blockSize - 1;
if(id == THREAD_COUNT){
endIndex = length;
}
//開啟線程,按照計算出來的開始結束位置開始下載數據
new DownLoadThread(startIndex, endIndex, id).start();
}
String path = "http://192.168.1.102:8080/editplus.exe";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//向服務器請求部分數據
conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
conn.connect();
下載請求到的數據,存放至臨時文件中
if(conn.getResponseCode() == 206){
InputStream is = conn.getInputStream();
RandomAccessFile raf = new RandomAccessFile(getFileName(path), "rwd");
//指定從哪個位置開始存放數據
raf.seek(startIndex);
byte[] b = new byte[1024];
int len;
while((len = is.read(b)) != -1){
raf.write(b, 0, len);
}
raf.close();
}
定義一個int變量記錄每條線程下載的數據總長度,然後加上該線程的下載開始位置,得到的結果就是下次下載時,該線程的開始位置,把得到的結果存入緩存文件
//用來記錄當前線程總的下載長度
int total = 0;
while((len = is.read(b)) != -1){
raf.write(b, 0, len);
total += len;
//每次下載都把新的下載位置寫入緩存文本文件
RandomAccessFile raf2 = new RandomAccessFile(threadId + ".txt", "rwd");
raf2.write((startIndex + total + "").getBytes());
raf2.close();
}
下次下載開始時,先讀取緩存文件中的值,得到的值就是該線程新的開始位置
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String text = br.readLine();
int newStartIndex = Integer.parseInt(text);
//把讀到的值作為新的開始位置
startIndex = newStartIndex;
fis.close();
三條線程都下載完畢之後,刪除緩存文件
RUNNING_THREAD--;
if(RUNNING_THREAD == 0){
for(int i = 0; i <= 3; i++){
File f = new File(i + ".txt");
f.delete();
}
}
拿到下載文件總長度時,設置進度條的最大值
//設置進度條的最大值
pb.setMax(length);
進度條需要顯示三條線程的整體下載進度,所以三條線程每下載一次,就要把新下載的長度加入進度條
定義一個int全局變量,記錄三條線程的總下載長度
int progress;
刷新進度條
while((len = is.read(b)) != -1){
raf.write(b, 0, len);
//把當前線程本次下載的長度加到進度條裡
progress += len;
pb.setProgress(progress);
每次斷點下載時,從新的開始位置開始下載,進度條也要從新的位置開始顯示,在讀取緩存文件獲取新的下載開始位置時,也要處理進度條進度
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String text = br.readLine();
int newStartIndex = Integer.parseInt(text);
//新開始位置減去原本的開始位置,得到已經下載的數據長度
int alreadyDownload = newStartIndex - startIndex;
//把已經下載的長度設置入進度條
progress += alreadyDownload;
tv.setText(progress * 100 / pb.getMax() + "%");
HttpUtils本身就支持多線程斷點續傳,使用起來非常的方便
創建HttpUtils對象
HttpUtils http = new HttpUtils();
下載文件
http.download(url, //下載請求的網址
target, //下載的數據保存路徑和文件名
true, //是否開啟斷點續傳
true, //如果服務器響應頭中包含了文件名,那麼下載完畢後自動重命名
new RequestCallBack() {//偵聽下載狀態
//下載成功此方法調用
@Override
public void onSuccess(ResponseInfo arg0) {
tv.setText("下載成功" + arg0.result.getPath());
}
//下載失敗此方法調用,比如文件已經下載、沒有網絡權限、文件訪問不到,方法傳入一個字符串參數告知失敗原因
@Override
public void onFailure(HttpException arg0, String arg1) {
tv.setText("下載失敗" + arg1);
}
//在下載過程中不斷的調用,用於刷新進度條
@Override
public void onLoading(long total, long current, boolean isUploading) {
super.onLoading(total, current, isUploading);
//設置進度條總長度
pb.setMax((int) total);
//設置進度條當前進度
pb.setProgress((int) current);
tv_progress.setText(current * 100 / total + "%");
}
});
有時候為了程序的安全性,我們經常要采取一些安全措施,就像我們常用的支付寶那樣,隔一定的時間再回到應用程序時會讓用戶利用手勢去解鎖應用程序,最近由於項目需求,也要求做這樣一
一、JNI概述 JNI 是Java Native Interface的縮寫,中文翻譯為“Java本地調用”,JNI 是本地編程接口。它使得在 Java 虛擬機 (VM)
最近在做android串口的開發,找到一個開源的串口類android-serialport-api。其主頁在這裡http://code.google.com/p/andr
Fragment 與 Activity之間傳遞數據有兩種方法,一種是使用setArgument,一種是使用接口回調。下面先學習第一種方法。 (1)使用setArgum