利用GreenDao多线程断点续传

来源:互联网 发布:java list 排序 编辑:程序博客网 时间:2024/06/04 18:07

本文参考:

http://blog.csdn.net/inter_native/article/details/78603256

首先要引入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的布局中粘贴

复制代码
<TextView    android:id="@+id/textView"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_alignParentLeft="true"    android:layout_alignParentStart="true"    android:layout_alignParentTop="true"    android:layout_marginLeft="23dp"    android:layout_marginStart="23dp"    android:layout_marginTop="18dp"    android:text="TextView" /><ProgressBar    android:id="@+id/progressBar"    style="?android:attr/progressBarStyleHorizontal"    android:layout_width="fill_parent"    android:layout_height="7.5dp"    android:layout_below="@+id/textView"    android:layout_marginRight="8dp"    android:max="100"    android:progress="100"    android:visibility="visible" /><Button    android:id="@+id/start"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_alignParentBottom="true"    android:layout_toEndOf="@+id/textView"    android:layout_toRightOf="@+id/textView"    android:text="下载" /><Button    android:id="@+id/delete"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_alignParentBottom="true"    android:layout_marginLeft="48dp"    android:layout_marginStart="48dp"    android:layout_toEndOf="@+id/start"    android:layout_toRightOf="@+id/start"    android:text="暂停" />
复制代码

 

 
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<DownloadInfo> 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<DownloadInfo> getInfos(String urlstr) {        List<DownloadInfo> list = new ArrayList<DownloadInfo>();        List<User> 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<DownloadInfo> 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<DownloadInfo>();        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<Void,Void,Void>() {            @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那个包

然后就是权限:

 

<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

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