完善下载

This commit is contained in:
lyy
2016-10-07 19:30:55 +08:00
parent cb9188423f
commit 9c2015c90b
23 changed files with 337 additions and 93 deletions

11
.idea/gradle.xml generated
View File

@ -3,8 +3,9 @@
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" /> <option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" /> <option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="C:\Android Studio\gradle\gradle-2.14.1" />
<option name="modules"> <option name="modules">
<set> <set>
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
@ -12,13 +13,7 @@
<option value="$PROJECT_DIR$/downloadutil" /> <option value="$PROJECT_DIR$/downloadutil" />
</set> </set>
</option> </option>
<option name="myModules"> <option name="resolveModulePerSourceSet" value="false" />
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/downloadutil" />
</set>
</option>
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>

View File

@ -0,0 +1,10 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintStaticFieldLeak" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
</inspection_tool>
</profile>
</component>

View File

@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Project Default" />
<option name="USE_PROJECT_PROFILE" value="true" />
<version value="1.0" />
</settings>
</component>

2
.idea/misc.xml generated
View File

@ -37,7 +37,7 @@
<ConfirmationsSetting value="0" id="Add" /> <ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" /> <ConfirmationsSetting value="0" id="Remove" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View File

@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application <application
android:name=".base.BaseApplication" android:name=".base.BaseApplication"
android:allowBackup="true" android:allowBackup="true"
@ -12,8 +13,9 @@
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<!--android:name=".activity.SimpleTestActivity"-->
<activity <activity
android:name=".activity.SimpleTestActivity" android:name=".activity.MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>

View File

@ -1,9 +1,15 @@
package com.arialyy.simple.activity; package com.arialyy.simple.activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import com.arialyy.downloadutil.core.DownloadManager;
import com.arialyy.downloadutil.entity.DownloadEntity;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R; import com.arialyy.simple.R;
import com.arialyy.simple.adapter.DownloadAdapter; import com.arialyy.simple.adapter.DownloadAdapter;
import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.base.BaseActivity;
@ -29,4 +35,56 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> {
mList.setLayoutManager(new LinearLayoutManager(this)); mList.setLayoutManager(new LinearLayoutManager(this));
mList.setAdapter(mAdapter); mList.setAdapter(mAdapter);
} }
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
long len = 0;
@Override public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
DownloadEntity entity = intent.getParcelableExtra(DownloadManager.ENTITY);
switch (action) {
case DownloadManager.ACTION_PRE:
len = entity.getFileSize();
L.d(TAG, "download pre");
break;
case DownloadManager.ACTION_START:
L.d(TAG, "download start");
break;
case DownloadManager.ACTION_RESUME:
L.d(TAG, "download resume");
long location = intent.getLongExtra(DownloadManager.CURRENT_LOCATION, 1);
mAdapter.updateState(entity);
break;
case DownloadManager.ACTION_RUNNING:
long current = intent.getLongExtra(DownloadManager.CURRENT_LOCATION, 0);
mAdapter.setProgress(entity.getDownloadUrl(), current);
break;
case DownloadManager.ACTION_STOP:
L.d(TAG, "download stop");
mAdapter.updateState(entity);
break;
case DownloadManager.ACTION_COMPLETE:
L.d(TAG, "download complete");
mAdapter.updateState(entity);
break;
case DownloadManager.ACTION_CANCEL:
L.d(TAG, "download cancel");
break;
case DownloadManager.ACTION_FAIL:
L.d(TAG, "download fail");
break;
}
}
};
@Override protected void onResume() {
super.onResume();
registerReceiver(mReceiver, getModule(DownloadModule.class).getDownloadFilter());
}
@Override protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
} }

View File

