Servic与Activity相比它没有界面,主要是在后台执行一些任务,Service有两种启动方法startService()和bindService(),startService方式Service不可交互,可一直在后台即便应用结束,bindService方式可通过ServiceConnection获得运行的Service实例的方式实现Activity和Service之间的交互,通常Activity退出则绑定的服务也就取消了。我们可以通过同时执行启动服务和绑定服务的方式实现Service交互同时又使服务可一直在后台运行直到任务完成,下面我们就使用Service来实现Apk下载任务
实现如图所示效果:
一、编写应用起始界面(CheckUpdateActivity) |
单击“检查版本”执行代码如下:
public void checkUpdate(View view){ //先进行网络版本检查,代码这里不做讲解 showDownload();//转到下载界面}public void showDownload(){ Intent intent=new Intent(CheckUpdateActivity.this,DownloadActivity.class); startActivity(intent); }
二、 Activity与Service通信实现App下载(DownloadActivity+DownloadService) |
1、DownloadActivity
1.1先看一下界面
xml文件如下:
1.2、DownloadActivity代码:
1.2.1构建界面:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_download); pbDownload=(ProgressBar)super.findViewById(R.id.pbDownload); app=(MyApp)super.getApplication();}
1.2.2 在onResume()中启动下载服务:
@Overrideprotected void onResume() { super.onResume(); startDownload();}private void startDownload(){ if(!app.isDownloadIng()){ Intent intent=new Intent(DownloadActivity.this,DownloadService.class); super.startService(intent);//启动服务下载服务,可以确保应用结束下载服务仍然执行 super.bindService(intent, conn, Service.BIND_AUTO_CREATE);//同时绑定服务,可通过ServiceConnection获得Binder实现与Service的通信 app.setIsDownloadIng(true); }}
1.2.3创建ServiceConnnection
private DownloadService.DownloadBind bind;private ServiceConnection conn=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { bind=(DownloadService.DownloadBind)service;//获得binder bind.start();//调用DownloadService实例中的start(),执行后台下载任务 bind.setOnBackResult(result);//调用DownloadService实例中的setOnBackResult() } @Override public void onServiceDisconnected(ComponentName name) { bind=null; }};
1.2.4定义回调接口(ICallbackResult),实现根据下载的百分比设置进度条
public interface ICallbackResult { public void OnBackResult(Object Result);}private ICallbackResult result=new ICallbackResult() { @Override public void OnBackResult(Object result) { if("finish".equals(result)){ //如果传入“finish”表示下载完成 finish(); isFinished=true; return ; } int progress=(Integer)result; pbDownload.setProgress(progress);//改变进度条 }};
1.2.5取消下载,单击停止按钮
public void onCancel(View view){ isCancel=true; app.setIsDownloadIng(false); bind.cancelNotification(); finish();}1.2.5 Activity结束,停止服务protected void onDestroy() { super.onDestroy(); if(isFinished||isCancel){ //如果下载完成或用户取消下载停止后台服务,否则服务仍在后台运行 stopService(new Intent(this, DownloadService.class));//停止后台服务 } if(bind!=null){ unbindService(conn);//取消服务绑定 }}
2、使用DownloadService承载下载任务
2.1初始化
private MyApp app;private NotificationManager notificationManager;@Overridepublic void onCreate() { super.onCreate(); app=(MyApp)super.getApplication();notificationManager=(NotificationManager)super.getSystemService(Context.NOTIFICATION_SERVICE);}
2.2启动服务
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) { isStart=true; return Service.START_STICKY;}
2.3绑定服务
@Overridepublic IBinder onBind(Intent intent) { isStart=true; return new DownloadBind();}
2.4 DownloadBind—— Service实例中Binder组件,实现与DownloadActivity之间通信
public class DownloadBind extends Binder{ public void start(){ startupNotification();//在信息栏显示下载通知信息 startDownload();//执行下载任务 } public void setOnBackResult(DownloadActivity.ICallbackResult iCallbackResult){ callbackResult=iCallbackResult; } public void cancelNotification(){ mNotification.tickerText="已经取消下载"; notificationManager.cancel(NOTIFY_ID);//取消通知栏信息 stopDownload=true; }}
2.5 实现向提示栏发送下载通知
执行效果:
startupNotifiaction()代码:
private final int NOTIFY_ID=0;private Notification mNotification;private void startupNotification(){ mNotification=new NotificationCompat.Builder(this).build(); mNotification.icon=R.mipmap.ic_launcher; mNotification.tickerText="正在下载"; mNotification.defaults=Notification.DEFAULT_SOUND; RemoteViews view=new RemoteViews(super.getPackageName(),R.layout.notification_download); mNotification.contentView=view; Intent intent=new Intent(this,DownloadActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent contentIntent=PendingIntent .getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); mNotification.contentIntent=contentIntent; notificationManager.notify(NOTIFY_ID, mNotification);}
2.6 startDownload()启动线程执行下载任务:
private Thread downloadThread;private void startDownload(){ downloadThread=new Thread(new Runnable() { @Override public void run() { downApk();//这里模拟实现网络下载功能 } }); downloadThread.start();}downApk()实现连接网络并下载并保存文件,这里模拟实现网络下载功能private int progress=0;private int lastLength=10*1024*1024;//剩余文件的大小,初始值为文件总尺寸private int count=0;//已经下载的数据大小private boolean stopDownload=false;private void downApk(){ while(lastLength>0&&!stopDownload){ try { Thread.sleep(2000); count+=1*1024*1024; lastLength=lastLength-1*1024*1024; progress=(int)((float)count/(10*1024*1024)*100); if(progress>1){ Message msg=mhandler.obtainMessage(); msg.what=1; msg.arg1=progress; mhandler.sendMessage(msg); callbackResult.OnBackResult(progress);//通过ICallBackResult回调OnBackResult(),实现更改DownloadActivity中进度条的值 } } catch (InterruptedException e) { e.printStackTrace(); } } mhandler.sendEmptyMessage(0);//表示下载完成 app.setIsDownloadIng(false); callbackResult.OnBackResult("finish");}
2.7 文件下载的异步通信
private Handler mhandler=new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case 0://表示下载完成 stopSelf();//停止当前服务 notificationManager.cancel(NOTIFY_ID);//关闭下载提示栏 isStart=false; break; case 1://表示产生>1的百分比的变化 int progress=(Integer)msg.arg1; RemoteViews contentView=mNotification.contentView; contentView.setTextViewText(R.id.tvProgress,progress+"%");//显示百分比数据 contentView.setProgressBar(R.id.pbUpdate, 100, progress, false);//改变进度条 mNotification.defaults=0;//取消声音提示 notificationManager.notify(NOTIFY_ID, mNotification);//通知下载提示栏的更新 break; } }};
三、其他 |
3.1 MyApp记录应用共享的信息数据
public class MyApp extends Application { private boolean isDownloadIng=false;//记录是否正在下载应用 @Override public void onCreate() { super.onCreate(); } public boolean isDownloadIng() { return isDownloadIng; } public void setIsDownloadIng(boolean isDownloadIng) { this.isDownloadIng = isDownloadIng; }}
3.2 AndroidMainifest.xml
作者: 出处: 版权声明:本文版权归和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 技术咨询: