3-4这节课没听懂,完全是蒙蔽状态。

3-4这节课没听懂,完全是蒙蔽状态。

老师说这是提高篇,然而他说的这些技巧也没有像上节课那样从头到尾演示一遍,上节课倒是听懂了。这节课讲得我感觉一头雾水,也没搞清楚老师要说的逻辑是什么,55555555555555555555555

正在回答

登陆购买课程后可参与讨论,去登陆

3回答

哪地方没有听懂呢?这一节课就是把前一节学习的技术点封装成了一个Helper类并完成下载apk功能,这样可以供所有想执行异步下载功能的地方调用。

  • 大饼蓝 提问者 #1
    那MainActivity.java中的DownloadAsyncTask可以删除吗?因为MainActivity.java和DownloadHelper.java中都有这个DownloadAsyncTask
    2017-12-07 18:39:46
  • irista23 回复 提问者 大饼蓝 #2
    是的,可以两种选择一种方式,但显然封装成独立的下载工具类,复用率更高。
    2017-12-07 18:53:32
  • irista23 回复 提问者 大饼蓝 #3
    也是课程由浅入深,由低到高的一个设计。
    2017-12-07 18:54:48
提问者 大饼蓝 2017-12-08 10:19:30
public class MainActivity extends AppCompatActivity {

    public static final int PROGRESS = 0;
    public static final String APK_URL = "http://download.sj.qq.com/upload/connAssitantDownload/upload/MobileAssistant_1.apk";

    ProgressBar mProgressBar;
    Button mDownloadButton;
    TextView mResultTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化视图
        initView();

        //添加点击事件
        setListener();

        //初始化UI数据
        setData();
    }

    //初始化视图
    private void initView() {
        mProgressBar = findViewById(R.id.progressbar);
        mDownloadButton = findViewById(R.id.download_btn);
        mResultTextView = findViewById(R.id.result_textview);
    }

    //对“点击下载”按钮添加点击事件
    private void setListener() {
        mDownloadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // TODO: 2017/12/4 下载任务
                DownloadHelper.download(APK_URL, "", new DownloadHelper.OnDownloadListener.SimpleDownloadListener() {
                    @Override
                    public void onStart() {
                        super.onStart();
                        mProgressBar.setProgress(PROGRESS); //设置进度条从0开始
                        mDownloadButton.setText(R.string.downloading); //下载中
                        mResultTextView.setText(R.string.downloading);
                        mDownloadButton.setEnabled(false);//一旦开始下载,则Button控件不可用
                    }
                    @Override
                    public void onProgress(int progress) {
                        super.onProgress(progress);

                        if (progress > 0) {
                            mProgressBar.setProgress(progress);
                        }
                    }
                    @Override
                    public void onSuccess(int code, File file) {
                        mDownloadButton.setText(R.string.download_finish);
                        mDownloadButton.setEnabled(true);
                        mResultTextView.setText((R.string.download_finish)); //想在这里加上显示路径,可试了很多办法都没弄成!!!!

                    }
                    @Override
                    public void onFail(int code, File file, String message) {
                        mDownloadButton.setText(R.string.download_fail);
                        mResultTextView.setText(R.string.download_fail);
                    }
                });
            }
        });
    }
    //初始化UI数据
    private void setData() {
       mProgressBar.setProgress(PROGRESS);
        mResultTextView.setText(R.string.download_text);
    }
}
提问者 大饼蓝 2017-12-08 10:18:16
// 自定义下载的封装实现
public class DownloadHelper {

    //1.创建一个方法
    public static void download(String url, String localPath, OnDownloadListener listener) {

        DownloadAsyncTask downloadAsyncTask = new DownloadAsyncTask(url, localPath, listener);
        downloadAsyncTask.execute(); //执行
    }

    //3.创建一个异步任务类
    public static class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {

        String dUrl; //定义url
        String dFilePath; //定义dFilePath文件路径
        OnDownloadListener dListener; //定义OnDownloadListener接口

        DownloadAsyncTask(String dUrl, String dFilePath, OnDownloadListener dListener) {

            this.dUrl = dUrl;
            this.dFilePath = dFilePath;
            this.dListener = dListener;
        }

        static final String File_name = "imooc.apk"; //定义文件名

