android多线程怎么调试多线程,Log大法吗,太苦逼了吧

46372人阅读
Android(38)
(1)首先获得下载文件的长度,然后设置本地文件的长度。
(2)根据文件长度和线程数计算每条线程下载的数据长度和下载位置。
如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如下图所示:
(网上找的图)
&例如10M大小,使用3个线程来下载,
线程下载的数据长度 & (10%3 == 0 ? 10/3:10/3+1) ,第1,2个线程下载长度是4M,第三个线程下载长度为2M
下载开始位置:线程id*每条线程下载的数据长度 = ?
下载结束位置:(线程id+1)*每条线程下载的数据长度-1=?
之前练习时的一个demo,不多说了,直接上代码吧,有关断点续传,需要使用数据库,不再加了,网上有很多成熟的项目可以直接用。
package com.amos.
import java.io.F
import java.io.IOE
import java.net.MalformedURLE
import java.net.URL;
import java.net.URLC
import com.amos.download.R;
import android.annotation.SuppressL
import android.app.A
import android.os.B
import android.os.E
import android.os.H
import android.os.M
import android.util.L
import android.view.V
import android.view.View.OnClickL
import android.widget.ProgressB
import android.widget.TextV
import android.widget.T
* @author yangxiaolong
public class MainApp extends Activity implements OnClickListener {
private static final String TAG = MainApp.class.getSimpleName();
/** 显示下载进度TextView */
private TextView mMessageV
/** 显示下载进度ProgressBar */
private ProgressBar mP
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress_activity);
findViewById(R.id.download_btn).setOnClickListener(this);
mMessageView = (TextView) findViewById(R.id.download_message);
mProgressbar = (ProgressBar) findViewById(R.id.download_progress);
public void onClick(View v) {
if (v.getId() == R.id.download_btn) {
doDownload();
* 使用Handler更新UI界面信息
@SuppressLint(&HandlerLeak&)
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
mProgressbar.setProgress(msg.getData().getInt(&size&));
float temp = (float) mProgressbar.getProgress()
/ (float) mProgressbar.getMax();
int progress = (int) (temp * 100);
if (progress == 100) {
Toast.makeText(MainApp.this, &下载完成!&, Toast.LENGTH_LONG).show();
mMessageView.setText(&下载进度:& + progress + & %&);
* 下载准备工作,获取SD卡路径、开启线程
private void doDownload() {
// 获取SD卡路径
String path = Environment.getExternalStorageDirectory()
+ &/amosdownload/&;
File file = new File(path);
// 如果SD卡目录不存在创建
if (!file.exists()) {
file.mkdir();
// 设置progressBar初始化
mProgressbar.setProgress(0);
// 简单起见,我先把URL和文件名称写死,其实这些都可以通过HttpHeader获取到
String downloadUrl = &/data/wisegame/dfae322/baidu_.apk&;
String fileName = &baidu_.apk&;
int threadNum = 5;
String filepath = path + fileN
Log.d(TAG, &download file
path:& + filepath);
downloadTask task = new downloadTask(downloadUrl, threadNum, filepath);
task.start();
* 多线程文件下载
* @author yangxiaolong
class downloadTask extends Thread {
private String downloadU// 下载链接地址
private int threadN// 开启的线程数
private String fileP// 保存文件路径地址
private int blockS// 每一个线程的下载量
public downloadTask(String downloadUrl, int threadNum, String fileptah) {
this.downloadUrl = downloadU
this.threadNum = threadN
this.filePath =
public void run() {
FileDownloadThread[] threads = new FileDownloadThread[threadNum];
URL url = new URL(downloadUrl);
Log.d(TAG, &download file http path:& + downloadUrl);
URLConnection conn = url.openConnection();
// 读取下载文件总大小
int fileSize = conn.getContentLength();
if (fileSize &= 0) {
System.out.println(&读取文件失败&);
// 设置ProgressBar最大的长度为文件Size
mProgressbar.setMax(fileSize);
// 计算每条线程下载的数据长度
blockSize = (fileSize % threadNum) == 0 ? fileSize / threadNum
: fileSize / threadNum + 1;
Log.d(TAG, &fileSize:& + fileSize + &
blockSize:&);
File file = new File(filePath);
for (int i = 0; i & threads. i++) {
// 启动线程,分别下载每个线程需要下载的部分
threads[i] = new FileDownloadThread(url, file, blockSize,
threads[i].setName(&Thread:& + i);
threads[i].start();
boolean isfinished =
int downloadedAllSize = 0;
while (!isfinished) {
isfinished =
// 当前所有线程下载总量
downloadedAllSize = 0;
for (int i = 0; i & threads. i++) {
downloadedAllSize += threads[i].getDownloadLength();
if (!threads[i].isCompleted()) {
isfinished =
// 通知handler去更新视图组件
Message msg = new Message();
msg.getData().putInt(&size&, downloadedAllSize);
mHandler.sendMessage(msg);
// Log.d(TAG, &current downloadSize:& + downloadedAllSize);
Thread.sleep(1000);// 休息1秒后再读取下载进度
Log.d(TAG, & all of downloadSize:& + downloadedAllSize);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
FileDownloadThread:
package com.amos.
import java.io.BufferedInputS
import java.io.F
import java.io.IOE
import java.io.RandomAccessF
import java.net.URL;
import java.net.URLC
import android.util.L
* 文件下载类
* @author yangxiaolong
public class FileDownloadThread extends Thread {
private static final String TAG = FileDownloadThread.class.getSimpleName();
/** 当前下载是否完成 */
private boolean isCompleted =
/** 当前下载文件长度 */
private int downloadLength = 0;
/** 文件保存路径 */
/** 文件下载路径 */
private URL downloadU
/** 当前下载线程ID */
private int threadId;
/** 线程下载数据长度 */
private int blockS
* @param url:文件下载地址
* @param file:文件保存路径
* @param blocksize:下载数据长度
* @param threadId:线程ID
public FileDownloadThread(URL downloadUrl, File file, int blocksize,
int threadId) {
this.downloadUrl = downloadU
this.file =
this.threadId = threadId;
this.blockSize =
public void run() {
BufferedInputStream bis =
RandomAccessFile raf =
URLConnection conn = downloadUrl.openConnection();
conn.setAllowUserInteraction(true);
int startPos = blockSize * (threadId - 1);//开始位置
int endPos = blockSize * threadId - 1;//结束位置
//设置当前线程下载的起点、终点
conn.setRequestProperty(&Range&, &bytes=& + startPos + &-& + endPos);
System.out.println(Thread.currentThread().getName() + &
+ startPos + &-& + endPos);
byte[] buffer = new byte[1024];
bis = new BufferedInputStream(conn.getInputStream());
raf = new RandomAccessFile(file, &rwd&);
raf.seek(startPos);
while ((len = bis.read(buffer, 0, 1024)) != -1) {
raf.write(buffer, 0, len);
downloadLength +=
isCompleted =
Log.d(TAG, &current thread task has finished,all size:&
+ downloadLength);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
bis.close();
} catch (IOException e) {
e.printStackTrace();
if (raf != null) {
raf.close();
} catch (IOException e) {
e.printStackTrace();
* 线程文件是否下载完毕
public boolean isCompleted() {
return isC
* 线程下载文件长度
public int getDownloadLength() {
return downloadL
Log控制台:
可以看到文件总大小、我们创建的5个线程每个负责下载的区间
这个用到了数据存储保存当前每个线程下载文件的长度,等下一次再下载时读取,网上有成熟的案例,就不再造轮子了,资源里我打包了自己的项目和带断点续传的项目(别人的),大家可以下载下来直接用,全部免费:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3983815次
积分:14264
积分:14264
排名:第885名
原创:95篇
转载:24篇
评论:699条
(1)(1)(1)(1)(3)(2)(11)(6)(1)(7)(1)(1)(3)(2)(1)(10)(4)(6)(9)(4)(10)(1)(5)(4)(1)(3)(2)(9)(5)(1)(6)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'Android 多线程处理之多线程用法大集合完整页_西西软件资讯
西西软件下载最安全的下载网站、值得信赖的软件下载站!
→ Android 多线程处理之多线程用法大集合
类型:服务器区大小:21KB语言:中文 评分:6.6
handler.post(r)其实这样并不会新起线程,只是执行的runnable里的run()方法,却没有执行start()方法,所以runnable走的还是UI线程。1.如果像这样,是可以操作ui,但是run还是走在主线程,见打印出来的Log线程名字是main,说明是主线程。这就是为什么可以直接在run方法里操作ui,因为它本质还是ui线程handler.post(new Runnable(){  public void run(){  Log.e(&当前线程:&,Thread.currrentThread.getName());//这里打印de结果会是main  setTitle(&哈哈&);& & & }});2.通过HandlerThread获取到looper却是可以新起线程,但是在这里的run方法里操作ui是不可能的,但是这显然有个缺点,如果你执行多次post(r)方法其实走的还是HandlerThread线程。假如你执行5次,n次,其实还是一次并且它们是串行的。假如下载5张图片,你会看到图片是下完第一张,才会去下第二张。实践证明,只有是拥有主线程looper的handler才可以操作ui,而在主线程操作ui可以在handler的handlerMessage()方法中操作Ui,也可以在handler的post(r)的run方法里操作Ui.HandlerThread ht = new HandlerThread(&handler thread&);ht.start();handler = new Handler(ht.getLooper());handler.post(new Runnable(){//这里run()方法其实还是在等ht.start()调用  public void run(){  Log.e(&当前线程:&,Thread.currrentThread.getName());//这里打印的会是handler thread  setTitle(&哈哈&);//这样必定报错  //android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.& & & }});这样该怎么办呢,呵呵,可以无参构建一个handler。用这个handler来发送消息和处理消息,用上面的handler来开启新线程。mainHandler = new Handler(){  protecket void handlerMessage(Message msg){    setTitle(&哈哈&);//这样就不会报错啦  }}handler.post(new Runnable(){//这里run()方法其实还是在等ht.start()调用  public void run(){  Log.e(&当前线程:&,Thread.currrentThread.getName());//这里打印的会是handler thread  mainHandler.sendEmpetMessage();//用mainHandler来发送消息  //setTitle(&哈哈&);//这样必定报错  //android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.& & & }});打印Log:3.其实第2个方法显得麻烦而且低效,用了2个handler,一个用来发起线程,一个用于处理消息。发起线程的handler必须拥有looper,所以还要实例化一个HanderThread;而处理消息的handler则不需要looper,因为它默认拥有主线程的looper,所以可以在这个handler处理ui。其实可以只需要实例化一个handler,在主线程里构建一个无参的handler,然后由它发送和处理消息。而创建线程的任务就不用handler了,直接用new Thread(r).start();然后在r的run()方法里面处理逻辑事务。用这样的模式下载5张图片,你就可能不会看到图片一张挨着一张展示出来,可能第2张先出来,也可能同时出来3张,5条线程很随机的。private void loadImagesByThread(final String url,final int id){//通过Thread来new 出多个线程&&&&&&& &&&&&&& new Thread(new Runnable(){&&&&&&&&&&& @Override&&&&&&&&&&& public void run() {&&&&&&&&&&&&&&& // TODO Auto-generated method stub&&&&&&&&&&&&&&& Log.e(&当前线程:&, &&+Thread.currentThread().getName());&&&&&&&&&&&&&&& Drawable drawable =&&&&&&&&&&&&&&& try {&&&&&&&&&&&&&&&&&&& drawable = Drawable.createFromStream(new URL(url).openStream(), &image.gif&);&&&&&&&&&&&&&&& } catch (MalformedURLException e) {&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block&&&&&&&&&&&&&&&&&&& e.printStackTrace();&&&&&&&&&&&&&&& } catch (IOException e) {&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block&&&&&&&&&&&&&&&&&&& e.printStackTrace();&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&& Message msg = mainHandler.obtainMessage();&&&&&&&&&&&&&&& msg.what = 2012;&&&&&&&&&&&&&&& msg.arg1 =&&&&&&&&&&&&&&& msg.obj =&&&&&&&&&&&&&&& msg.sendToTarget();&&&&&&&&&&&&&&& &&&&&&&&&&& }&&&&&&&&&&& &&&&&&& }).start();&&& } 打印Log:4.AsyncTask用异步任务架构多任务模型其实也不是很健壮,得创建多个AsyncTask实例。一个AsyncTask仅执行一次,不能重复执行,快餐类的线程,一次用完。实现AsyncTask子类,最重要的两个方法,一个是doInBackground(params);一个是onPostExecute(result)。在doInBackground()方法里处理耗时事务,并把结果返回,返回的值将在onPostExecute方法作为参数,然后就可以在onPostExecute()把结果展示在ui上面了。步骤:①实例化AsyncTask:实例化AsyncTask然后通过task.exec(pamas);传进去参数,这个参数列表是动态的,可以是一个也可以使多个,长度可变。  AsyncTask,第一个参数会传进去这个方法doInBackground(params),第二个参数是数据更新的值,第三个是处理事务返回的结果。②onPreExecute方法:这个方法没有参数,也没有返回值,可以在这个方法里,做一些提醒。比如show一个Dialog,或者弹个Toast告诉用户开始下载啦。③doInBackground(params)方法:进入AsyncTask内部结构,首先将执行reslut&doInBackground(params)方法,这个方法将处理耗时事务,exec()的参数将会传进这个方法做参数,而返回值将会作为onPostExecute()的参数。如果要更新进度的话,需执行publicProgress()方法。④onProgressUpdate(values)方法:这个方法的参数必须在doInBackground()方法里执行publicProgress()方法,这个方法将会把参数传递进onProgressUpdate()方法里,然后可以在这个方法做一些ui上的更新展示,比如进度条的值就可以通过这个values值动态改变。⑤onPostExecute(result)方法:这里就是事务处理完毕的走的方法,doInBackground方法执行的结果将传到这里,如果这个方法返回了数据。在这个方法里可以处理Ui,可以把处理完的数据展示在ui上。比如图片啊,文字啊,一切你想要的结果。private void loadImageByAsyncTask(final String url,final int id){//构建异步任务,这样就不用handler来处理消息了&&&&&&& DownloadTask task = new DownloadTask();&&&&&&& task.execute(&&+id,url);//AsyncTask不可重复执行&&& }&&& &&& class DownloadTask extends AsyncTask{&&&&&&&&&&&&&& @Override&&&&&&& protected Drawable doInBackground(String... params) {//params保存url和控件id两个数据&&&&&&&&&&& // TODO Auto-generated method stub&&&&&&&&&&& Log.e(&当前线程:&, &&+Thread.currentThread().getName());&&&&&&&&&&& Drawable drawable =&&&&&&&&&&& this.id = Integer.parseInt(params[0]);&&&&&&&&&&& try {&&&&&&&&&&&&&&& drawable = Drawable.createFromStream(new URL(params[1]).openStream(), &image.gif&);&&&&&&&&&&& } catch (MalformedURLException e) {&&&&&&&&&&&&&&& // TODO Auto-generated catch block&&&&&&&&&&&&&&& e.printStackTrace();&&&&&&&&&&& } catch (IOException e) {&&&&&&&&&&&&&&& // TODO Auto-generated catch block&&&&&&&&&&&&&&& e.printStackTrace();&&&&&&&&&&& }&&&&&&&&&&& &&&&&&&&&&&&&&&&&& }&&&&&&& @Override&&&&&&& protected void onPostExecute(Drawable result) {&&&&&&&&&&& // TODO Auto-generated method stub&&&&&&&&&&& super.onPostExecute(result);&&&&&&&&&&& ((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(result);&&&&&&& }&&&&&&& @Override&&&&&&& protected void onPreExecute() {&&&&&&&&&&& // TODO Auto-generated method stub&&&&&&&&&&& super.onPreExecute();&&&&&&& }&&&&&&& @Override&&&&&&& protected void onProgressUpdate(Integer... values) {&&&&&&&&&&& // TODO Auto-generated method stub&&&&&&&&&&& super.onProgressUpdate(values);&&&&&&& }&&&&&&& &&& }这里打印的log5.ExecutorServie线程池通过Executors的静态方法来创建,一般有三种:1.单线程 :Executors.newSingleThreadExecutor();2.固定数量线程 :Executors.newFixedThreadPool();3.动态线程 :Executors.newCachedThreadPool();这里我们用固定5个线程来应用,使用方法是创建ExecutorService对象,然后执行submit(r)可以发起一个Runnable对象。用线程池来管理的好处是,可以保证系统稳定运行,适用与有大量线程,高工作量的情景下使用,假如要展示1000张图片如果创建1000个线程去加载,保证系统会死掉。用线程池就可以避免这个问题,可以用5个线程轮流执行,5个一组,执行完的线程不直接回收而是等待下次执行,这样对系统的开销就可以减小不少。private void loadImagesByExecutors(final String url,final int id){&&&&&&& service.submit(new Runnable(){&&&&&&&&&&& &&&&&&&&&&& @Override&&&&&&&&&&& public void run() {&&&&&&&&&&&&&&& // TODO Auto-generated method stub&&&&&&&&&&&&&&& Log.e(&当前线程:&, &&+Thread.currentThread().getName());&&&&&&&&&&&&&&& &&&&&&&&&&&&&&& try {&&&&&&&&&&&&&&&&&&& final Drawable drawable& = Drawable.createFromStream(new URL(url).openStream(), &image.gif&);&&&&&&&&&&&&&&&&&&& mainHandler.post(new Runnable(){&&&&&&&&&&&&&&&&&&&&&&& @Override&&&&&&&&&&&&&&&&&&&&&&& public void run() {//这将在主线程运行&&&&&&&&&&&&&&&&&&&&&&&&&&& // TODO Auto-generated method stub&&&&&&&&&&&&&&&&&&&&&&&&&&& ((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);&&&&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&& });&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&& } catch (MalformedURLException e) {&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block&&&&&&&&&&&&&&&&&&& e.printStackTrace();&&&&&&&&&&&&&&& } catch (IOException e) {&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block&&&&&&&&&&&&&&&&&&& e.printStackTrace();&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&& &&&&&&&&&&& }&&&&&&&&&&& &&&&&&& });&&&&&&& &&& }Log:其实可能没有说清楚,第一种不算多线程。1.loadImagesByHandler()是通过Handler.post()方法,构建两个Handler进行通信。2.loadImagesByThread(),这个是直接new Thread()发起线程,在主线程的handler处理消息3.loadImageByAsyncTask(),这个用的是异步任务,所有实现在它的内部结构里,可以在里头操作Ui.4.loadImagesByExecutors()用的是线程池,使得线程可控,保证稳定运行。其实常用的就是后三种,第二个用法灵活,简单,但不适宜大数量任务;第三个一般适用于单个任务,一次性任务;第四个一般用于大数量,高密度执行的使用情景,比如批量加载图片,批量下载文件等。看一眼图吧:全部源码:&1 package com.bvin.& 2 & 3 import java.io.IOE& 4 import java.net.MalformedURLE& 5 import java.net.URL;& 6 import java.util.concurrent.ExecutorS& 7 import java.util.concurrent.E& 8 & 9 import android.app.A10 import android.graphics.drawable.D11 import android.os.AsyncT12 import android.os.B13 import android.os.H14 import android.os.HandlerT15 import android.os.M16 import android.util.L17 import android.view.V18 import android.widget.B19 import android.widget.ImageV20 21 public class MainActivity extends Activity {22&&&& /** Called when the activity is first created. */23&&&& 24&&&& private H25&&&& private B26&&&& private Handler mainHandler = new Handler(){27 28&&&&&&&& @Override29&&&&&&&& public void handleMessage(Message msg) {30&&&&&&&&&&&& // TODO Auto-generated method stub31&&&&&&&&&&&& super.handleMessage(msg);32&&&&&&&&&&&& if(msg.what == 2012){33&&&&&&&&&&&&&&&& //只要在主线程就可以处理ui 34&&&&&&&&&&&&&&&& ((ImageView)MainActivity.this.findViewById(msg.arg1)).setImageDrawable((Drawable)msg.obj);35&&&&&&&&&&&& }36&&&&&&&& }37&&&&&&&& 38&&&&&&&& 39&&&& };40&&&& 41&&&& private ExecutorService service = Executors.newFixedThreadPool(5);42&&&& 43&&&& @Override44&&&& public void onCreate(Bundle savedInstanceState) {45&&&&&&&& super.onCreate(savedInstanceState);46&&&&&&&& setContentView(R.layout.main);47&&&&&&&& initViews();48&&&&&&&& HandlerThread ht = new HandlerThread(&down image thread&);49&&&&&&&& ht.start();50&&&&&&&& handler = new Handler(ht.getLooper()){//如果有了looper那么这个handler就不可以处理ui了51 52&&&&&&&&&&&& @Override53&&&&&&&&&&&& public void handleMessage(Message msg) {54&&&&&&&&&&&&&&&& // TODO Auto-generated method stub55&&&&&&&&&&&&&&&& super.handleMessage(msg);56&&&&&&&&&&&&&&&& 57&&&&&&&&&&&&&&&& 58&&&&&&&&&&&& }59&&&&&&&&&&&& 60&&&&&&&& };61&&&&&&&& 62&&&& }63&&&& 64&&&& private void initViews(){65&&&&&&&& 66&&&&&&&& bt = (Button)findViewById(R.id.bt);67&&&&&&&& bt.setOnClickListener(new View.OnClickListener() {68&&&&&&&&&&&& 69&&&&&&&&&&&& @Override70&&&&&&&&&&&& public void onClick(View v) {71&&&&&&&&&&&&&&&& // TODO Auto-generated method stub72&&&&&&&&&&&&&&&& loadImagesByExecutors(&/z/resource/r/image//23c1625aca99f02c50d8ee7.jpg&,R.id.iv1);73&&&&&&&&&&&&&&&& loadImagesByExecutors(&/z/resource/r/image//cd733c7beb3.jpg&,R.id.iv2);74&&&&&&&&&&&&&&&& loadImagesByExecutors(&/z/resource/r/image//f332ffe433be2abff5a40.jpg&,R.id.iv3);75&&&&&&&&&&&&&&&& loadImagesByExecutors(&/z/resource/r/image//6ff8a9c647a1e80bc602eeda48865d4c.jpg&,R.id.iv4);76&&&&&&&&&&&&&&&& loadImagesByExecutors(&/z/resource/r/image//f104d069f7443dca52a878d.jpg&,R.id.iv5);77&&&&&&&&&&&& }78&&&&&&&& });79&&&& }80&&&& 81&&&& private void loadImagesByHandler(final String url,final int id){//通过拥有looper的handler.post(runnable),新建线程82&&&&&&&& 83&&&&&&&& 84&&&&&&&& handler.post(new Runnable(){//如果handler没有Looper那么它就不能构建新线程了85 86&&&&&&&&&&&& @Override87&&&&&&&&&&&& public void run() {88&&&&&&&&&&&&&&&& // TODO Auto-generated method stub89&&&&&&&&&&&&&&&& Log.e(&当前线程:&, &&+Thread.currentThread().getName());90&&&&&&&&&&&&&&&& Drawable drawable =91&&&&&&&&&&&&&&&& try {92&&&&&&&&&&&&&&&&&&&& drawable = Drawable.createFromStream(new URL(url).openStream(), &image.gif&);93&&&&&&&&&&&&&&&& } catch (MalformedURLException e) {94&&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block95&&&&&&&&&&&&&&&&&&&& e.printStackTrace();96&&&&&&&&&&&&&&&& } catch (IOException e) {97&&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block98&&&&&&&&&&&&&&&&&&&& e.printStackTrace();99&&&&&&&&&&&&&&&& }100&&&&&&&&&&&&&&&& //SystemClock.sleep(2000);101&&&&&&&&&&&&&&&& //((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);102&&&&&&&&&&&&&&&& Message msg = mainHandler.obtainMessage();103&&&&&&&&&&&&&&&& msg.what = 2012;104&&&&&&&&&&&&&&&& msg.arg1 =105&&&&&&&&&&&&&&&& msg.obj =106&&&&&&&&&&&&&&&& msg.sendToTarget();107&&&&&&&&&&&& }108&&&&&&&&&&&& 109&&&&&&&& });110&&&&&&&& 111&&&&&&&& 112&&&& }113&&&& 114&&&& private void loadImagesByThread(final String url,final int id){//通过Thread来new 出多个线程115&&&&&&&& 116&&&&&&&& new Thread(new Runnable(){117 118&&&&&&&&&&&& @Override119&&&&&&&&&&&& public void run() {120&&&&&&&&&&&&&&&& // TODO Auto-generated method stub121&&&&&&&&&&&&&&&& Log.e(&当前线程:&, &&+Thread.currentThread().getName());122&&&&&&&&&&&&&&&& Drawable drawable =123&&&&&&&&&&&&&&&& try {124&&&&&&&&&&&&&&&&&&&& drawable = Drawable.createFromStream(new URL(url).openStream(), &image.gif&);125&&&&&&&&&&&&&&&& } catch (MalformedURLException e) {126&&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block127&&&&&&&&&&&&&&&&&&&& e.printStackTrace();128&&&&&&&&&&&&&&&& } catch (IOException e) {129&&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block130&&&&&&&&&&&&&&&&&&&& e.printStackTrace();131&&&&&&&&&&&&&&&& }132&&&&&&&&&&&&&&&& Message msg = mainHandler.obtainMessage();133&&&&&&&&&&&&&&&& msg.what = 2012;134&&&&&&&&&&&&&&&& msg.arg1 =135&&&&&&&&&&&&&&&& msg.obj =136&&&&&&&&&&&&&&&& msg.sendToTarget();137&&&&&&&&&&&&&&&& 138&&&&&&&&&&&& }139&&&&&&&&&&&& 140&&&&&&&& }).start();141&&&& } 142 143&&&& private void loadImageByAsyncTask(final String url,final int id){//构建异步任务,这样就不用handler来处理消息了144&&&&&&&& DownloadTask task = new DownloadTask();145&&&&&&&& task.execute(&&+id,url);//AsyncTask不可重复执行146&&&& }147&&&& 148&&&& private void loadImagesByExecutors(final String url,final int id){149&&&&&&&& service.submit(new Runnable(){150&&&&&&&&&&&& 151&&&&&&&&&&&& @Override152&&&&&&&&&&&& public void run() {153&&&&&&&&&&&&&&&& // TODO Auto-generated method stub154&&&&&&&&&&&&&&&& Log.e(&当前线程:&, &&+Thread.currentThread().getName());155&&&&&&&&&&&&&&&& 156&&&&&&&&&&&&&&&& try {157&&&&&&&&&&&&&&&&&&&& final Drawable drawable& = Drawable.createFromStream(new URL(url).openStream(), &image.gif&);158&&&&&&&&&&&&&&&&&&&& mainHandler.post(new Runnable(){159 160&&&&&&&&&&&&&&&&&&&&&&&& @Override161&&&&&&&&&&&&&&&&&&&&&&&& public void run() {//这将在主线程运行162&&&&&&&&&&&&&&&&&&&&&&&&&&&& // TODO Auto-generated method stub163&&&&&&&&&&&&&&&&&&&&&&&&&&&& ((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);164&&&&&&&&&&&&&&&&&&&&&&&& }165&&&&&&&&&&&&&&&&&&&& });166&&&&&&&&&&&&&&&&&&&& 167&&&&&&&&&&&&&&&& } catch (MalformedURLException e) {168&&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block169&&&&&&&&&&&&&&&&&&&& e.printStackTrace();170&&&&&&&&&&&&&&&& } catch (IOException e) {171&&&&&&&&&&&&&&&&&&&& // TODO Auto-generated catch block172&&&&&&&&&&&&&&&&&&&& e.printStackTrace();173&&&&&&&&&&&&&&&& }174&&&&&&&&&&&&&&&& 175&&&&&&&&&&&& }176&&&&&&&&&&&& 177&&&&&&&& });178&&&&&&&& 179&&&& }180&&&& 181&&&& class DownloadTask extends AsyncTask{182 183&&&&&&&&184&&&&&&&& @Override185&&&&&&&& protected Drawable doInBackground(String... params) {//params保存url和控件id两个数据186&&&&&&&&&&&& // TODO Auto-generated method stub187&&&&&&&&&&&& Log.e(&当前线程:&, &&+Thread.currentThread().getName());188&&&&&&&&&&&& Drawable drawable =189&&&&&&&&&&&& this.id = Integer.parseInt(params[0]);190&&&&&&&&&&&& try {191&&&&&&&&&&&&&&&& drawable = Drawable.createFromStream(new URL(params[1]).openStream(), &image.gif&);192&&&&&&&&&&&& } catch (MalformedURLException e) {193&&&&&&&&&&&&&&&& // TODO Auto-generated catch block194&&&&&&&&&&&&&&&& e.printStackTrace();195&&&&&&&&&&&& } catch (IOException e) {196&&&&&&&&&&&&&&&& // TODO Auto-generated catch block197&&&&&&&&&&&&&&&& e.printStackTrace();198&&&&&&&&&&&& }199&&&&&&&&&&&& 200&&&&&&&&&&&&201&&&&&&&& }202 203&&&&&&&& @Override204&&&&&&&& protected void onPostExecute(Drawable result) {205&&&&&&&&&&&& // TODO Auto-generated method stub206&&&&&&&&&&&& super.onPostExecute(result);207&&&&&&&&&&&& ((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(result);208&&&&&&&& }209 210&&&&&&&& @Override211&&&&&&&& protected void onPreExecute() {212&&&&&&&&&&&& // TODO Auto-generated method stub213&&&&&&&&&&&& super.onPreExecute();214&&&&&&&& }215 216&&&&&&&& @Override217&&&&&&&& protected void onProgressUpdate(Integer... values) {218&&&&&&&&&&&& // TODO Auto-generated method stub219&&&&&&&&&&&& super.onProgressUpdate(values);220&&&&&&&& }221 222&&&&&&&& 223&&&& }224 }
08-2005-2804-1212-1311-2911-2511-1711-1509-3002-13
阅读本文后您有什么感想? 已有23人给出评价!
名称大小下载}

我要回帖

更多关于 android多线程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信