}, 0, 100);
}
}.start();
}
/**
* 下载歌曲文件
*/
private void downloadSong() {
// 初始化DownUtil对象(最后一个参数指定线程数)
mSongDownUtil = new DownUtil(URL_DOWNLOAD_MP3,
"/mnt/sdcard/假如爱有天意.mp3", 1);
new Thread() {
@Override
public void run() {
try {
// 开始下载
mSongDownUtil.download();
} catch (Exception e) {
e.printStackTrace();
}
// 定义每0.1秒调度获取一次系统的完成进度
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// 获取下载任务的完成比率
double completeRate = mSongDownUtil.getCompleteRate();
mSongDownStatus = (int) (completeRate * 100);
// 发送消息通知界面更新进度条
mHandler.sendEmptyMessage(3);
// 下载完全后取消任务调度
if (mSongDownStatus >= 100) {
timer.cancel();
}
}
}, 0, 100);
}
}.start();
}
/**
* 播放歌曲
*/
private void playSong() {
boolean isPlaying = mMediaPlayer.isPlaying();
if (isPlaying == false) {
mMediaPlayer.start();
mPlayBtn.setImageResource(R.drawable.pause);
} else if ((isPlaying == true)) {
mMediaPlayer.pause();
mPlayBtn.setImageResource(R.drawable.start);
}
}
}
DownUtil.java :
public class DownUtil {
// 定义下载资源的路径
private String path;
// 指定所下载的文件的保存位置
private String targetFile;
// 定义需要使用多少线程下载资源
private int threadNum;
// 定义下载的线程对象
private DownThread[] threads;
// 定义下载的文件的总大小
private long fileSize;
public DownUtil(String path, String targetFile, int threadNum)
{
this.path = path;
this.threadNum = threadNum;
// 初始化threads数组
threads = new DownThread[threadNum];
this.targetFile = targetFile;
}
public void download() throws Exception
{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+ "application/x-shockwave-flash, application/xaml+xml, "
+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+ "application/x-ms-application, application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Connection", "Keep-Alive");
// 得到文件大小
fileSize = conn.getContentLength();
Log.e("fileSize", fileSize + "");
conn.disconnect();
long currentPartSize = fileSize / threadNum;
Log.e("currentPartSize",currentPartSize+"");
RandomAccessFile file = new RandomAccessFile(targetFile, "rw");
// 设置本地文件的大小
file.setLength(fileSize);
file.close();
for (int i = 0; i < threadNum; i++)
{
// 计算每条线程的下载的开始位置
long startPos = i * currentPartSize;
Log.e("startPos",startPos+"");
// 每个线程使用一个RandomAccessFile进行下载
RandomAccessFile currentPart = new RandomAccessFile(targetFile,
"rw");
// 定位该线程的下载位置
currentPart.seek(startPos);
// 创建下载线程
threads[i] = new DownThread(startPos, currentPartSize,
currentPart);
// 启动下载线程
threads[i].start();
}
}
public class DownThread extends Thread {
// 当前线程的下载位置
private long startPos;
// 定义当前线程负责下载的文件大小
private long currentPartSize;
// 当前线程需要下载的文件块
private RandomAccessFile currentPart;
// 定义已经该线程已下载的字节数
public long length;
public DownThread(long startPos, long currentPartSize,
RandomAccessFile currentPart) {
this.startPos = startPos;
this.currentPartSize = currentPartSize;
this.currentPart = currentPart;
}
@Override
public void run()
{
try
{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url
.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+ "application/x-shockwave-flash, application/xaml+xml, "
+ "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+ "application/x-ms-application, application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
InputStream inStream = conn.getInputStream();
/*
* 跳过startPos个字节,表明该线程只下载自己负责哪部分文件
* 如果直接使用 InputStream.skip(long n); 会出现错误
* 因为用的时候,返回值往往小于n
* Java 官方文档指出这个问题,建议自己去写一个方法来实现这个功能
*/
long at = this.startPos;
while(at > 0) {
long amt = inStream.skip(at);
if (amt == -1) {
throw new RuntimeException(currentPart + ": unexpected EOF");
}
at -= amt;
}
byte[] buffer = new byte[1024];
int hasRead = 0;
// 读取网络数据,并写入本地文件
while (length < currentPartSize
&& (hasRead = inStream.read(buffer)) > 0)
{
currentPart.write(buffer, 0, hasRead);
// 累计该线程下载的总大小
length += hasRead;
}
currentPart.close();
inStream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
// 获取下载的完成百分比
public double getCompleteRate()
{
// 统计多条线程已经下载的总大小
long sumSize = 0;
for (int i = 0; i < threadNum; i++)
{
sumSize += threads[i].length;
}
// 返回已经完成的百分比
return sumSize * 1.0 / fileSize;
}
}
activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<ImageView
android:id="@+id/iv_singer_picture"
android:layout_width="match_parent"
android:layout_height="240dp"
android:layout_margin="16dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<ProgressBar
android:id="@+id/bar_dowmload_picture"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<Button
android:id="@+id/btn_download_picture"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:text="点击下载歌手图片"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<ProgressBar
android:id="@+id/bar_dowmload_song"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
设计模式学习笔记
设计模式系列学习视频
- 以上进阶BATJ大厂学习资料可以免费分享给大家,需要完整版的朋友,【点这里可以看到全部内容】。
自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-mikfChgB-1711296201987)]
[外链图片转存中…(img-TLEhjpAT-1711296201987)]
[外链图片转存中…(img-JlR5566R-1711296201988)]
[外链图片转存中…(img-wRZ0YjVi-1711296201988)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-XtvjYthE-1711296201988)]
设计模式学习笔记
[外链图片转存中…(img-vBLknieq-1711296201989)]
设计模式系列学习视频
[外链图片转存中…(img-76txIGUn-1711296201989)]
- 以上进阶BATJ大厂学习资料可以免费分享给大家,需要完整版的朋友,【点这里可以看到全部内容】。