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

来源:互联网 发布:网络借贷监管暂行办法 编辑:程序博客网 时间:2024/05/17 23:29

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方法则覆盖方法就可以了

如下图:



阅读全文
0 0
原创粉丝点击