@ -103,7 +103,7 @@ public class SimpleTestActivity extends BaseActivity<ActivitySimpleBinding> {
String action = intent.getAction(); String action = intent.getAction();
switch (action) { switch (action) {
case DownloadManager.ACTION_PRE: case DownloadManager.ACTION_PRE:
DownloadEntity entity = intent.getParcelableExtra(DownloadManager.ACTION_PRE); DownloadEntity entity = intent.getParcelableExtra(DownloadManager.ENTITY);
len = entity.getFileSize(); len = entity.getFileSize();
L.d(TAG, "download pre"); L.d(TAG, "download pre");
mUpdateHandler.obtainMessage(DOWNLOAD_PRE, len).sendToTarget(); mUpdateHandler.obtainMessage(DOWNLOAD_PRE, len).sendToTarget();
@ -117,7 +117,7 @@ public class SimpleTestActivity extends BaseActivity<ActivitySimpleBinding> {
mUpdateHandler.obtainMessage(DOWNLOAD_RESUME, location).sendToTarget(); mUpdateHandler.obtainMessage(DOWNLOAD_RESUME, location).sendToTarget();
break; break;
case DownloadManager.ACTION_RUNNING: case DownloadManager.ACTION_RUNNING:
long current = intent.getLongExtra(DownloadManager.ACTION_RUNNING, 0); long current = intent.getLongExtra(DownloadManager.CURRENT_LOCATION, 0);
if (len == 0) { if (len == 0) {
mPb.setProgress(0); mPb.setProgress(0);
} else { } else {

View File

@ -1,16 +1,21 @@
package com.arialyy.simple.adapter; package com.arialyy.simple.adapter;
import android.content.Context; import android.content.Context;
import android.util.SparseArray; import android.util.SparseIntArray;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import com.arialyy.absadapter.common.AbsHolder; import com.arialyy.absadapter.common.AbsHolder;
import com.arialyy.absadapter.recycler_view.AbsRVAdapter; import com.arialyy.absadapter.recycler_view.AbsRVAdapter;
import com.arialyy.downloadutil.core.DownloadManager;
import com.arialyy.downloadutil.core.command.CommandFactory;
import com.arialyy.downloadutil.core.command.IDownloadCommand;
import com.arialyy.downloadutil.entity.DownloadEntity; import com.arialyy.downloadutil.entity.DownloadEntity;
import com.arialyy.downloadutil.util.Util;
import com.arialyy.simple.R; import com.arialyy.simple.R;
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber; import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -23,17 +28,21 @@ import butterknife.Bind;
*/ */
public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapter.MyHolder> { public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapter.MyHolder> {
private static final String TAG = "DownloadAdapter"; private static final String TAG = "DownloadAdapter";
private DownloadManager mManager;
private CommandFactory mFactory;
private Map<String, Long> mProgress = new HashMap<>(); private Map<String, Long> mProgress = new HashMap<>();
private SparseArray<String> mPositions = new SparseArray<>(); private SparseIntArray mPositions = new SparseIntArray();
public DownloadAdapter(Context context, List<DownloadEntity> data) { public DownloadAdapter(Context context, List<DownloadEntity> data) {
super(context, data); super(context, data);
int i = 0; int i = 0;
for (DownloadEntity entity : data) { for (DownloadEntity entity : data) {
mProgress.put(entity.getDownloadUrl(), entity.getCurrentProgress()); mProgress.put(entity.getDownloadUrl(), entity.getCurrentProgress());
mPositions.append(i, entity.getDownloadUrl()); mPositions.append(i, Util.keyToHashCode(entity.getDownloadUrl()));
i++; i++;
} }
mFactory = CommandFactory.getInstance();
mManager = DownloadManager.getInstance();
} }
@Override protected MyHolder getViewHolder(View convertView, int viewType) { @Override protected MyHolder getViewHolder(View convertView, int viewType) {
@ -44,13 +53,17 @@ public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapte
return R.layout.item_download; return R.layout.item_download;
} }
public synchronized void updateState(DownloadEntity entity) {
notifyItemChanged(indexItem(entity.getDownloadUrl()));
}
public synchronized void setProgress(String url, long currentPosition) { public synchronized void setProgress(String url, long currentPosition) {
mProgress.put(url, currentPosition); mProgress.put(url, currentPosition);
notifyItemChanged(indexItem(url)); notifyItemChanged(indexItem(url));
} }
private int indexItem(String url) { private int indexItem(String url) {
return mPositions.indexOfValue(url); return mPositions.indexOfValue(Util.keyToHashCode(url));
} }
@Override protected void bindData(MyHolder holder, int position, DownloadEntity item) { @Override protected void bindData(MyHolder holder, int position, DownloadEntity item) {
@ -62,13 +75,80 @@ public class DownloadAdapter extends AbsRVAdapter<DownloadEntity, DownloadAdapte
} }
current = (int) (mProgress.get(item.getDownloadUrl()) * 100 / item.getFileSize()); current = (int) (mProgress.get(item.getDownloadUrl()) * 100 / item.getFileSize());
holder.progress.setProgress(current); holder.progress.setProgress(current);
BtClickListener listener = (BtClickListener) holder.bt.getTag(holder.bt.getId());
if (listener == null) {
listener = new BtClickListener(item);
holder.bt.setTag(holder.bt.getId(), listener);
}
holder.bt.setOnClickListener(listener);
String str = "";
switch (item.getState()) {
case DownloadEntity.STATE_WAIT:
case DownloadEntity.STATE_OTHER:
case DownloadEntity.STATE_FAIL:
str = "开始";
break;
case DownloadEntity.STATE_STOP:
str = "恢复";
break;
case DownloadEntity.STATE_DOWNLOAD_ING:
str = "暂停";
break;
}
holder.bt.setText(str);
}
private class BtClickListener implements View.OnClickListener {
private DownloadEntity entity;
BtClickListener(DownloadEntity entity) {
this.entity = entity;
}
@Override public void onClick(View v) {
switch (entity.getState()) {
case DownloadEntity.STATE_WAIT:
case DownloadEntity.STATE_OTHER:
case DownloadEntity.STATE_FAIL:
case DownloadEntity.STATE_STOP:
start(entity);
break;
case DownloadEntity.STATE_DOWNLOAD_ING:
stop(entity);
break;
}
}
private void start(DownloadEntity entity) {
List<IDownloadCommand> commands = new ArrayList<>();
IDownloadCommand addCommand = mFactory.createCommand(getContext(), entity,
CommandFactory.TASK_CREATE);
IDownloadCommand startCommand = mFactory.createCommand(getContext(), entity,
CommandFactory.TASK_START);
commands.add(addCommand);
commands.add(startCommand);
mManager.setCommands(commands).exe();
}
private void stop(DownloadEntity entity) {
IDownloadCommand stopCommand = mFactory.createCommand(getContext(), entity,
CommandFactory.TASK_STOP);
mManager.setCommand(stopCommand).exe();
}
private void cancel(DownloadEntity entity) {
IDownloadCommand cancelCommand = mFactory.createCommand(getContext(), entity,
CommandFactory.TASK_CANCEL);
mManager.setCommand(cancelCommand).exe();
}
} }
class MyHolder extends AbsHolder { class MyHolder extends AbsHolder {
@Bind(R.id.progressBar) HorizontalProgressBarWithNumber progress; @Bind(R.id.progressBar) HorizontalProgressBarWithNumber progress;
@Bind(R.id.bt) Button bt; @Bind(R.id.bt) Button bt;
public MyHolder(View itemView) { MyHolder(View itemView) {
super(itemView); super(itemView);
} }
} }

View File

@ -6,11 +6,13 @@ import android.os.Environment;
import com.arialyy.downloadutil.core.DownloadManager; import com.arialyy.downloadutil.core.DownloadManager;
import com.arialyy.downloadutil.entity.DownloadEntity; import com.arialyy.downloadutil.entity.DownloadEntity;
import com.arialyy.downloadutil.util.Util;
import com.arialyy.frame.util.AndroidUtils; import com.arialyy.frame.util.AndroidUtils;
import com.arialyy.frame.util.StringUtil; import com.arialyy.frame.util.StringUtil;
import com.arialyy.simple.R; import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseModule; import com.arialyy.simple.base.BaseModule;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -24,14 +26,23 @@ public class DownloadModule extends BaseModule {
/** /**
* 设置下载数据 * 设置下载数据
*
* @return * @return
*/ */
public List<DownloadEntity> getDownloadData() { public List<DownloadEntity> getDownloadData() {
List<DownloadEntity> list = DownloadEntity.findAllData(DownloadEntity.class);
if (list == null) {
list = createNewDownload();
}
return list;
}
private List<DownloadEntity> createNewDownload() {
List<DownloadEntity> list = new ArrayList<>(); List<DownloadEntity> list = new ArrayList<>();
String[] urls = getContext().getResources() String[] urls = getContext().getResources()
.getStringArray(R.array.test_apk_download_url); .getStringArray(R.array.test_apk_download_url);
for (String url : urls) { for (String url : urls) {
String fileName = StringUtil.keyToHashKey(url) + ".apk"; String fileName = Util.keyToHashCode(url) + ".apk";
DownloadEntity entity = new DownloadEntity(); DownloadEntity entity = new DownloadEntity();
entity.setDownloadUrl(url); entity.setDownloadUrl(url);
entity.setDownloadPath(getDownloadPath(url)); entity.setDownloadPath(getDownloadPath(url));
@ -43,6 +54,7 @@ public class DownloadModule extends BaseModule {
/** /**
* 下载广播过滤器 * 下载广播过滤器
*
* @return * @return
*/ */
public IntentFilter getDownloadFilter() { public IntentFilter getDownloadFilter() {
@ -60,7 +72,13 @@ public class DownloadModule extends BaseModule {
} }
private String getDownloadPath(String url) { private String getDownloadPath(String url) {
return Environment.getExternalStorageDirectory().getPath() + "/" + AndroidUtils.getAppName( String path = Environment.getExternalStorageDirectory()
getContext()) + "downloads/" + StringUtil.keyToHashKey(url) + ".apk"; .getPath() + "/" + AndroidUtils.getAppName(getContext()) + "downloads/" + StringUtil
.keyToHashKey(url) + ".apk";
File file = new File(path);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
return path;
} }
} }

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <layout
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -5,5 +5,8 @@
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item> <item name="android:statusBarColor">@android:color/transparent</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style> </style>
</resources> </resources>

View File

@ -4,9 +4,9 @@
<string-array name="test_apk_download_url"> <string-array name="test_apk_download_url">
<item>http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk</item> <!--300M的文件--> <item>http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk</item> <!--300M的文件-->
<item>http://static.gaoshouyou.com/d/21/e8/61218d78d0e8b79df68dbc18dd484c97.apk</item> <!--<item>http://static.gaoshouyou.com/d/21/e8/61218d78d0e8b79df68dbc18dd484c97.apk</item>-->
<item>http://static.gaoshouyou.com/d/12/0d/7f120f50c80d2e7b8c4ba24ece4f9cdd.apk</item> <!--<item>http://static.gaoshouyou.com/d/12/0d/7f120f50c80d2e7b8c4ba24ece4f9cdd.apk</item>-->
<item>http://static.gaoshouyou.com/d/d4/4f/d6d48db3794fb9ecf47e83c346570881.apk</item> <!--<item>http://static.gaoshouyou.com/d/d4/4f/d6d48db3794fb9ecf47e83c346570881.apk</item>-->
<!--<item>http://static.gaoshouyou.com/d/18/cf/ba18113bc6cf56c1c5863e761e717003.apk</item>--> <!--<item>http://static.gaoshouyou.com/d/18/cf/ba18113bc6cf56c1c5863e761e717003.apk</item>-->
<!--<item>http://static.gaoshouyou.com/d/60/17/2460921367173ea7145f11194a6f2587.apk</item>--> <!--<item>http://static.gaoshouyou.com/d/60/17/2460921367173ea7145f11194a6f2587.apk</item>-->
<!--<item>http://static.gaoshouyou.com/d/32/e0/1a32123ecbe0ee010d35479df248f90f.apk</item>--> <!--<item>http://static.gaoshouyou.com/d/32/e0/1a32123ecbe0ee010d35479df248f90f.apk</item>-->

View File

@ -11,6 +11,9 @@
<style name="AppTheme.NoActionBar"> <style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style> </style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/> <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>

View File

@ -6,7 +6,7 @@ buildscript {
} }
dependencies { dependencies {
// classpath 'com.android.tools.build:gradle:2.1.0' // classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.android.tools.build:gradle:1.5.0' classpath 'com.android.tools.build:gradle:2.2.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1" classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View File

@ -8,6 +8,7 @@ import com.arialyy.downloadutil.core.command.IDownloadCommand;
import com.arialyy.downloadutil.entity.DownloadEntity; import com.arialyy.downloadutil.entity.DownloadEntity;
import com.arialyy.downloadutil.orm.DbEntity; import com.arialyy.downloadutil.orm.DbEntity;
import com.arialyy.downloadutil.orm.DbUtil; import com.arialyy.downloadutil.orm.DbUtil;
import com.arialyy.downloadutil.util.Task;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -63,7 +64,7 @@ public class DownloadManager {
/** /**
* 下载实体 * 下载实体
*/ */
public static final String DATA = "DOWNLOAD_ENTITY"; public static final String ENTITY = "DOWNLOAD_ENTITY";
/** /**
* 位置 * 位置

View File

@ -48,9 +48,14 @@ public class DownloadTarget extends IDownloadTarget {
} }
@Override public void stopTask(Task task) { @Override public void stopTask(Task task) {
if (task.isDownloading()) {
if (mExecutePool.removeTask(task)) { if (mExecutePool.removeTask(task)) {
task.stop(); task.stop();
} }
}else {
task.stop();
Log.w(TAG, "停止任务失败,【任务已经停止】");
}
} }
@Override public void cancelTask(Task task) { @Override public void cancelTask(Task task) {

View File

@ -98,6 +98,14 @@ public abstract class IDownloadTarget implements IDownloader, ITask {
this.mTargetListener = targetListener; this.mTargetListener = targetListener;
} }
/**
* 获取任务执行池
* @return
*/
public ExecutePool getExecutePool(){
return mExecutePool;
}
/** /**
* 获取当前运行的任务数 * 获取当前运行的任务数
* *

View File

@ -3,8 +3,8 @@ package com.arialyy.downloadutil.core.command;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import com.arialyy.downloadutil.util.Task;
import com.arialyy.downloadutil.entity.DownloadEntity; import com.arialyy.downloadutil.entity.DownloadEntity;
import com.arialyy.downloadutil.util.Task;
/** /**
* Created by lyy on 2016/9/20. * Created by lyy on 2016/9/20.
@ -22,10 +22,15 @@ class StopCommand extends IDownloadCommand {
@Override public void executeComment() { @Override public void executeComment() {
Task task = target.getTask(mEntity); Task task = target.getTask(mEntity);
if (task != null) { if (task == null) {
if (mEntity.getState() == DownloadEntity.STATE_DOWNLOAD_ING) {
task = target.createTask(mEntity);
target.stopTask(task); target.stopTask(task);
} else { } else {
Log.w(TAG, "停止命令执行失败,【调度器中没有该任务】"); Log.w(TAG, "停止命令执行失败,【调度器中没有该任务】");
} }
} else {
target.stopTask(task);
}
} }
} }

View File

@ -23,7 +23,7 @@ public class DbEntity {
/** /**
* 获取所有行的rowid * 获取所有行的rowid
*/ */
public int[] getRowId() { public int[] getRowIds() {
return mUtil.getRowId(getClass()); return mUtil.getRowId(getClass());
} }
@ -71,6 +71,18 @@ public class DbEntity {
* 查找数据在表中是否存在 * 查找数据在表中是否存在
*/ */
private boolean thisIsExist() { private boolean thisIsExist() {
return findData(getClass(), new String[]{"rowid"}, new String[]{rowID + ""}) != null;
}
/**
* 插入数据
*/
public void insert() {
mUtil.insertData(this);
updateRowID();
}
private void updateRowID() {
try { try {
Field[] fields = Util.getFields(getClass()); Field[] fields = Util.getFields(getClass());
List<String> where = new ArrayList<>(); List<String> where = new ArrayList<>();
@ -84,19 +96,14 @@ public class DbEntity {
where.add(field.getName()); where.add(field.getName());
values.add(field.get(this) + ""); values.add(field.get(this) + "");
} }
return findData(getClass(), where.toArray(new String[where.size()]), DbEntity entity = findData(getClass(), where.toArray(new String[where.size()]),
values.toArray(new String[values.size()])) != null; values.toArray(new String[values.size()]));
if (entity != null) {
rowID = entity.rowID;
}
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
return false;
}
/**
* 插入数据
*/
public void insert() {
mUtil.insertData(this);
} }
/** /**

View File

@ -62,7 +62,7 @@ public class DbUtil {
/** /**
* 删除某条数据 * 删除某条数据
*/ */
protected <T extends DbEntity> void delData(Class<T> clazz, @NonNull Object[] wheres, <T extends DbEntity> void delData(Class<T> clazz, @NonNull Object[] wheres,
@NonNull Object[] values) { @NonNull Object[] values) {
mDb = mHelper.getWritableDatabase(); mDb = mHelper.getWritableDatabase();
if (wheres.length <= 0 || values.length <= 0) { if (wheres.length <= 0 || values.length <= 0) {
@ -88,7 +88,7 @@ public class DbUtil {
/** /**
* 修改某行数据 * 修改某行数据
*/ */
protected void modifyData(DbEntity dbEntity) { void modifyData(DbEntity dbEntity) {
mDb = mHelper.getWritableDatabase(); mDb = mHelper.getWritableDatabase();
Class<?> clazz = dbEntity.getClass(); Class<?> clazz = dbEntity.getClass();
Field[] fields = Util.getFields(clazz); Field[] fields = Util.getFields(clazz);
@ -113,6 +113,7 @@ public class DbUtil {
} }
i++; i++;
} }
sb.append(" where rowid=").append(dbEntity.rowID);
print(MODIFY_DATA, sb.toString()); print(MODIFY_DATA, sb.toString());
mDb.execSQL(sb.toString()); mDb.execSQL(sb.toString());
} }
@ -122,7 +123,10 @@ public class DbUtil {
/** /**
* 遍历所有数据 * 遍历所有数据
*/ */
protected <T extends DbEntity> List<T> findAllData(Class<T> clazz) { <T extends DbEntity> List<T> findAllData(Class<T> clazz) {
if (!tableExists(clazz)) {
createTable(clazz);
}
mDb = mHelper.getReadableDatabase(); mDb = mHelper.getReadableDatabase();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("SELECT rowid, * FROM ").append(Util.getClassName(clazz)); sb.append("SELECT rowid, * FROM ").append(Util.getClassName(clazz));
@ -134,7 +138,7 @@ public class DbUtil {
/** /**
* 条件查寻数据 * 条件查寻数据
*/ */
protected <T extends DbEntity> List<T> findData(Class<T> clazz, @NonNull String[] wheres, <T extends DbEntity> List<T> findData(Class<T> clazz, @NonNull String[] wheres,
@NonNull String[] values) { @NonNull String[] values) {
if (!tableExists(clazz)) { if (!tableExists(clazz)) {
createTable(clazz); createTable(clazz);
@ -163,7 +167,7 @@ public class DbUtil {
/** /**
* 插入数据 * 插入数据
*/ */
protected void insertData(DbEntity dbEntity) { void insertData(DbEntity dbEntity) {
Class<?> clazz = dbEntity.getClass(); Class<?> clazz = dbEntity.getClass();
if (!tableExists(clazz)) { if (!tableExists(clazz)) {
createTable(clazz); createTable(clazz);
@ -211,7 +215,7 @@ public class DbUtil {
/** /**
* 查找某张表是否存在 * 查找某张表是否存在
*/ */
public synchronized boolean tableExists(Class clazz) { synchronized boolean tableExists(Class clazz) {
if (mDb == null || !mDb.isOpen()) { if (mDb == null || !mDb.isOpen()) {
mDb = mHelper.getReadableDatabase(); mDb = mHelper.getReadableDatabase();
} }
@ -326,7 +330,7 @@ public class DbUtil {
/** /**
* 获取所在行Id * 获取所在行Id
*/ */
protected int[] getRowId(Class clazz) { int[] getRowId(Class clazz) {
mDb = mHelper.getReadableDatabase(); mDb = mHelper.getReadableDatabase();
Cursor cursor = mDb.rawQuery("SELECT rowid, * FROM " + Util.getClassName(clazz), null); Cursor cursor = mDb.rawQuery("SELECT rowid, * FROM " + Util.getClassName(clazz), null);
int[] ids = new int[cursor.getCount()]; int[] ids = new int[cursor.getCount()];
@ -343,7 +347,7 @@ public class DbUtil {
/** /**
* 获取行Id * 获取行Id
*/ */
protected int getRowId(Class clazz, Object[] wheres, Object[] values) { int getRowId(Class clazz, Object[] wheres, Object[] values) {
mDb = mHelper.getReadableDatabase(); mDb = mHelper.getReadableDatabase();
if (wheres.length <= 0 || values.length <= 0) { if (wheres.length <= 0 || values.length <= 0) {
Log.e(TAG, "请输入删除条件"); Log.e(TAG, "请输入删除条件");
@ -404,7 +408,6 @@ public class DbUtil {
} else if (type == byte[].class) { } else if (type == byte[].class) {
field.set(entity, cursor.getBlob(column)); field.set(entity, cursor.getBlob(column));
} }
// field.set(entity, cursor.getColumnIndex("entity_id"));
} }
entity.rowID = cursor.getInt(cursor.getColumnIndex("rowid")); entity.rowID = cursor.getInt(cursor.getColumnIndex("rowid"));
entitys.add(entity); entitys.add(entity);

View File

@ -55,6 +55,16 @@ public class Task {
public void stop() { public void stop() {
if (mUtil.isDownloading()) { if (mUtil.isDownloading()) {
mUtil.stopDownload(); mUtil.stopDownload();
} else {
mEntity.setState(DownloadEntity.STATE_STOP);
mEntity.save();
sendInState2Target(IDownloadTarget.STOP);
// 发送停止下载的广播
Intent intent = createIntent(DownloadManager.ACTION_STOP);
intent.putExtra(DownloadManager.CURRENT_LOCATION, mEntity.getCurrentProgress());
intent.putExtra(DownloadManager.ENTITY, mEntity);
mContext.sendBroadcast(intent);
} }
} }
@ -84,40 +94,61 @@ public class Task {
mUtil.delConfigFile(); mUtil.delConfigFile();
mUtil.delTempFile(); mUtil.delTempFile();
mEntity.deleteData(); mEntity.deleteData();
sendInState2Target(IDownloadTarget.CANCEL);
//发送取消下载的广播 //发送取消下载的广播
Intent intent = createIntent(DownloadManager.ACTION_CANCEL);
intent.putExtra(DownloadManager.ENTITY, mEntity);
mContext.sendBroadcast(intent);
}
}
/**
* 创建特定的Intent
*
* @param action
* @return
*/
private Intent createIntent(String action) {
Uri.Builder builder = new Uri.Builder(); Uri.Builder builder = new Uri.Builder();
builder.scheme(mContext.getPackageName()); builder.scheme(mContext.getPackageName());
Uri uri = builder.build(); Uri uri = builder.build();
Intent intent = new Intent(DownloadManager.ACTION_CANCEL); Intent intent = new Intent(action);
intent.setData(uri); intent.setData(uri);
intent.putExtra(DownloadManager.ACTION_CANCEL, mEntity); return intent;
mContext.sendBroadcast(intent); }
/**
* 将任务状态发送给下载器
*
* @param state {@link IDownloadTarget#START}
*/
private void sendInState2Target(int state) {
if (mOutHandler != null) {
mOutHandler.obtainMessage(state, mEntity).sendToTarget();
} }
} }
/** /**
* 下载监听类 * 下载监听类
*/ */
private static class DownloadListener extends DownLoadUtil.DownloadListener { private class DownloadListener extends DownLoadUtil.DownloadListener {
Handler outHandler; Handler outHandler;
Context context; Context context;
Intent sendIntent; Intent sendIntent;
long INTERVAL = 1024 * 10; //10k大小的间隔 long INTERVAL = 1024 * 10; //10k大小的间隔
long lastLen = 0; //上一次发送长度 long lastLen = 0; //上一次发送长度
long lastTime = 0;
long INTERVAL_TIME = 60 * 1000; //10k大小的间隔
DownloadEntity downloadEntity; DownloadEntity downloadEntity;
public DownloadListener(Context context, DownloadEntity downloadEntity, DownloadListener(Context context, DownloadEntity downloadEntity,
Handler outHandler) { Handler outHandler) {
this.context = context; this.context = context;
this.outHandler = outHandler; this.outHandler = outHandler;
this.downloadEntity = downloadEntity; this.downloadEntity = downloadEntity;
sendIntent = new Intent(DownloadManager.ACTION_RUNNING); sendIntent = createIntent(DownloadManager.ACTION_RUNNING);
Uri.Builder builder = new Uri.Builder(); sendIntent.putExtra(DownloadManager.ENTITY, downloadEntity);
builder.scheme(context.getPackageName());
Uri uri = builder.build();
sendIntent.setData(uri);
} }
@Override public void onPreDownload(HttpURLConnection connection) { @Override public void onPreDownload(HttpURLConnection connection) {
@ -143,9 +174,14 @@ public class Task {
@Override public void onProgress(long currentLocation) { @Override public void onProgress(long currentLocation) {
super.onProgress(currentLocation); super.onProgress(currentLocation);
if (currentLocation - lastLen > INTERVAL) { //不要太过于频繁发送广播 // if (currentLocation - lastLen > INTERVAL) { //不要太过于频繁发送广播
sendIntent.putExtra(DownloadManager.ACTION_RUNNING, currentLocation); // sendIntent.putExtra(DownloadManager.CURRENT_LOCATION, currentLocation);
lastLen = currentLocation; // lastLen = currentLocation;
// context.sendBroadcast(sendIntent);
// }
if (System.currentTimeMillis() - lastLen > INTERVAL_TIME){
sendIntent.putExtra(DownloadManager.CURRENT_LOCATION, currentLocation);
lastTime = System.currentTimeMillis();
context.sendBroadcast(sendIntent); context.sendBroadcast(sendIntent);
} }
} }
@ -180,27 +216,12 @@ public class Task {
sendIntent(DownloadManager.ACTION_FAIL, -1); sendIntent(DownloadManager.ACTION_FAIL, -1);
} }
/**
* 将任务状态发送给下载器
*
* @param state {@link IDownloadTarget#START}
*/
private void sendInState2Target(int state) {
if (outHandler != null) {
outHandler.obtainMessage(state, downloadEntity).sendToTarget();
}
}
private void sendIntent(String action, long location) { private void sendIntent(String action, long location) {
downloadEntity.setDownloadComplete(action.equals(DownloadManager.ACTION_COMPLETE)); downloadEntity.setDownloadComplete(action.equals(DownloadManager.ACTION_COMPLETE));
downloadEntity.setCurrentProgress(location); downloadEntity.setCurrentProgress(location);
downloadEntity.update(); downloadEntity.update();
Uri.Builder builder = new Uri.Builder(); Intent intent = createIntent(action);
builder.scheme(context.getPackageName()); intent.putExtra(DownloadManager.ENTITY, downloadEntity);
Uri uri = builder.build();
Intent intent = new Intent(action);
intent.setData(uri);
intent.putExtra(action, downloadEntity);
if (location != -1) { if (location != -1) {
intent.putExtra(DownloadManager.CURRENT_LOCATION, location); intent.putExtra(DownloadManager.CURRENT_LOCATION, location);
} }

View File

@ -58,7 +58,24 @@ public class Util {
} }
/** /**
* 将缓存的key转换为hash码 * 字符串转hashcode
*
* @param str
* @return
*/
public static int keyToHashCode(String str) {
int total = 0;
for (int i = 0; i < str.length() && i < 6; i++) {
char ch = str.charAt(i);
if (ch == '-') ch = (char) 28; // does not contain the same last 5 bits as any letter
if (ch == '\'') ch = (char) 29; // nor this
total = (total * 33) + (ch & 0x1F);
}
return total;
}
/**
* 将key转换为16进制码
* *
* @param key 缓存的key * @param key 缓存的key
* @return 转换后的key的值, 系统便是通过该key来读写缓存 * @return 转换后的key的值, 系统便是通过该key来读写缓存

View File

@ -1,6 +1,6 @@
#Mon Dec 28 10:00:20 PST 2015 #Fri Oct 07 09:47:16 CST 2016
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip