上次我们讲到如何实现一个可更新的进度通知,实现的方式是启动一个线程模拟一个下载任务,然后根据任务进度向UI线程消息队列发送进度消息,UI线程根据进度消息更新通知的UI界面。可是在实际应用中,我们一般会将上传、下载等比较耗时的后台任务以服务的形式运行,更新进度通知也是交由后台服务来完成的。 不过有的时候,除了在通知里面显示进度信息,我们也要在Activity中显示当前进度,很多下载系统都有这样的功能,例如Android自带浏览器的下载系统、QQ浏览器的下载系统等等。那么如何实现这一功能呢?实现方式有很多,我们今天先来介绍其中的一种:在Activity中主动监听服务的进度。
具体的思路是:让Activity与后台服务绑定,通过中间对象Binder的实例操作后台服务,获取进度信息和服务的状态以及在必要的时候停止服务。
关于服务的生命周期,如果有些朋友们不太熟悉的话,可以去查阅相关资料;如果以后有时间,我可能也会总结一些与服务相关的知识。
为了让大家对这个过程更清晰一些,在上代码之前,我们先来看看几个截图:
整个过程如上图所示:在我们点击开始按钮后,下载任务开始运行,同事更新通知上的进度,当前Activity也从后台服务获取进度信息,显示到按钮下方;当我们点击通知后,跳转到下载管理界面,在这里我们也从后台服务获取进度,还可以做取消任务等操作。
了解了整个过程的情况后,我们就来分析一下具体的代码实现。
首先是/res/main.xml布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="start"
android:onClick="start"/>
<TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"/>
</LinearLayout>
其中Button是用来启动服务的,TextView是用来显示进度信息的。
然后再在看一下MainActivity.java的代码:
package com.scott.notification;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
private DownloadService.DownloadBinder binder;
private TextView text;
private boolean binded;
private Handler handler = new Handler() {