欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新

Android四大组件应用系列——Activity与Service交互实现APK下载,androidapk

来源: 开发者 投稿于  被查看 25094 次 评论:273

Android四大组件应用系列——Activity与Service交互实现APK下载,androidapk


  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文件如下:

<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()中启动下载服务:
@Override
protected 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;
@Override
public void onCreate() {
    super.onCreate();
    app=(MyApp)super.getApplication();
notificationManager=(NotificationManager)super.getSystemService(Context.NOTIFICATION_SERVICE);
}
2.2启动服务
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    isStart=true;
    return Service.START_STICKY;
}
2.3绑定服务
@Override
public 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 

 

<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技术交流
 

用户评论