1、startService和BindService都是作为后台服务,但区别在于生命周期,多次启动,Activity销毁是否解绑。
2、关于startService简介声明:
public IBinder onBind(Intent intent){
Log.e("call","onBind"); returnnull; }
//开启服务Intent service =new Intent(this, MyService.class); startService(service);
//结束服务stopService(service);
调用多次startService,onCreate只有第一次会被执行,而onStartCommand会执行多次。
3、关于BindService简介声明:
//开启服务 Intent service =newIntent(this, MyService.class);
MyConnection conn =new MyConnection();
//第一个参数:Intent意图
//第二个参数:是一个接口,通过这个接口接收服务开启或者停止的消息,并且这个参数不能为null
//第三个参数:开启服务时的操作,BIND_AUTO_CREATE代表自动创建
servicebindService(service, conn, BIND_AUTO_CREATE);
同时自己实现conn:
//结束服务unbindService(conn);
onBind返回值不为null的情况分析:
以下内容转自网友:
4、startService和bindService开启服务时,他们与activity之间的关系
1)startService开启服务以后,与activity就没有关联,不受影响,独立运行。
2)bindService开启服务以后,与activity存在关联,退出activity时必须调用unbindService方法,否则会报ServiceConnection泄漏的错误。
以上知识点结合DownloadManager实践:
public class DownloadServiceextends Service {
public static final StringBUNDLE_KEY_DOWNLOAD_URL ="download_url";
public static final int UNBIND_SERVICE =0x002;
private DownloadBinderbinder;
public static final int HANDLE_DOWNLOAD =0x001;
//下载任务ID
private long downloadId;
private StringdownloadUrl;
private DownloadManagerdownloadManager;
private OnProgressListeneronProgressListener;
private BroadcastReceiverdownLoadBroadcast;
private ScheduledExecutorServicescheduledExecutorService;
@Override
public void onCreate() {
super.onCreate();
binder =new DownloadBinder();
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(progressRunnable, 0, 1, TimeUnit.SECONDS);
}
@Override
public IBinderonBind(Intent intent) {
downloadUrl = intent.getStringExtra(BUNDLE_KEY_DOWNLOAD_URL);
downloadApk(downloadUrl, "lotteryInstall.apk");
return binder;
}
/**
* 下载最新APK
*/
private void downloadApk(String url, String name) {
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request =new DownloadManager.Request(Uri.parse(url));
/**设置用于下载时的网络状态*/
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
/**设置通知栏是否可见*/
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
/**设置漫游状态下是否可以下载*/
request.setAllowedOverRoaming(false);
/**如果我们希望下载的文件可以被系统的Downloads应用扫描到并管理,
我们需要调用Request对象的setVisibleInDownloadsUi方法,传递参数true.*/
request.setVisibleInDownloadsUi(true);
//设置可以被系统扫描到
request.allowScanningByMediaScanner();
/**设置文件保存路径*/
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, name);
/**将下载请求放入队列, return下载任务的ID*/
downloadId =downloadManager.enqueue(request);
registerBroadcast();
}
/**
* 注册广播
*/
private void registerBroadcast() {
/**注册service 广播 1.任务完成时 */
IntentFilter intentFilter =new IntentFilter();
intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downLoadBroadcast =new DownLoadBroadcast(), intentFilter);
}
/**
* 注销广播
*/
private void unregisterBroadcast() {
if (downLoadBroadcast !=null) {
unregisterReceiver(downLoadBroadcast);
downLoadBroadcast =null;
}
}
public class DownloadBinderextends Binder {
/**
* 返回当前服务的实例
*
* @return
*/
public DownloadServicegetService() {
return DownloadService.this;
}
}
/**
* 接受下载完成广播
*/
private class DownLoadBroadcastextends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
checkStatus();
}
}
//检查下载状态
private void checkStatus() {
DownloadManager.Query query =new DownloadManager.Query();
//通过下载的id查找
query.setFilterById(downloadId);
Cursor c =downloadManager.query(query);
if (c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status) {
//下载暂停
case DownloadManager.STATUS_PAUSED:
break;
//下载延迟
case DownloadManager.STATUS_PENDING:
break;
//正在下载
case DownloadManager.STATUS_RUNNING:
LogWriter.writeExceptionLog("DownloadUtils 正在下载");
//下载完成
case DownloadManager.STATUS_SUCCESSFUL:
LogWriter.writeExceptionLog("DownloadUtils app下载完成");
close();
if (onProgressListener !=null) {
onProgressListener.onProgress(UNBIND_SERVICE);
}
DeviceAPIFactory.getRobotSystemServer().startApkUpdate(new IMessageBagReceiver() {
@Override
public void onMessageBagReceived(MessageBag resMsgBag) {
AppUpgradeService.startActionUpdateApp(App.getInstance(),
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() +"/lotteryInstall.apk", BuildConfig.APPLICATION_ID);
}
@Override
public void onMessageBagTimeout(MessageBag reqMsgBag) {
ToastUtil.showMessage("发送数据超时,App升级失败,请重试!");
}
});
break;
//下载失败
case DownloadManager.STATUS_FAILED:
LogWriter.writeExceptionLog("DownloadUtils 下载失败");
break;
}
}
c.close();
}
/**
* 关闭定时器,线程等操作
*/
private void close() {
if (scheduledExecutorService !=null && !scheduledExecutorService.isShutdown()) {
scheduledExecutorService.shutdown();
}
if (downLoadHandler !=null) {
downLoadHandler.removeCallbacksAndMessages(null);
}
}
public HandlerdownLoadHandler =new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case HANDLE_DOWNLOAD:
if (onProgressListener !=null &&HANDLE_DOWNLOAD == msg.what) {
onProgressListener.onProgress(getDownloadPercent(downloadId));
}
break;
default:
break;
}
}
};
private RunnableprogressRunnable =new Runnable() {
@Override
public void run() {
updateProgress();
}
};
/**
* 发送Handler消息更新进度和状态
*/
private void updateProgress() {
downLoadHandler.sendEmptyMessage(HANDLE_DOWNLOAD);
}
public interface OnProgressListener {
/**
* 下载进度
*
* @param fraction 已下载/总大小
*/
void onProgress(int fraction);
}
/**
* 对外开发的方法
*
* @param onProgressListener
*/
public void setOnProgressListener(OnProgressListener onProgressListener) {
this.onProgressListener = onProgressListener;
}
/**
* 获取下载进度
*
* @param downloadId
* @return
*/
private int getDownloadPercent(long downloadId) {
DownloadManager.Query query =new DownloadManager.Query().setFilterById(downloadId);
Cursor c =downloadManager.query(query);
if (c.moveToFirst()) {
int downloadBytesIdx = c.getColumnIndexOrThrow(
DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
int totalBytesIdx = c.getColumnIndexOrThrow(
DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
long totalBytes = c.getLong(totalBytesIdx);
long downloadBytes = c.getLong(downloadBytesIdx);
return (int) (downloadBytes *100 / totalBytes);
}
return 0;
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterBroadcast();
}
}
Activity部分代码掠影:
private ServiceConnectionconn =new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
DownloadService.DownloadBinder binder = (DownloadService.DownloadBinder) service;
DownloadService downloadService = binder.getService();
//接口回调,下载进度
downloadService.setOnProgressListener(new DownloadService.OnProgressListener() {
@Override
public void onProgress(float fraction) {
LogUtil.i(TAG, "下载进度:" + fraction);
bnp.setProgress((int)(fraction *100));
//判断是否真的下载完成进行安装了,以及是否注册绑定过服务
if (fraction == DownloadService.UNBIND_SERVICE &&isBindService) {
unbindService(conn);
isBindService =false;
MToast.shortToast("下载完成!");
}
}
});
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
That's all !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
网友评论