版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在Android中利用线程池控制并发数
这篇文章给大家介绍怎么在Android中利用线程池控制并发数,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。主要实现步奏:1、定义一个DownUtil类,下载工作基本在此类完成,在构造器中初始化UI线程的Handler。用于子线程和UI线程传递下载进度值。2、所有的下载任务都保存在LinkedList。在init()方法中开启一个后台线程,不断地从LinkedList中取任务交给线程池中的空闲线程执行。3、每当addTask方法添加一个任务,就向mPoolThreadHandler发送条消息,就从任务队列中取出一个任务交给线程池执行。这里使用了使用了Semaphore信号量,也就是说只有当一个任务执行完成之后,release()一个信号量,才能从LinkedList中取出一个任务再去执行,否则acquire()方法会一直阻塞线程,直到上一个任务完成。public
class
DownUtil
{
//定义下载资源的路径
private
String
path;
//指定下载文件的保存位置
private
String
targetFile;
//定义下载文件的总大小
private
int
fileSize;
//线程池
private
ExecutorService
mThreadPool;
//线程数量
private
static
final
int
DEFAULT_THREAD_COUNT
=
5;
//任务队列
private
LinkedList<Runnable>
mTasks;
//后台轮询线程
private
Thread
mPoolThread;
//后台线程的handler
private
Handler
mPoolThreadHandler;
//UI线程的Handler
private
Handler
mUIThreadHandler;
//信号量
private
Semaphore
semaphore;
private
Semaphore
mHandlerSemaphore
=
new
Semaphore(0);
//下载线程数量
private
int
threadNum;
public
DownUtil(String
path
,
String
targetFile
,
int
threadNum
,
final
ProgressBar
bar)
{
this.path
=
path;
this.targetFile
=
targetFile;
this.threadNum
=
threadNum;
init();
mUIThreadHandler
=
new
Handler()
{
int
sumSize
=
0;
@Override
public
void
handleMessage(Message
msg)
{
if
(msg.what
==
0x123)
{
int
size
=
msg.getData().getInt("upper");
sumSize
+=
size;
Log.d("sumSize"
,
sumSize
+
"");
bar.setProgress((int)
(sumSize
*
1.0
/
fileSize
*
100));
}
}
};
}
private
void
init()
{
mPoolThread
=
new
Thread()
{
public
void
run()
{
Looper.prepare();
mPoolThreadHandler
=
new
Handler()
{
public
void
handleMessage(Message
msg)
{
if
(msg.what
==
0x111)
{
mThreadPool.execute(getTask());
try
{
semaphore.acquire();
}
catch
(InterruptedException
e)
{
e.printStackTrace();
}
}
}
};
mHandlerSemaphore.release();
Looper.loop();
}
};
mPoolThread.start();
mThreadPool
=
Executors.newFixedThreadPool(DEFAULT_THREAD_COUNT);
mTasks
=
new
LinkedList<>();
semaphore
=
new
Semaphore(DEFAULT_THREAD_COUNT);
}
public
void
downLoad()
{
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");
conn.setRequestProperty("Connection",
"Keep-Alive");
//得到文件的大小
fileSize
=
conn.getContentLength();
conn.disconnect();
int
currentPartSize
=
fileSize
/
threadNum
+
1;
RandomAccessFile
file
=
new
RandomAccessFile(targetFile
,
"rw");
file.setLength(fileSize);
file.close();
for
(int
i
=
0
;
i
<
threadNum
;
i++)
{
//计算每条线程下载的开始位置
int
startPos
=
i
*
currentPartSize;
//每条线程使用一个RandomAccessFile进行下载
RandomAccessFile
currentPart
=
new
RandomAccessFile(targetFile
,
"rw");
//定位该线程的下载位置
currentPart.seek(startPos);
//将任务添加到任务队列中
addTask(new
DownThread(startPos
,
currentPartSize
,
currentPart));
}
}
catch
(IOException
e)
{
e.printStackTrace();
}
}
private
Runnable
getTask()
{
if
(!mTasks.isEmpty())
{
return
mTasks.removeFirst();
}
return
null;
}
private
synchronized
void
addTask(Runnable
task)
{
mTasks.add(task);
try
{
if
(mPoolThreadHandler
==
null)
{
mHandlerSemaphore.acquire();
}
}
catch
(InterruptedException
e)
{
e.printStackTrace();
}
mPoolThreadHandler.sendEmptyMessage(0x111);
}
private
class
DownThread
implements
Runnable
{
//当前线程的下载位置
private
int
startPos;
//定义当前线程负责下载的文件大小
private
int
currentPartSize;
//当前线程需要下载的文件块
private
RandomAccessFile
currentPart;
//定义该线程已经下载的字节数
private
int
length;
public
DownThread(int
startPos
,
int
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");
conn.setRequestProperty("Connection",
"Keep-Alive");
InputStream
inStream
=
conn.getInputStream();
//跳过startPos个字节
skipFully(inStream
,
this.startPos);
byte[]
buffer
=
new
byte[1024];
int
hasRead
=
0;
while
(length
<
currentPartSize
&&
(hasRead
=
inStream.read(buffer))
>
0)
{
currentPart.write(buffer
,
0
,
hasRead);
//累计该线程下载的总大小
length
+=
hasRead;
}
Log.d("length"
,
length
+
"");
//创建消息
Message
msg
=
new
Message();
msg.what
=
0x123;
Bundle
bundle
=
new
Bundle();
bundle.putInt("upper"
,
length);
msg.setData(bundle);
//向UI线程发送消息
mUIThreadHandler.sendMessage(msg);
semaphore.release();
currentPart.close();
inStream.close();
}
catch
(Exception
e)
{
e.printStackTrace();
}
}
}
public
static
void
skipFully(InputStream
in
,
long
bytes)
throws
IOException
{
long
remaining
=
bytes;
long
len
=
0;
while
(remaining
>
0)
{
len
=
in.skip(remaining);
remaining
-=
len;
}
}
}以下是MainActivity的代码:public
class
MainActivity
extends
Activity
{
EditText
url;
EditText
target;
Button
downBn;
ProgressBar
bar;
DownUtil
downUtil;
private
String
savePath;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//获取界面中的四个界面控件
url
=
(EditText)
findViewById(R.id.address);
target
=
(EditText)
findViewById(R.id.target);
try
{
File
sdCardDir
=
Environment.getExternalStorageDirectory();
savePath
=
sdCardDir.getCanonicalPath()
+
"/d.chm";
}
catch
(Exception
e)
{
e.printStackTrace();
}
target.setText(savePath);
downBn
=
(Button)
findViewById(R.id.down);
bar
=
(ProgressBar)
findViewById(R.id.bar);
downBn.setOnClickListener(new
View.OnClickListener()
{
@Override
public
void
onClick(View
view)
{
downUtil
=
new
DownUtil(url.getText().toString()
,
target.getText().toString()
,
7
,
bar);
new
Thread()
{
@Override
public
void
run()
{
try
{
downUtil.downLoad();
}
catch
(Exception
e)
{
e.printStackTrace();
}
}
}.start();
}
});
}
}页面布局比较简单这里一并贴出:<LinearLayout
xmlns:android="/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 吉林省长春市外国语学校2024年高一数学第二学期期末质量跟踪监视模拟试题含解析
- 含混合储能的光伏直流微网接入牵引供电系统技术研究
- 机械振动无线传感器网络数据传输能耗优化方法研究
- 水产品加工行业特征分析报告
- Heilaohuguosu-G-生命科学试剂-MCE
- 云南省昆明市实验中学2024年高一数学第二学期期末教学质量检测模拟试题含解析
- 粮油加工市场分析报告
- 低温仓储提升装料系统设计
- 水的用途-幼儿活动
- 水电安装专项施工方案
- 2024届江西师大附属中学高三第三次模拟考试英语试卷含解析
- 白炭黑市场深度分析及未来趋势预测(简报)
- 幼儿园大班课件:《认识职业-医生》
- 医院采购代理机构遴选制度
- MOOC 理性思维实训-华南师范大学 中国大学慕课答案
- 数智时代的商业变革智慧树知到期末考试答案2024年
- 中国农药杀虫剂行业市场现状供需分析及市场深度研究发展前景及规划可行性分析研究报告(2024-2030版)
- 2024年浙江省温州市中考一模语文试题
- 《垃圾的分类收集与处理》作业设计方案
- 孵化器资质服务协议
- 《土木工程新材料》PPT课件-2024鲜版
评论
0/150
提交评论