編輯:關於Android編程
在tomcat6.0的webappsROOT下放一個.exe的可執行文件(若放.mp3、.jpg等格式的文件可能下載過程出現損壞還是可以查看的,若是.exe可執行文件下載過程出現損壞就不可執行了),然後啟動tomcat,雙擊bin文件夾下的startup.bat,出現以下的界面
記得不要關閉這個窗體,若關閉了後面的文件下載會出錯的。
Android的布局文件代碼如下:
為了方便,在代碼中寫死了下載路徑。
MainActivity中的代碼如下:
package com.myself.download; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.text.TextUtils; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { protected static final int DOWN_LOAD_ERROR = 1; protected static final int SERVER_ERROR = 2; protected static final int SD_UNABLE = 3; public static final int DOWN_LOAD_FINISH = 4; public static final int UPDATE_TEXT = 5; public static int threadCount = 3; public static int runingThread =3; public int currentProcess=0;//當前的進度 private EditText et_path; private ProgressBar pb; private TextView tv_show; private Handler handler=new Handler(){ public void handleMessage(android.os.Message msg) { switch (msg.what) { case DOWN_LOAD_ERROR: Toast.makeText(MainActivity.this, 下載錯誤, 1).show(); break; case SERVER_ERROR: Toast.makeText(MainActivity.this, 服務器連接錯誤, 1).show(); break; case SD_UNABLE: Toast.makeText(MainActivity.this, SD卡不可用, 1).show(); break; case DOWN_LOAD_FINISH: Toast.makeText(MainActivity.this, 資源下載完畢, 1).show(); break; case UPDATE_TEXT: tv_show.setText(目前下載的進度:+pb.getProgress()*100/pb.getMax()+%); break; default: break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path=(EditText) findViewById(R.id.et_path); pb=(ProgressBar) findViewById(R.id.pb); tv_show=(TextView) findViewById(R.id.tv_show); } public void download(View v){ final String path=et_path.getText().toString().trim(); if(TextUtils.isEmpty(path)){ Toast.makeText(this, 下載路徑不能為空, 1).show(); return ; } new Thread(){ public void run() { // 1.連接服務器,獲取要下載的文件長度,並創建一個跟要下載資源大小一樣的臨時文件 try { //String path = http://172.29.168.1:8088/fengxing.exe; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod(GET); int code = conn.getResponseCode(); System.out.println(code: +code); if (code == 200) { // 服務器返回的數據的長度實際上就是文件的長度 int length = conn.getContentLength(); pb.setMax(length); //System.out.println(文件總長度: + length); //判斷sd卡是否可用 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ //在客戶端創建一個與要下載的資源同樣大小的臨時文件 RandomAccessFile raf=new RandomAccessFile(/sdcard/fengxing.exe, rwd); //設置文件的大小 raf.setLength(length); raf.close(); // 假設是3個線程去下載 // 平均每一個線程下載的資源的大小 int blockSize = length / threadCount; for (int threadId = 1; threadId <= threadCount; threadId++) { // 第一個線程開始下載的位置 int startIndex = (threadId - 1) * blockSize; int endIndex = (threadId * blockSize) - 1; if (threadId == threadCount) {// 最後一個線程下載的資源就是剩下的資源 endIndex = length; } System.out.println(線程+threadId+線程下載的位置: +startIndex+------->+endIndex); new DownlLoad(threadId, startIndex, endIndex, path).start(); } }else{ System.out.println(sd卡不可用...); Message msg=new Message(); msg.what=SD_UNABLE; handler.sendMessage(msg); } } else { System.out.println(服務器連接錯誤...); Message msg=new Message(); msg.what=SERVER_ERROR; handler.sendMessage(msg); } } catch (Exception e) { e.printStackTrace(); Message msg=new Message(); msg.what=DOWN_LOAD_ERROR; handler.sendMessage(msg); } }; }.start(); } /** * 下載文件的子線程 每一個線程下載對應位置的文件 * @author Administrator * */ public class DownlLoad extends Thread{ private int threadId; private int startIndex; private int endIndex; private String path; /** * * @param threadId 線程Id * @param startIndex 開始下載的位置 * @param endIndex 結束位置 * @param path 要下載的資源所在路徑 */ public DownlLoad(int threadId, int startIndex, int endIndex, String path) { this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; this.path = path; } @Override public void run() { try { //檢查是否存在記錄了已經下載長度的文件,若存在則讀取文件的內容 File tempFile=new File(/sdcard/+threadId+.txt); if(tempFile.exists()&&tempFile.length()>0){ FileInputStream fis=new FileInputStream(tempFile); byte[] temp=new byte[1024]; int leng=fis.read(temp); String downloadLen=new String(temp,0,leng); int downloadInt=Integer.parseInt(downloadLen); int alreadyDownInt=downloadInt-startIndex;//已經下載的進度 currentProcess+=alreadyDownInt;//若已經有下載的,重新設置進度 startIndex=downloadInt;//修改下載真實的開始位置 } URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod(GET); //重要:請求服務器下載部分的文件 指定下載的資源范圍 conn.setRequestProperty(Range, bytes=+startIndex+-+endIndex); System.out.println(線程+threadId+線程重新開始下載的位置: +startIndex+------->+endIndex); int code = conn.getResponseCode();//200代表的是全部的資源 206代表的是部分資源 //System.out.println(code:+code); if(code==206){ InputStream is=conn.getInputStream();//已經設置了請求的位置 返回當前位置對應的文件的輸入流 RandomAccessFile raf=new RandomAccessFile(/sdcard/fengxing.exe, rwd); raf.seek(startIndex);//定位開始位置 int len=0; byte[] buff=new byte[1024]; int total=0;//記錄已經下載的文件的長度 while((len=is.read(buff))!=-1){ //FileOutputStream fos=new FileOutputStream(file); RandomAccessFile file=new RandomAccessFile(/sdcard/+threadId+.txt,rwd);//記錄當前線程下載的長度 raf.write(buff, 0, len); total+=len; //System.out.println(線程+threadId+ 下載長度:+total); file.write((+(total+startIndex)).getBytes()); file.close(); //更新進度條 synchronized (MainActivity.this) { currentProcess+=len;//獲取所有線程下載的總進度 pb.setProgress(currentProcess);//更改進度條的進度 Message msg=Message.obtain();//復用舊的消息 msg.what=UPDATE_TEXT; handler.sendMessage(msg); } } is.close(); raf.close(); System.out.println(線程+threadId+下載完畢...); }else{ System.out.println(線程+threadId+下載失敗...); } /*File deleteFile=new File(threadId+.txt); deleteFile.delete();*/ } catch (Exception e) { e.printStackTrace(); } finally{ threadFinish(); } } private synchronized void threadFinish() { //這部分的作用:防止某一個記錄文件在資源下載完後沒有被刪除 runingThread--; if(runingThread==0){ for(int i=1;i<=3;i++){ File file=new File(/sdcard/+i+.txt); file.delete(); } System.out.println(資源已經下載完畢,刪除所有的下載記錄...); Message msg=new Message(); msg.what=DOWN_LOAD_FINISH; handler.sendMessage(msg); } } } }
在下載的過程中,退出程序,然後在打開程序,程序會接著在原來的基礎上繼續下載。
最後打開File Explor中的sdcard,就會發現下載的文件:
Android中UI特效 android經典開源代碼分享 本文原始網址 作者為23code,歡迎給作者投稿 其它UI相關的網址: https://github.co
RecyclerView是什麼?筆者個人看法,RecyclerView只是一個對ListView的升級版,這個升級的主要目的是為了讓這個view的效率更高,並且使用更加方
Notifications in Android 4.4 and Lower notification是很重要的部分,它與service,BroadcastReceive
Statement:This archive is created by William Yi and it’s all the harvests which