zoukankan      html  css  js  c++  java
  • 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先看一下界面

     

      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技术交流
     
  • 相关阅读:
    wordpress升级需设置ftp的解决方法
    用命令创建MySQL数据库
    MySQL创建用户与授权
    MySQL基本命令和常用数据库对象
    转换说明符和转换说明修饰符
    html-webpack-plugin
    数据库-之MySQL的dos命令
    浅谈Java拆箱、装箱
    Java基础问题10问
    Java单例类
  • 原文地址:https://www.cnblogs.com/jerehedu/p/4877503.html
Copyright © 2011-2022 走看看