1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
Handler mHadler =
new
Handler(){
@Override
public
void
handleMessage(Message msg) {
super
.handleMessage(msg);
if
(msg.what ==
1
){
Bitmap bitmap = (Bitmap) msg.obj;
//更新UI...
}
}
};
private
void
download(){
new
Thread(
new
Runnable() {
@Override
public
void
run() {
// 这里进行下载操作...获得了图片的bitmap
//下载完后才,向主线程发送Message
Message msg = Message.obtain();
msg.obj = bitmap;
msg.what =
1
;
//区分哪一个线程发送的消息
mHadler.sendMessage(msg);
}
}).start();
}
|
1
|
public
abstract
class
AsyncTask
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
public
class
MyAsyncTask
extends
AsyncTask
private
ProgressBar mPreogressBar;
//进度条
private
ImageView mImageView;
//图片显示控件
public
MyAsyncTask(ProgressBar pb,ImageView iv){
mPreogressBar = pb;
mImageView = iv;
}
@Override
protected
void
onPreExecute() {
super
.onPreExecute();
mPreogressBar.setVisibility(View.VISIBLE);
}
@Override
protected
Bitmap doInBackground(String... params) {
String urlParams = params[
0
];
//拿到execute()传过来的图片url
Bitmap bitmap =
null
;
URLConnection conn =
null
;
InputStream is =
null
;
try
{
URL url =
new
URL(urlParams);
conn = url.openConnection();
is = conn.getInputStream();
//这里只是为了演示更新进度的功能,实际的进度值需要在从输入流中读取时逐步获取
for
(
int
i =
0
; i <
100
; i++){
publishProgress(i);
Thread.sleep(
50
);
//为了看清效果,睡眠一段时间
}
//将获取到的输入流转成Bitmap
BufferedInputStream bis =
new
BufferedInputStream(is);
bitmap = BitmapFactory.decodeStream(bis);
is.close();
bis.close();
}
catch
(IOException e) {
e.printStackTrace();
}
catch
(InterruptedException e) {
e.printStackTrace();
}
return
bitmap;
}
@Override
protected
void
onProgressUpdate(Integer... values) {
super
.onProgressUpdate(values);
mPreogressBar.setProgress(values[
0
]);
}
@Override
protected
void
onPostExecute(Bitmap bitmap) {
super
.onPostExecute(bitmap);
mPreogressBar.setVisibility(View.GONE);
mImageView.setImageBitmap(bitmap);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
|
//实际项目中如何获取文件大小作为进度值及更新进度值
int
totalSize = conn.getContentLength();
//获取文件总大小
int
size =
0
;
//保存当前下载文件的大小,作为进度值
int
count =
0
;
byte
[] buffer =
new
byte
[
1024
];
while
((count = is.read(buffer)) != -
1
){
size += count;
//获取已下载的文件大小
//调用publishProgress更新进度,它内部会回调onProgressUpdate()方法
publishProgress(size,totalSize);
Thread.sleep(
100
);
//为了看清效果,睡眠一段时间
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
class
MainActivity
extends
AppCompatActivity {
private
ImageView mImageView;
private
ProgressBar mProgressBar;
private
static
String URL =
"http://c.hiphotos.baidu.com/baike/s%3D220/sign=86442af5a6c27d1ea1263cc62bd4adaf/42a98226cffc1e17d8f914604890f603738de919.jpg"
;
private
MyAsyncTask asyncTask;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.image);
mImageView = (ImageView) findViewById(R.id.id_image);
mProgressBar = (ProgressBar) findViewById(R.id.pb);
asyncTask =
new
MyAsyncTask(mProgressBar, mImageView);
asyncTask.execute(URL);
//将图片url作为参数传入到doInBackground()中
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
"@+id/id_image"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
"@+id/pb"
style=
"@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_centerInParent=
"true"
android:layout_width=
"match_parent"
android:layout_height=
"30dp"
/>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
"@+id/id_image"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
"@+id/pb"
style=
"@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_centerInParent=
"true"
android:layout_width=
"match_parent"
android:layout_height=
"30dp"
/>
"match_parent"
android:layout_height=
"wrap_content"
android:padding=
"15dp"
android:id=
"@+id/id_btn"
android:text=
"加载图片"
android:textSize=
"16sp"
android:layout_alignParentBottom=
"true"
android:onClick=
"loadImage"
/>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public
class
MainActivity
extends
AppCompatActivity {
private
ImageView mImageView;
private
ProgressBar mProgressBar;
private
static
String url =
"http://c.hiphotos.baidu.com/baike/s%3D220/sign=86442af5a6c27d1ea1263cc62bd4adaf/42a98226cffc1e17d8f914604890f603738de919.jpg"
;
private
MyAsyncTask asyncTask;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.image);
mImageView = (ImageView) findViewById(R.id.id_image);
mProgressBar = (ProgressBar) findViewById(R.id.pb);
asyncTask =
new
MyAsyncTask(mProgressBar, mImageView);
asyncTask.execute(url);
}
public
void
loadImage(View v){
asyncTask.execute(url);
}
}
|
1
2
3
4
|
public
void
loadImage(View v){
Intent i =
new
Intent(
this
,MainActivity.
class
);
startActivity(i);
}
|
1
2
3
4
5
6
7
8
|
@Override
protected
void
onPause() {
super
.onPause();
if
(asyncTask !=
null
&& asyncTask.getStatus() == AsyncTask.Status.RUNNING){
//cancel只是将对应的任务标记为取消状态
asyncTask.cancel(
true
);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
@Override
protected
Bitmap doInBackground(String... params) {
String urlParams = params[
0
];
//拿到execute()传过来的图片url
Bitmap bitmap =
null
;
URLConnection conn =
null
;
InputStream is =
null
;
try
{
URL url =
new
URL(urlParams);
conn = url.openConnection();
is = conn.getInputStream();
for
(
int
i =
0
; i <
100
; i++){
if
(isCancelled()){
//通过isCancelled()判断任务任务是否被取消
break
;
}
publishProgress(i);
Thread.sleep(
50
);
//为了看清效果,睡眠一段时间
}
BufferedInputStream bis =
new
BufferedInputStream(is);
bitmap = BitmapFactory.decodeStream(bis);
is.close();
bis.close();
}
catch
(IOException e) {
e.printStackTrace();
}
catch
(InterruptedException e) {
e.printStackTrace();
}
return
bitmap;
}
@Override
protected
void
onProgressUpdate(Integer... values) {
super
.onProgressUpdate(values);
if
(isCancelled()){
//通过isCancelled()判断任务任务是否被取消
return
;
}
mPreogressBar.setProgress(values[
0
]);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
private
static
final
ThreadFactory sThreadFactory =
new
ThreadFactory() {
private
final
AtomicInteger mCount =
new
AtomicInteger(
1
);
public
Thread newThread(Runnable r) {
return
new
Thread(r,
"AsyncTask #"
+ mCount.getAndIncrement());
}
};
private
static
final
BlockingQueue
new
LinkedBlockingQueue
128
);
/**
* 真正用来执行任务的的线程池
*/
public
static
final
Executor THREAD_POOL_EXECUTOR
=
new
ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
/**
* 定义一个线程池,在线程池中有一个Runnable任务队列,用来存放、顺序执行任务
*/
public
static
final
Executor SERIAL_EXECUTOR =
new
SerialExecutor();
//AsyncTask内部默认使用的线程池
private
static
volatile
Executor sDefaultExecutor = SERIAL_EXECUTOR;
//自定义的一个Handler
private
static
InternalHandler sHandler;
|
1
|
|
1
2
3
4
|
@MainThread
public
final
AsyncTask return
executeOnExecutor(sDefaultExecutor, params);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@MainThread
public
final
AsyncTask
Params... params) {
if
(mStatus != Status.PENDING) {
//1、这里判断当前AsyncTask是否正在执行或已执行完毕
switch
(mStatus) {
case
RUNNING:
throw
new
IllegalStateException(
"Cannot execute task:"
+
" the task is already running."
);
case
FINISHED:
throw
new
IllegalStateException(
"Cannot execute task:"
+
" the task has already been executed "
+
"(a task can be executed only once)"
);
}
}
mStatus = Status.RUNNING;
//2、设置正在执行的状态
onPreExecute();
//3、回调onPreExecute()方法
mWorker.mParams = params;
exec.execute(mFuture);
//4、放到前面默认构造的线程池中去执行
return
this
;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
private
static
class
SerialExecutor
implements
Executor {
final
ArrayDeque
new
ArrayDeque
Runnable mActive;
public
synchronized
void
execute(
final
Runnable r) {
mTasks.offer(
new
Runnable() {
public
void
run() {
try
{
r.run();
}
finally
{
scheduleNext();
}
}
});
if
(mActive ==
null
) {
scheduleNext();
}
}
protected
synchronized
void
scheduleNext() {
if
((mActive = mTasks.poll()) !=
null
) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private
static
class
InternalHandler
extends
Handler {
public
InternalHandler() {
super
(Looper.getMainLooper());
}
@SuppressWarnings
({
"unchecked"
,
"RawUseOfParameterizedType"
})
@Override
public
void
handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;
switch
(msg.what) {
case
MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[
0
]);
break
;
case
MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break
;
}
}
}
|
1
2
3
4
5
6
7
8
|
private
static
class
AsyncTaskResult {
final
AsyncTask mTask;
final
Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
|
1
2
3
4
|
protected
final
void
publishProgress(Progress... values) {
if
(!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new
AsyncTaskResult
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
mFuture =
new
FutureTask
@Override
protected
void
done() {
try
{
postResultIfNotInvoked(get());
//这里面通过handler往UI线程发送消息
}
catch
(InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
}
catch
(ExecutionException e) {
throw
new
RuntimeException(
"An error occurred while executing doInBackground()"
,
e.getCause());
}
catch
(CancellationException e) {
postResultIfNotInvoked(
null
);
}
}
};
|