你的位置:首页 > 操作系统

[操作系统]Android四大组件应用系列——Activity与Service交互实现APK下载


  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先看一下界面

 

  

<RelativeLayout ...>  <TextView    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:textAppearance="?android:attr/textAppearanceLarge"    android:text="正在下载"    android:id="@+id/textView"    android:layout_alignParentTop="true" />  <ProgressBar    style="?android:attr/progressBarStyleHorizontal"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:id="@+id/pbDownload"    android:layout_below="@+id/textView"    android:layout_alignParentLeft="true"    android:layout_alignParentStart="true"    android:max="100"    android:progress="0"    android:indeterminate="false" />  <Button    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:text="停止"    android:id="@+id/btStop"    android:layout_below="@+id/pbDownload"    android:layout_alignLeft="@+id/pbDownload"    android:layout_alignStart="@+id/pbDownload" android:onClick="onCancel" /></RelativeLayout>

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. 

 

<application  android:allowBackup="true"  android:icon="@mipmap/ic_launcher"  android:label="@string/app_name"  android:theme="@style/AppTheme"  android:name="com.jerehedu.service.MyApp">  <activity    android:name="com.jerehedu.service.CheckUpdateActivity"    android:label="@string/title_activity_check_update" >    <intent-filter>      <action android:name="android.intent.action.MAIN" />      <category android:name="android.intent.category.LAUNCHER" />    </intent-filter>  </activity>  <activity    android:name="com.jerehedu.service.DownloadActivity"    android:label="@string/title_activity_download" >  </activity>  <service    android:name="com.jerehedu.service.DownloadService"    android:enabled="true"    android:exported="true" >  </service></application>

 

作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
版权声明:本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
技术咨询:JRedu技术交流