博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程断点续传GreenDao版
阅读量:5007 次
发布时间:2019-06-12

本文共 16008 字,大约阅读时间需要 53 分钟。

本文参考:

首先要引入GreenDao,具体引用请参考本人的前面的博客,这里就不再写了;

废话完就要开始写了

首先要写一个User类:

@Entity public class User {    @Id    private Long id;    private Integer thread_id;    private Integer start_pos;    private Integer end_pos;    private Integer compelete_size;    private String url;}

到这一步之后不要急不要慌,深呼吸然后运行一下子,看这个类和你的gen包都好了没,方方面面好了之后就开始粘贴下面的代码;

然后就先粘贴布局(这是本人多年粘贴代码的经验,先粘贴布局)

这个布局就非常简单了,在MainActivity的布局中粘贴

 
 

 

 
App
public class App extends Application {    public static UserDao userDao;    @Override    public void onCreate() {        super.onCreate();        DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "lenvess.db", null);        DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());        DaoSession daoSession = daoMaster.newSession();        userDao = daoSession.getUserDao();    }}
DownlaodSqlTool
public class DownlaodSqlTool {    /**     * 创建下载的具体信息     */    public void insertInfos(List
infos) { for (DownloadInfo info : infos) { User user = new User(null, info.getThreadId(), info.getStartPos(), info.getEndPos(), info.getCompeleteSize(), info.getUrl()); userDao.insert(user); } } /** * 得到下载具体信息 */ public List
getInfos(String urlstr) { List
list = new ArrayList
(); List
list1 = userDao.queryBuilder().where(UserDao.Properties.Url.eq(urlstr)).build().list(); for (User user : list1) { DownloadInfo infoss = new DownloadInfo( user.getThread_id(), user.getStart_pos(), user.getEnd_pos(), user.getCompelete_size(), user.getUrl()); Log.d("main-----", infoss.toString()); list.add(infoss); } return list; } /** * 更新数据库中的下载信息 */ public void updataInfos(int threadId, int compeleteSize, String urlstr) { User user = userDao.queryBuilder() .where(UserDao.Properties.Thread_id.eq(threadId), UserDao.Properties.Url.eq(urlstr)).build().unique(); user.setCompelete_size(compeleteSize); userDao.update(user); } /** * 下载完成后删除数据库中的数据 */ public void delete(String url) { userDao.deleteAll(); }}
DownloadHttpTool
public class DownloadHttpTool {    /**     * 利用Http协议进行多线程下载具体实践类     */    private static final String TAG = DownloadHttpTool.class.getSimpleName();    private int threadCount;//线程数量    private String urlstr;//URL地址    private Context mContext;    private Handler mHandler;    private List
downloadInfos;//保存下载信息的类 private String localPath;//目录 private String fileName;//文件名 private int fileSize; private DownlaodSqlTool sqlTool;//文件信息保存的数据库操作类 private enum Download_State { Downloading, Pause, Ready;//利用枚举表示下载的三种状态 } private Download_State state = Download_State.Ready;//当前下载状态 private int globalCompelete = 0;//所有线程下载的总数 public DownloadHttpTool(int threadCount, String urlString, String localPath, String fileName, Context context, Handler handler) { super(); this.threadCount = threadCount; this.urlstr = urlString; this.localPath = localPath; this.mContext = context; this.mHandler = handler; this.fileName = fileName; sqlTool = new DownlaodSqlTool(); } //在开始下载之前需要调用ready方法进行配置 public void ready() { Log.w(TAG, "ready"); globalCompelete = 0; downloadInfos = sqlTool.getInfos(urlstr); if (downloadInfos.size() == 0) { initFirst(); } else { File file = new File(localPath + "/" + fileName); if (!file.exists()) { sqlTool.delete(urlstr); initFirst(); } else { fileSize = downloadInfos.get(downloadInfos.size() - 1) .getEndPos(); for (DownloadInfo info : downloadInfos) { globalCompelete += info.getCompeleteSize(); } Log.w(TAG, "globalCompelete:::" + globalCompelete); } } } public void start() { Log.w(TAG, "start"); if (downloadInfos != null) { if (state == Download_State.Downloading) { return; } state = Download_State.Downloading; for (DownloadInfo info : downloadInfos) { Log.v(TAG, "startThread"); new DownloadThread(info.getThreadId(), info.getStartPos(), info.getEndPos(), info.getCompeleteSize(), info.getUrl()).start(); } } } public void pause() { state = Download_State.Pause; } public void delete() { compelete(); File file = new File(localPath + "/" + fileName); file.delete(); } public void compelete() { sqlTool.delete(urlstr); } public int getFileSize() { return fileSize; } public int getCompeleteSize() { return globalCompelete; } //第一次下载初始化 private void initFirst() { Log.w(TAG, "initFirst"); try { URL url = new URL(urlstr); HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setConnectTimeout(5000); connection.setRequestMethod("GET"); fileSize = connection.getContentLength(); Log.w(TAG, "fileSize::" + fileSize); File fileParent = new File(localPath); if (!fileParent.exists()) { fileParent.mkdir(); } File file = new File(fileParent, fileName); if (!file.exists()) { file.createNewFile(); } // 本地访问文件 RandomAccessFile accessFile = new RandomAccessFile(file, "rwd"); accessFile.setLength(fileSize); accessFile.close(); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } int range = fileSize / threadCount; downloadInfos = new ArrayList
(); for (int i = 0; i < threadCount - 1; i++) { DownloadInfo info = new DownloadInfo(i, i * range, (i + 1) * range - 1, 0, urlstr); downloadInfos.add(info); } DownloadInfo info = new DownloadInfo(threadCount - 1, (threadCount - 1) * range, fileSize - 1, 0, urlstr); downloadInfos.add(info); sqlTool.insertInfos(downloadInfos); } //自定义下载线程 private class DownloadThread extends Thread { private int threadId; private int startPos; private int endPos; private int compeleteSize; private String urlstr; private int totalThreadSize; public DownloadThread(int threadId, int startPos, int endPos, int compeleteSize, String urlstr) { this.threadId = threadId; this.startPos = startPos; this.endPos = endPos; totalThreadSize = endPos - startPos + 1; this.urlstr = urlstr; this.compeleteSize = compeleteSize; } @Override public void run() { HttpURLConnection connection = null; RandomAccessFile randomAccessFile = null; InputStream is = null; try { randomAccessFile = new RandomAccessFile(localPath + "/" + fileName, "rwd"); randomAccessFile.seek(startPos + compeleteSize); URL url = new URL(urlstr); connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(5000); connection.setRequestMethod("GET"); connection.setRequestProperty("Range", "bytes=" + (startPos + compeleteSize) + "-" + endPos); is = connection.getInputStream(); byte[] buffer = new byte[1024]; int length = -1; while ((length = is.read(buffer)) != -1) { randomAccessFile.write(buffer, 0, length); compeleteSize += length; Message message = Message.obtain(); message.what = threadId; message.obj = urlstr; message.arg1 = length; mHandler.sendMessage(message); sqlTool.updataInfos(threadId, compeleteSize, urlstr); Log.w(TAG, "Threadid::" + threadId + " compelete::" + compeleteSize + " total::" + totalThreadSize); if (compeleteSize >= totalThreadSize) { break; } if (state != Download_State.Downloading) { break; } } } catch (Exception e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } randomAccessFile.close(); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } } } }}
DownloadInfo
public class DownloadInfo {    /**     * 保存每个下载线程下载信息类     *     */    private int threadId;// 下载器id    private int startPos;// 开始点    private int endPos;// 结束点    private int compeleteSize;// 完成度    private String url;// 下载文件的URL地址    public DownloadInfo(int threadId, int startPos, int endPos,                        int compeleteSize, String url) {        this.threadId = threadId;        this.startPos = startPos;        this.endPos = endPos;        this.compeleteSize = compeleteSize;        this.url = url;    }    public DownloadInfo() {    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }    public int getThreadId() {        return threadId;    }    public void setThreadId(int threadId) {        this.threadId = threadId;    }    public int getStartPos() {        return startPos;    }    public void setStartPos(int startPos) {        this.startPos = startPos;    }    public int getEndPos() {        return endPos;    }    public void setEndPos(int endPos) {        this.endPos = endPos;    }    public int getCompeleteSize() {        return compeleteSize;    }    public void setCompeleteSize(int compeleteSize) {        this.compeleteSize = compeleteSize;    }    @Override    public String toString() {        return "DownloadInfo [threadId=" + threadId + ", startPos=" + startPos                + ", endPos=" + endPos + ", compeleteSize=" + compeleteSize                + "]";    }}
DownloadUtil
public class DownloadUtil {    private DownloadHttpTool mDownloadHttpTool;    private OnDownloadListener onDownloadListener;    private int fileSize;    private int downloadedSize = 0;    @SuppressLint("HandlerLeak")    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            // TODO Auto-generated method stub            super.handleMessage(msg);            int length = msg.arg1;            synchronized (this) {
//加锁保证已下载的正确性 downloadedSize += length; } if (onDownloadListener != null) { onDownloadListener.downloadProgress(downloadedSize); } if (downloadedSize >= fileSize) { mDownloadHttpTool.compelete(); if (onDownloadListener != null) { onDownloadListener.downloadEnd(); } } } }; public DownloadUtil(int threadCount, String filePath, String filename, String urlString, Context context) { mDownloadHttpTool = new DownloadHttpTool(threadCount, urlString, filePath, filename, context, mHandler); } //下载之前首先异步线程调用ready方法获得文件大小信息,之后调用开始方法 public void start() { new AsyncTask
() { @Override protected Void doInBackground(Void... arg0) { // TODO Auto-generated method stub mDownloadHttpTool.ready(); return null; } @Override protected void onPostExecute(Void result) { // TODO Auto-generated method stub super.onPostExecute(result); fileSize = mDownloadHttpTool.getFileSize(); downloadedSize = mDownloadHttpTool.getCompeleteSize(); Log.w("Tag", "downloadedSize::" + downloadedSize); if (onDownloadListener != null) { onDownloadListener.downloadStart(fileSize); } mDownloadHttpTool.start(); } }.execute(); } public void pause() { mDownloadHttpTool.pause(); } public void delete(){ mDownloadHttpTool.delete(); } public void reset(){ mDownloadHttpTool.delete(); start(); } public void setOnDownloadListener(OnDownloadListener onDownloadListener) { this.onDownloadListener = onDownloadListener; } //下载回调接口 public interface OnDownloadListener { public void downloadStart(int fileSize); public void downloadProgress(int downloadedSize);//记录当前所有线程下总和 public void downloadEnd(); }}
MainActivity(!!注意,注意这是MainActivity不是自己创的类,不要粘贴错了)
public class MainActivity extends AppCompatActivity {    private static final String TAG = MainActivity.class.getSimpleName();    private ProgressBar mProgressBar;    private Button start;    private Button pause;    private TextView total;    private int max;    private DownloadUtil mDownloadUtil;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        total = (TextView) findViewById(R.id.textView);        start = (Button) findViewById(R.id.start);        pause = (Button) findViewById(R.id.delete);        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);        String urlString = "http://2449.vod.myqcloud.com/2449_22ca37a6ea9011e5acaaf51d105342e3.f20.mp4";        String localPath = Environment.getExternalStorageDirectory()                .getAbsolutePath() + "/local2";        mDownloadUtil = new DownloadUtil(2, localPath, "adc.mp4", urlString,                this);        mDownloadUtil.setOnDownloadListener(new DownloadUtil.OnDownloadListener() {            @Override            public void downloadStart(int fileSize) {                // TODO Auto-generated method stub                Log.w(TAG, "fileSize::" + fileSize);                max = fileSize;                mProgressBar.setMax(fileSize);            }            @Override            public void downloadProgress(int downloadedSize) {                // TODO Auto-generated method stub                Log.w(TAG, "Compelete::" + downloadedSize);                mProgressBar.setProgress(downloadedSize);                total.setText((int) downloadedSize * 100 / max + "%");            }            @Override            public void downloadEnd() {                // TODO Auto-generated method stub                Log.w(TAG, "ENd");            }        });        start.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View arg0) {                // TODO Auto-generated method stub                mDownloadUtil.start();            }        });        pause.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View arg0) {                // TODO Auto-generated method stub                mDownloadUtil.pause();            }        });    }}

这样代码方面就完事了;如果有报错一般是Handler的事这个千万记的倒OS那个包

然后就是权限:

 

 如果运行了还报错,可能是你的App没有配,不要慌,仔细检查

转载于:https://www.cnblogs.com/cainiaodongdong/p/7880723.html

你可能感兴趣的文章
利用Clojure统计代码文件数量和代码行数
查看>>
课时23:递归:这帮小兔崽子
查看>>
RobotFrameWork接口报文测试-----(三)demo的加强版(数据驱动测试)
查看>>
NetBeansRCP-添加/修改NetBeans的JVM启动参数
查看>>
Linux c获取时间
查看>>
css中设置background属性
查看>>
第九周作业
查看>>
[leedcode 70] Climbing Stairs
查看>>
学习 WCF (1)--基础篇
查看>>
sql server 2008学习4 设计索引的建议
查看>>
vim 插件之vundle
查看>>
数据库多对多关联表(Python&MySQL)
查看>>
[实变函数]1.2 集合的运算
查看>>
第06天
查看>>
设计模式的征途—5.原型(Prototype)模式
查看>>
Fiddler中添加serverIP
查看>>
mysql的某个数据库拒绝访问的问题
查看>>
C# ~ 从 XML 到 Linq 到 Linq to XML
查看>>
常用汉字的五笔拆法
查看>>
1044: [HAOI2008]木棍分割 - BZOJ
查看>>