3-4这节课没听懂,完全是蒙蔽状态。
老师说这是提高篇,然而他说的这些技巧也没有像上节课那样从头到尾演示一遍,上节课倒是听懂了。这节课讲得我感觉一头雾水,也没搞清楚老师要说的逻辑是什么,55555555555555555555555
19
收起
正在回答
3回答
哪地方没有听懂呢?这一节课就是把前一节学习的技术点封装成了一个Helper类并完成下载apk功能,这样可以供所有想执行异步下载功能的地方调用。
大饼蓝
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) {
}
}
}
}
Android网络操作与数据存储2018版
- 参与学习 人
- 提交作业 307 份
- 解答问题 1613 个
本专题是联网及数据处理的必备技能。课程从网络基础知识到线程间协同工作、异步下载处理。介绍了Android内外部文件存储、轻量级数据库SQLite的使用。利用屏幕适配、状态保持、百度地图解决实际问题。
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星