您的位置:首页 > 其它

多线程断点续传

2016-06-15 13:13 204 查看
一、定义UI

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.it.zjhz.downloaddemo.MainActivity">

<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文件名称" />

<ProgressBar
android:id="@+id/pb_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_name"
style="@android:style/Widget.ProgressBar.Horizontal"/>

<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始"
android:layout_below="@+id/pb_progress"
android:layout_toLeftOf="@+id/btn_stop"/>

<Button
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂停"
android:layout_below="@+id/pb_progress"
android:layout_alignParentRight="true"/>
</RelativeLayout>


二、定义实体类

FileInfo:id、url、fileName、length、progress,实现Serializable接口

ThreadInfo:id、url、start、stop、progress

三、向Service传递参数

将要下载的文件信息实体从Activity传递到Service

Intent intent = new Intent(MainActivity.this, DownloadService.class);
intent.setAction(DownloadService.ACTION_START);
intent.putExtra("fileInfo", fileInfo);
startService(intent);


Service里面定义两个Action,分别标识开始和暂停

public static final String ACTION_START = "ACTION_START";
public static final String ACTION_STOP = "ACTION_STOP";


在onStartCommand方法中接收传过来的FileInfo

if (ACTION_START.equals(intent.getAction())) {
FileInfo fileInfo = (FileInfo) intent.getSerializableExtra("fileInfo");
Log.i("StartFileInfo",fileInfo.toString());
} else if (ACTION_STOP.equals(intent.getAction())) {
FileInfo fileInfo = (FileInfo) intent.getSerializableExtra("fileInfo");
Log.i("stopFileInfo",fileInfo.toString());
}


四、使用线程进行初始化

开启服务后,如果是ACTION_START,子线程访问网络获取文件长度,在本地创建一个文件,并使用Handler将文件信息返回给主线程。

子线程类有一个成员变量是一个FileInfo对象,是该子线程所要初始化的下载文件,创建子线程时通过构造方法传进来。

/**
* 初始化子线程
*/

class InitThread extends Thread {

private FileInfo mFileInfo;

public InitThread(FileInfo mFileInfo) {
this.mFileInfo = mFileInfo;
}

@Override
public void run() {
super.run();
HttpURLConnection conn = null;
RandomAccessFile raf = null;
try {
URL url = new URL(mFileInfo.getUrl());
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
int length = -1;
if (conn.getResponseCode() == 200) {
length = conn.getContentLength();
}
if (length < 0) {
return;
}
//创建本地文件
File dir = new File("/data/data/" + getPackageName() +
4000
"/downloads/");
if (!dir.exists()) {
dir.mkdir();
}
File file = new File(dir, mFileInfo.getFileName());
raf = new RandomAccessFile(file, "rwd");
//设置文件长度
raf.setLength(length);
//将获取文件长度之后的FileInfo回传到主线程
mFileInfo.setLength(length);
mHandler.obtainMessage(MSG_INIT, mFileInfo).sendToTarget();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.disconnect();
raf.close();
} catch (Exception e) {
e.printStackTrace();
}
}

}
}


Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_INIT:
FileInfo fileInfo = (FileInfo) msg.obj;
Log.i("InitfileInfo", fileInfo.toString());
break;
default:
break;
}
}
};


五、创建数据库和数据访问接口

创建数据库辅助类

private static final String DB_NAME = "download.db";
private static final int VERSION = 1;
private static final String SQL_CREATE = "create table thread_info(_id integer primary key autoincrement," +
"thread_id integer,url text,start integer,stop integer,progress integer)";
private static final String SQL_DROP = "drop table if exists thread_info";

public DBHelper(Context context) {
super(context, DB_NAME, null, VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(SQL_DROP);
db.execSQL(SQL_CREATE);
}
}


数据访问接口

public interface ThreadDao {
public void insertThread(ThreadInfo threadInfo);
public void deleteThread(String url,int thread_id);
public void updateThread(String ul,int thread_id,int progress);
public List<ThreadInfo> getThreads(String url);
public boolean isExists(String ul,int thread_id);
}


数据访问接口实现

public class ThreadDaoImpl implements ThreadDao {
private DBHelper dbHelper;

public ThreadDaoImpl(Context context) {
dbHelper = new DBHelper(context);
}

@Override
public void insertThread(ThreadInfo threadInfo) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("thread_id", threadInfo.getId());
values.put("url", threadInfo.getUrl());
values.put("start", threadInfo.getStart());
values.put("stop", threadInfo.getStop());
values.put("progress", threadInfo.getProgress());
db.insert("thread_info", null, values);
db.close();
}

@Override
public void deleteThread(String url, int thread_id) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("thread_info", "url = ? and thread_id = ?", new String[]{url, thread_id + ""});
db.close();
}

@Override
public void updateThread(String url, int thread_id, int progress) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("progress", progress);
db.update("thread_info", values, "url = ? and thread_id = ?", new String[]{url, thread_id + ""});
db.close();
}

@Override
public List<ThreadInfo> getThreads(String url) {
List<ThreadInfo> list = new ArrayList<>();
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.rawQuery("select * from thread_info where url = ?", new String[]{url});
while (cursor.moveToNext()) {
ThreadInfo threadInfo = new ThreadInfo();
threadInfo.setId(cursor.getInt(cursor.getColumnIndex("thread_id")));
threadInfo.setUrl(cursor.getString(cursor.getColumnIndex("url")));
threadInfo.setStart(cursor.getInt(cursor.getColumnIndex("start")));
threadInfo.setStop(cursor.getInt(cursor.getColumnIndex("stop")));
threadInfo.setProgress(cursor.getInt(cursor.getColumnIndex("progress")));
list.add(threadInfo);
}
cursor.close();
db.close();
return list;
}

@Override
public boolean isExists(String url, int thread_id) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.rawQuery("select * from thread_info where url = ? and thread_id = ?", new String[]{url, thread_id + ""});
boolean result = cursor.moveToNext();
cursor.close();
db.close();
return result;
}
}


六、数据下载类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: