IntentService is a base class for Service
s
that handle asynchronous requests (expressed as Intent
s)
on demand. Clients send requests through startService(Intent)
calls;
the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
This "work queue processor" pattern is commonly used to offload tasks from an application‘s main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent)
.
IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application‘s main loop), but only one request will be processed at a time.
总结:与普通的Service不同有几点:
1、相当于一个线程,在onHandleIntent里面可以执行下载等长时间的任务,而Service里面会导致ANR
2、每次IntentService只会执行一个任务,也就是第二次调用IntentService会等待第一个任务执行完才会进行。所以对于一次只能下载一个文件这种场景来说还是比较好用的。
没有解决的问题:
1、IntentServcie怎么暂停当前任务,执行下一个任务?比如暂停一个下载。
下面是写的代码是使用的例子:(当然是在非常理想情况下:网络中断就挂喽)
public class DownloadService extends IntentService {
public static final int UPDATE_PROGRESS = 8344;
private static final String TAG = "DownloadService";
private String fileName = null;//文件名
private int fileLength = 0;//文件长度
private ContentResolver resolver;
private Uri uri;
private int sendTime = 0;
public DownloadService() {
super("DownloadService");
}
@Override
protected void onHandleIntent(Intent intent) {
String downloadUrl = intent.getStringExtra("downloadUrl");
if (!FileUtil.checkFileDir()) {
return;
}
//初始化contentprovider
resolver = this.getContentResolver();
uri = Uri.parse(ConstantUtil.content_provider_uri);
fileName = FileUtil.getFileNameByUrl(downloadUrl);
try {
fileName = URLDecoder.decode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, e.getMessage());
}
//TODO 需要判断是否正在下载或已经下载,名称要反编码为中文
try {
URL url = new URL(downloadUrl);
URLConnection connection = url.openConnection();
connection.connect();
fileLength = connection.getContentLength();
int pieceSize = fileLength / 20;
// 初始化进度
// initProgress();
// 下载文件 TODO 网络异常时,要进行处理
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(ConstantUtil.downloadFileDir + fileName);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
//总共发10次更新消息
if (total >= pieceSize * sendTime) {
Log.i(TAG, "=========sendTime==========" + sendTime + fileName);
updateProgress(total);
sendTime++;
}
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
//完成下载
sendTime = 0;
finishProgress();
}
/**
* 向数据库中插入初始化数据
*/
private void initProgress() {
ContentValues values = new ContentValues();
values.put(DataBaseUtil.DOWNLOAD_FILE_NAME, fileName);
values.put(DataBaseUtil.CREATE_FILE_DATE, new Date().toString());
values.put(DataBaseUtil.DOWNLOAD_FILE_TOTAL_SIZE, fileLength);
values.put(DataBaseUtil.DOWNLOAD_FILE_CURRENT_SIZE, 0);
values.put(DataBaseUtil.DOWNLOAD_FINISHED, false);
resolver.insert(uri, values); //向ContentProvider插入数据
}
/**
*
* 更新进度
*
*<p>detail comment
*@see
*@since
*
*/
private void updateProgress(long currentSize) {
ContentValues values = new ContentValues();
values.put(DataBaseUtil.DOWNLOAD_FILE_CURRENT_SIZE, currentSize);
values.put(DataBaseUtil.DOWNLOAD_FILE_TOTAL_SIZE, fileLength);
values.put(DataBaseUtil.DOWNLOAD_FINISHED, false);
values.put(DataBaseUtil.CREATE_FILE_DATE, new Date().toString());
resolver.update(uri, values, "name=?", new String[] { fileName });
}
/**
*
* 完成下载
*
*<p>detail comment
*@param currentSize
*@see
*@since
*
*/
private void finishProgress() {
ContentValues values = new ContentValues();
values.put(DataBaseUtil.DOWNLOAD_FILE_CURRENT_SIZE, fileLength);
values.put(DataBaseUtil.DOWNLOAD_FINISHED, true);
resolver.update(uri, values, "name=?", new String[] { fileName });
}
}
IntentService实现下载