        /**
         * 1
         * 在异步任务之前,在主线程中
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //可操作UI
            if (dListener != null) {
                dListener.onStart();
            }//回调出去
        }

        /**
         * 2
         * 在另外一个线程中处理事件(异步线程)
         *
         * @param strings 入参(String)
         *                Boolean 出参
         *                Integer 进度
         * @return 结果 (true or false)
         * String...表示String的长度,即字符串的个数可以为1个以上
         */
        @Override
        protected Boolean doInBackground(String... strings) {

            String APKUrl = dUrl; //取得APKUrl

            try {
                //构造URL
                URL url = new URL(APKUrl);
                //构造链接并打开
                URLConnection urlConnection = url.openConnection();

                //读取链接中的输入流
                InputStream inputStream = urlConnection.getInputStream();

                //获取下载内容的总长度
                int contentLength = urlConnection.getContentLength();

                //准备下载地址(获取文件路径,将内容下载到哪个文件路径),File.separator表示斜杠 “/”
                dFilePath = Environment.getExternalStorageDirectory() + File.separator + File_name;

                //对下载文件进行处理
                File apkFile = new File(dFilePath);  //创建文件
                if (apkFile.exists()) { //判断文件是否存在
                    boolean result = apkFile.delete();  //若存在则删除
                    if (!result) {  //判断是否删除失败,若删除失败则执行以下代码
                        /**
                         * 若文件删除失败,则在这里处理
                         */
                        if (dListener != null) {
                            dListener.onFail(-1, apkFile, "文件删除失败!");
                        }
                        return false;  //若删除失败则覆盖
                    }
                }
                //已下载大小
                int downloadSize = 0;
                //下载的内容存放到这个字节数组中(缓存)
                byte[] bytes = new byte[1024];

                //实时读取输入流的长度(当前)
                int length;

                //为mFilePath文件创建一个输出管道
                OutputStream outputStream = new FileOutputStream(dFilePath);

                //循环读取输入流,每循环读取一次就写入一次,并且累加
                while ((length = inputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, length); //写入输出流
                    downloadSize = downloadSize + length; //已下载大小 + 实时读取到的长度  = 下载进度(下载大小)
                    //发送进度
                    publishProgress(downloadSize * 100 / contentLength); //下载长度/总长度 = 当前下载进度(UI)
                }

                //为防止内存溢出,在此处关闭流
                inputStream.close();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
                /**
                 *若文件下载失败,则需要在这里显示失败信息
                 */
                /*if (dListener != null) {
                    dListener.onFail(-2, new File(dFilePath), e.getMessage());
                }*/
                return false;
            }

            /**
             *若文件下载成功,则在这里处理
             */
           /* if (dListener != null) {
                dListener.onSuccess(1, new File(dFilePath));
            }*/

            return true;

        }

        /**
         * 3
         * 也在UI线程中,收到进度,然后处理
         *
         * @param values 进度值
         *               Integer...表示一个可变的Integer,即进度改变
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if (values != null && values.length > 0) {
                /**
                 * 文件下载进度在这里处理
                 */
                if (dListener != null) {
                    dListener.onProgress(values[0]);
                }
            }
        }
        /**
         * 4
         * 也在主线程中,执行结果处理(更新UI)
         *
         * @param aBoolean
         */
        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);

            if (dListener != null) {
                if (aBoolean) {
                    dListener.onSuccess(1, new File(dFilePath));
                } else {
                    dListener.onFail(2, new File(dFilePath), "下载失败!");
                }
            }
        }
    }

    //2.创建一个接口(接口中的方法全部用来处理UI)
    public interface OnDownloadListener {

        void onStart();  //开始下载

        void onSuccess(int code, File file); //下载成功

        void onFail(int code, File file, String message);  //下载失败 String message:失败信息

        void onProgress(int progress);  //下载进度

        //创建一个OnDownloadListener的扩展类(属于抽象类)
        abstract class SimpleDownloadListener implements OnDownloadListener {

            //onStart() 和 onProgress() 这两个方法不是必须要实现的(可选项,可实现亦可不实现,看需求)

            @Override
            public void onStart() {

            }
            @Override
            public void onProgress(int progress) {
            }
        }
    }
}
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
Android网络操作与数据存储2018版
  • 参与学习           人
  • 提交作业       307    份
  • 解答问题       1613    个

本专题是联网及数据处理的必备技能。课程从网络基础知识到线程间协同工作、异步下载处理。介绍了Android内外部文件存储、轻量级数据库SQLite的使用。利用屏幕适配、状态保持、百度地图解决实际问题。

了解课程
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师