先看下效果图:
点击下载进度条开始动,实现下载
点击下载后下载按钮变成不可按的状态
暂停按钮变成可按状态
点击暂停后下载按钮再次变成可按状态,点击下载继续续传
下载完成后,下载完成按钮变成可点击,
下载完成后点击下载完成播放下载的视频
下面开始粘代码:
首先我们生成GreenDao
首先我们需要在项目build.gradle中导入包`
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
}
在model倒入依赖:
compile 'org.greenrobot:greendao:3.2.0' compile 'org.greenrobot:greendao-generator:3.2.0'
接着在模块build.gradle的顶部添加
apply plugin: ‘org.greenrobot.greendao’
以及
greendao {
schemaVersion 1
daoPackage 'com.xxxxx.xxx'//这个是生成代码保存的包名
targetGenDir 'src/main/java'//保存到java代码路径
}
同步后就可以使用greenDao。
生成bean
@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;
//下面的都是自动生成
@Generated(hash = 2041931179)
**public** User(Long id, Integer thread\_id, Integer start\_pos, Integer end\_pos,
Integer compelete\_size, String url) {
**this**.**id** \= id;
**this**.**thread\_id** \= thread\_id;
**this**.**start\_pos** \= start\_pos;
**this**.**end\_pos** \= end\_pos;
**this**.**compelete\_size** \= compelete\_size;
**this**.**url** \= url;
}
@Generated(hash = 586692638)
**public** User() {
}
**public** Long getId() {
**return this**.**id**;
}
**public void** setId(Long id) {
**this**.**id** \= id;
}
**public** Integer getThread\_id() {
**return this**.**thread\_id**;
}
**public void** setThread\_id(Integer thread\_id) {
**this**.**thread\_id** \= thread\_id;
}
**public** Integer getStart\_pos() {
**return this**.**start\_pos**;
}
**public void** setStart\_pos(Integer start\_pos) {
**this**.**start\_pos** \= start\_pos;
}
**public** Integer getEnd\_pos() {
**return this**.**end\_pos**;
}
**public void** setEnd\_pos(Integer end\_pos) {
**this**.**end\_pos** \= end\_pos;
}
**public** Integer getCompelete\_size() {
**return this**.**compelete\_size**;
}
**public void** setCompelete\_size(Integer compelete\_size) {
**this**.**compelete\_size** \= compelete\_size;
}
**public** String getUrl() {
**return this**.**url**;
}
**public void** setUrl(String url) {
**this**.**url** \= url;
}
}
自动生成是点击build
就能自动的生成你需要的Dao类和helper类
那么使用之前需要初始化一下
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();
}
}
GreenDao注解:
@Entity 用于标识这是一个需要Greendao帮我们生成代码的bean
@Id 标明主键,括号里可以指定是否自增
@Property 用于设置属性在数据库中的列名(默认不写就是保持一致)
@NotNull 非空
@Transient 标识这个字段是自定义的不会创建到数据库表里
@Unique 添加唯一约束
@ToOne 是将自己的一个属性与另一个表建立关联(外键)
@ToMany的属性referencedJoinProperty,类似于外键约束。
@JoinProperty 对于更复杂的关系,可以使用这个注解标明目标属性的源属性。
------------------------------------------------------------------------------------------------下面说下载的----------------------------------------------------------------------------------------------------------------------
public class DownlaodSqlTool {
/** * 创建下载的具体信息 */ public void insertInfos(List
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();
}
}
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
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 void** loadEnd(){
Toast.makeText(**mContext**,**"加载完成"**,Toast.**_LENGTH\_SHORT_**).show();
}
**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();
}
}
}
}
}
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 + "]";
}
}
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** loadend(){
**mDownloadHttpTool**.loadEnd();
}
**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();
}
}
activity使用
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@BindView(R.id.start)
Button start;
@BindView(R.id.delete)
Button pause;
@BindView(R.id.loadAll)
Button loadAll;
@BindView(R.id.progressBar)
ProgressBar mProgressBar;
@BindView(R.id.textView)
TextView total;
@BindView(R.id.videoview)
VideoView videoview;
**private int** **max**;
**private** DownloadUtil **mDownloadUtil**;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
**total**.setText(**"加载:0%"**);
String urlString = **"http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers\_2010W-480p.mp4"**;
String localPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + **"/local"**;
**mDownloadUtil** \= **new** DownloadUtil(4, 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);
_//textView进度_ **total**.setText((**long**) downloadedSize \* 100 / **mProgressBar**.getMax() + **"%"**);
}
@Override
public void downloadEnd() {
// TODO Auto-generated method stub Log.w(TAG, "ENd");
loadAll.setEnabled(true);
total.setText("加载完成");
}
});
**start**.setOnClickListener(**new** View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub //开始 start.setEnabled(false);
pause.setEnabled(true);
loadAll.setEnabled(false);
mDownloadUtil.start();
}
});
**pause**.setOnClickListener(**new** View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub //按钮可点击状态 start.setEnabled(true);
pause.setEnabled(true);
//暂停 mDownloadUtil.pause();
}
});
**loadAll**.setOnClickListener(**new** View.OnClickListener() {
@Override
public void onClick(View view) {
**mDownloadUtil**.loadend();
_//获取sd卡目录adc.map4文件_ File file = **new** File(Environment.getExternalStorageDirectory(), **"/local/adc.mp4"**);
_//判断目录文件是否存在_ **if** (file.exists()) {
_//视频播放路径_ **videoview**.setVideoPath(file.getPath());
**if** (!**videoview**.isPlaying()) {
_//开始播放_ **videoview**.start();
}
} **else** {
Toast.makeText(MainActivity.**this**, **"文件不存在"**, Toast.**_LENGTH\_SHORT_**).show();
}
}
});
}
}
最后布局也粘出来
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.bwie.wudan20180115.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:orientation="horizontal" > <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下载" /> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:enabled="false" android:text="暂停" /> <Button android:id="@+id/loadAll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:enabled="false" android:text="下载完成" /> LinearLayout>
<**ProgressBar** **android****:id=****"@+id/progressBar"** **style=****"?android:attr/progressBarStyleHorizontal"** **android****:layout\_width=****"fill\_parent"** **android****:layout\_height=****"7.5dp"** **android****:layout\_marginRight=****"8dp"** **android****:layout\_marginLeft=****"8dp"** **android****:max=****"100"** **android****:progress=****"100"** **android****:visibility=****"visible"** />
<**TextView** **android****:id=****"@+id/textView"** **android****:layout\_width=****"wrap\_content"** **android****:layout\_height=****"wrap\_content"** **android****:layout\_gravity=****"center"** **android****:layout\_marginTop=****"8dp"** **android****:text=****"TextView"** />
<**VideoView** **android****:id=****"@+id/videoview"** **android****:layout\_marginTop=****"30dp"** **android****:layout\_width=****"match\_parent"** **android****:layout\_height=****"200dp"** />
</LinearLayout>
手机扫一扫
移动阅读更方便
你可能感兴趣的文章