通过封装的AsyncTask类实现下载apk应用

AsyncTask类可以实现异步操作,通过其接口可以实现在子线程实现网络下载请求,并可返回结果在UI线程操作结果

public class DownloadAsync extends AsyncTask<String, Integer, Boolean>

AsyncTask定义了三种泛型类型参数 Params,Progress和Result。分别对应上面的String Integer Boolean

1.Params 启动任务执行的输入参数,比如HTTP请求的URL。

2.Progress 后台任务执行的百分比。这里的结果返回的是可变参数 Integer

会传入到

protected void onProgressUpdate(Integer... values)

可以用来对进度更新等操作

3.Result 后台执行任务最终返回的结果,比如这里返回的是Boolean。

protected void onPostExecute(Boolean aBoolean)

 这里做的效果图如下:

之后再FileManager中可以看到下载的apk文件:


具体代码实现如下:

建立的DownloadHelper类封装了AsyncTask类

public class DownloadHelper {
    public static void Download(String url, String path, onDownloadListener listener){
        DownloadAsync task = new DownloadAsync(url, path, listener);
        task.execute();
    }

    public static class DownloadAsync extends AsyncTask<String, Integer, Boolean> {
        String mUrl;
        String mPath;
        onDownloadListener mOnDownloadListener;
        static int contentLength;

        public DownloadAsync(String url, String path, onDownloadListener listener) {
            mUrl = url;
            mPath = path;
            mOnDownloadListener = listener;
        }

        /**
         * 通过主线程调用execute(String ..)执行
         * (子线程)
         */
        @Override
        protected Boolean doInBackground(String... params) {

            try {
                /**
                 * 执行下载任务
                 */
                URL url = new URL(mUrl);
                URLConnection con = url.openConnection();
                InputStream is = con.getInputStream();
                //下载总长度
                contentLength = con.getContentLength();

                File apkFile = new File(mPath);
                if(apkFile.exists()){
                    if(!apkFile.delete()){
                        if(mOnDownloadListener != null){
                            mOnDownloadListener.onFail(-2, apkFile, "文件删除失败");
                        }
                    }
                }
                // 已下载长度
                int downloadLength = 0;
                byte[] bytes = new byte[1024];
                int len;
                OutputStream os = new FileOutputStream(mPath);
                while ((len = is.read(bytes)) >-1 ){
                    os.write(bytes, 0, len);
                    downloadLength += len;
                    //传入两个参数到onProgressUpdate(Integer... values)
                    publishProgress(downloadLength * 100 / contentLength
                            , downloadLength);
                }
                is.close();
                os.close();

            } catch (MalformedURLException e) {
                e.printStackTrace();
                if(mOnDownloadListener != null){
                    mOnDownloadListener.onFail(-2, new File(mPath), e.getMessage());
                }
                return false;
            } catch (IOException e) {
                e.printStackTrace();
                if(mOnDownloadListener != null){
                    mOnDownloadListener.onFail(-3, new File(mPath), e.getMessage());
                }
                return false;
            }

            return true;
        }

        /**
         * 请求之前的操作调用了接口
         * 的onStart方法(UI线程)
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if(mOnDownloadListener != null){
                mOnDownloadListener.onStart();
            }
        }

        /**
         * 请求之后的操作,判断了doInBackground返回值Boolean类型调用了接口
         * 的onSuccess(UI线程)
         */
        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
            if(aBoolean){
                if(mOnDownloadListener != null){
                    mOnDownloadListener.onSuccess(0, new File(mPath));
                }
            }else{

            }
        }

        /**
         * 在doInBackground中调用的publishProgress会将其参数传入
         * @Integer类型可变参数,用于更新进度条及下载进度(UI线程)
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if(values == null || values.length == 0) {
                return ;
            }
            if(mOnDownloadListener != null){
                mOnDownloadListener.onProgress(values[0], values[1]);
            }
        }
    }
    //自定义接口用于实现请求成功,失败,进度,开始的处理
    public interface onDownloadListener {
        void onSuccess(int code, File file);
        void onFail(int code, File file, String msg);
        void onProgress(int progress, int downloadLength);
        void onStart();
    }
}

DownloadActivity如下

public class DownloadActivity extends AppCompatActivity {
    private static final String FILE_NAME = "i999.apk";
    private static final String TAG = "DownloadActivity";
    private ProgressBar progressBar;
    private TextView resultText;
    private Button downloadButton;
    private final static String APK_URL = "http://www.imooc.com/mobile/mukewang.apk";
    private final static String FILE_PATH = Environment.getExternalStorageDirectory()
            + File.separator + FILE_NAME;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_download);
        initView();
        bindEvents();
    }

    private void initView() {
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        resultText = (TextView) findViewById(R.id.result_txt);
        downloadButton = (Button) findViewById(R.id.download_btn);
    }

    private void bindEvents() {
        downloadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //传入参数1.URL 2.下载路径 3.接口(实现请求的各种处理)
                DownloadHelper.Download(APK_URL, FILE_PATH, new DownloadHelper.onDownloadListener() {
                    @Override
                    public void onSuccess(int code, File file) {
                        downloadButton.setText(R.string.waiting);
                        downloadButton.setEnabled(true);
                        resultText.setText(getString(R.string.download_finish));
                    }

                    @Override
                    public void onFail(int code, File file, String msg) {
                        downloadButton.setText(R.string.waiting);
                        downloadButton.setEnabled(true);
                        resultText.setText(getString(R.string.download_fail));
                    }

                    @Override
                    public void onProgress(int progress, int downloadLength) {
                        progressBar.setProgress(progress);
                        resultText.setText(downloadLength + "/" + DownloadHelper.DownloadAsync.contentLength);
                    }

                    @Override
                    public void onStart() {
                        downloadButton.setText(R.string.begin);
                        downloadButton.setEnabled(false);
                    }
                });
            }
        });
    }
}

有些时候可能我们并不需要实现onStart ,onProgress方法。所以我们可以在接口中定义一个抽象类如下图:


在Activity中我们便可只实现onSuccess , onFail方法了,如果需要实现只需要onStart, onProgress方法则覆盖方法就可以了

如下图:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值