1、创建一个类,继承IntentService,注意的是这里需要写一个无参的构造方法,不然会报错(IntentService的构造函数一定是参数为空的构造函数,然后再在其中调用super("classname")这种形式的构造函数。因为Service的实例化是系统来完成的,而且系统是用参数为空的构造函数来实例化Service的)。
2、onHandleIntent中写处理方法和耗时操作,是在子线程中执行的,不需要开启新线程。Service运行不需要依赖任何用户界面,不需要操作UI,所以也就不需要重写onStartCommand(该方法在主线程中执行,原则上,由于是主线程,可进行UI操作,但是好的编程风格,service不处理activity的内容。)
这里使用到Notification,更新不需要放到主线程中,onHandleIntent中操作没报错。
3、扩展遇到的问题:
Toast需要运行在主线程中。
service运行在主线程中,因此Toast是正常的。
IntentService运行在独立的线程中,因此Toast不正常。
1、NotificationManager
2、NotificationCompat.Builder(为了向下兼容,构造器 配置通知参数)
3、manager.notify(_notificationID, builder.build()); (推送通知)
注意点:
1、创建 Notification 正常方式创建 并且记得推送通知
2、更新通知和创建一样的方式,只需要再次发送相同 ID 的通知即可,如果之前的通知还未被取消,则会直接更新该通知相关的属性;如果之前的通知已经被取消,则会重新创建一个新通知。
更新通知跟发送通知使用相同的方式。
3、涉及到进度条通知的时候特别注意
setProgress(max, progress, false) 确定进度条(显示进度变化)
setProgress(0, 0, true) 不确定进度条(呼呼的跑)
当实时更新进度条通知的时候,manager.notify频繁执行会造成卡顿,并且执行速度变慢。
原因是进度条执行的时候,从progress的打印输出会看到很多重复的数值,造成了manager.notify多次执行。
解决办法很简单,减少执行次数,当变化的时候再执行:
05-30 16:41:30.684 5788-6229/com.sdhmw.com.mystudy E/DownLoadService: progress:23
05-30 16:41:30.694 5788-6229/com.sdhmw.com.mystudy E/DownLoadService: progress:23
05-30 16:41:30.694 5788-6229/com.sdhmw.com.mystudy E/DownLoadService: progress:23
05-30 16:41:30.704 5788-6229/com.sdhmw.com.mystudy E/DownLoadService: progress:23
05-30 16:41:30.714 5788-6229/com.sdhmw.com.mystudy E/DownLoadService: progress:23
05-30 16:41:30.714 5788-6229/com.sdhmw.com.mystudy E/DownLoadService: progress:23
//频繁的manager.notify 会造成卡顿 时间也会很慢
if (progress < 100) {
LogUtil.e(TAG, "progress:" + progress);
//防止界面卡死
if (preProgress < progress) {
builder.setProgress(100, progress, false);
//下载进度提示
builder.setContentText("下载" + progress + "%");
manager.notify(_notificationID, builder.build());
}
preProgress = progress;
} else {
LogUtil.e(TAG, "下载完成");
refreshNotification();
}
public class DownLoadService extends IntentService {
private static final String TAG = "DownLoadService";
private NotificationManager manager;
private NotificationCompat.Builder builder;
private Notification notification;
private final static int _notificationID = 1024;
private int preProgress = 0;
public DownLoadService() {
super(TAG);
}
@Override
public void onCreate() {
super.onCreate();
LogUtil.e(TAG, "onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtil.e(TAG, "onDestroy");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
//初始化通知
initNotification();
LogUtil.e(TAG, "下载启动");
//下载
downFile("http://218.59.191.198:845/file/apk/dtwb.apk");
}
private void downFile(String url) {
DownloadUtil.get().download(url, Environment.getExternalStorageDirectory().getAbsolutePath(), "dtwb2.apk", new DownloadUtil.OnDownloadListener() {
@Override
public void onDownloadSuccess(File file) {
}
@Override
public void onDownloading(int progress) {
//频繁的manager.notify 会造成卡顿 时间也会很慢
if (progress < 100) {
LogUtil.e(TAG, "progress:" + progress);
//防止界面卡死
if (preProgress < progress) {
builder.setProgress(100, progress, false);
//下载进度提示
builder.setContentText("下载" + progress + "%");
manager.notify(_notificationID, builder.build());
}
preProgress = progress;
} else {
LogUtil.e(TAG, "下载完成");
refreshNotification();
}
}
@Override
public void onDownloadFailed(Exception e) {
LogUtil.e(TAG, "下载出错 e:" + e);
}
});
}
private void initNotification() {
builder = new NotificationCompat.Builder(this);
builder.setContentTitle("下载文件")//设置通知栏标题
.setContentText("下载中...") //设置通知栏显示内容
.setSmallIcon(R.mipmap.ic_launcher);
manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
builder.setProgress(100, 0, false);
builder.setAutoCancel(true);
//推送通知
manager.notify(_notificationID, builder.build());
}
private void refreshNotification() {
builder = new NotificationCompat.Builder(this);
builder.setContentTitle("开始安装")//设置通知栏标题
.setContentText("安装中...") //设置通知栏显示内容
.setSmallIcon(R.mipmap.ic_launcher);
manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//设置进度为不确定,用于模拟安装
builder.setProgress(0, 0, true);
builder.setAutoCancel(true);
//通过builder.build()方法生成Notification对象,并发送通知
manager.notify(_notificationID, builder.build());
}
}
相关资料:
全面了解Android Notification