【免费下载】Android开发中的多线程编程技术

合集下载

Android 多线程和异步处理

Android 多线程和异步处理

Android 多线程和异步处理Android操作系统是基于Linux内核的,而Linux内核天生支持多线程的能力。

在Android开发中,多线程和异步处理是必不可少的技术。

本文将介绍Android多线程和异步处理的相关知识。

一、多线程概述多线程是指在一个进程中同时执行多个线程,每个线程都是独立运行的,可以完整的拥有自己的资源和运行环境。

在Android应用中,多线程的使用可以提高程序的性能和用户体验。

1.1 多线程的优点通过使用多线程,可以将一些耗时的操作和主线程分开,提高程序的响应速度。

同时,多线程还可以充分利用多核处理器的计算能力,提高程序的运行效率。

1.2 多线程的分析与设计在使用多线程时,需要充分考虑线程安全性和资源的合理分配。

可以使用线程池来管理和控制线程的创建和销毁,使得线程的创建和销毁过程更加高效。

二、Android多线程实现方式Android中提供了多种多线程的实现方式,下面将介绍几种常见的实现方式。

2.1 继承Thread类继承Thread类是一种常见的实现多线程的方式。

通过继承Thread 类并重写run方法,可以实现自定义的线程功能。

```javapublic class MyThread extends Thread{@Overridepublic void run(){// 线程执行的代码}}```2.2 实现Runnable接口实现Runnable接口是另一种实现多线程的方式。

通过实现Runnable接口并实现run方法,也可以实现自定义的线程功能。

```javapublic class MyRunnable implements Runnable{@Overridepublic void run(){// 线程执行的代码}```2.3 使用Handler实现多线程在Android开发中,我们经常需要在子线程中更新UI界面。

这时可以使用Handler来实现多线程和UI更新的交互。

android 多线程面试题

android 多线程面试题

android 多线程面试题Android多线程面试题Android多线程是一个重要的技术,对于开发者来说,掌握多线程编程是非常必要的。

在Android面试中,经常会出现与多线程相关的问题。

下面将介绍一些常见的Android多线程面试题,希望能够帮助你在面试中更好地回答问题。

1. 什么是多线程?多线程是指在一个进程中同时执行多个任务的技术。

在Android中,多线程可以实现在后台同时进行多个任务,以提升用户体验和应用性能。

2. 在Android中有哪些实现多线程的方式?在Android中,有以下几种实现多线程的方式:a. 使用Thread类:可以通过继承Thread类或者创建Thread匿名内部类的方式来创建线程对象,重写run()方法来定义线程执行的操作。

b. 使用Runnable接口:通过创建一个实现Runnable接口的类的实例,将其作为参数传递给Thread类的构造函数来创建线程。

c. 使用HandlerThread类:HandlerThread是继承自Thread的一个类,它内部封装了一个Looper和Handler,可以方便地实现线程间的通信。

d. 使用AsyncTask类:AsyncTask是一个封装了异步操作的类,它可以在后台执行耗时操作,并在主线程更新UI。

3. 什么是主线程和子线程?主线程是指应用程序的主要执行线程,也称为UI线程。

它负责处理用户交互、更新UI等操作。

子线程是在主线程之外创建的线程,用于执行一些耗时的操作,以保证主线程不会被阻塞。

4. 如何在子线程中更新UI?在Android中,UI更新必须在主线程中进行,但有时需要在子线程中执行一些耗时操作。

可以通过以下几种方式在子线程中更新UI:a. 使用Handler:可以在子线程中通过Handler发送消息给主线程,然后在主线程中通过Handler处理消息,更新UI。

b. 使用runOnUiThread()方法:可以在子线程中通过Activity的runOnUiThread()方法来直接更新UI。

全面详解Android实现多线程的几种方式(史上最全最详细)

全面详解Android实现多线程的几种方式(史上最全最详细)

全面详解Android实现多线程的几种方式(史上最全最详细)Android是一个基于Linux内核的开源操作系统,为移动设备提供了丰富的应用开发平台。

在开发过程中,多线程的使用是非常常见的,能够提升程序的性能和用户体验。

本文将全面详解Android实现多线程的几种方式,从线程的基本概念到具体的实现方法,让您全面了解Android多线程编程。

一、线程的基本概念在计算机科学中,线程是指程序中执行的最小单位,它是进程的一部分,可以独立运行、相互合作。

与进程不同的是,进程是操作系统分配资源的最小单位。

一个进程包含多个线程,它们共享进程的资源,可以同时执行。

Android中的线程是通过Thread类实现的。

每个线程对象都有一个run方法,它包含了线程要执行的代码。

二、实现多线程的几种方式1. 继承Thread类继承Thread类是最直接的实现多线程的方式。

具体步骤如下:(1)创建一个继承自Thread类的自定义类,重写run方法。

```public class MyThread extends Threadpublic void ru//线程要执行的代码}```(2)创建MyThread类的实例,并调用start方法启动线程。

```MyThread myThread = new MyThread(;myThread.start(;```2. 实现Runnable接口实现Runnable接口是更常用的实现多线程的方式。

具体步骤如下:(1)创建一个实现Runnable接口的自定义类,重写run方法。

```public class MyRunnable implements Runnablepublic void ru//线程要执行的代码}```(2)创建MyRunnable类的实例,并通过Thread类的构造方法传递给一个新的线程对象。

MyRunnable myRunnable = new MyRunnable(;Thread thread = new Thread(myRunnable);thread.start(;```3.使用线程池线程池是一种管理和复用线程的机制,可以减少线程创建、销毁的开销,提高性能。

android handlerthread用法

android handlerthread用法

android handlerthread用法Android HandlerThread是Android开发中常用的多线程处理工具。

它能够在后台线程中执行任务,并通过Handler与UI线程进行通信。

本文将详细介绍HandlerThread的用法,以及如何使用它来实现多线程任务处理。

一、什么是HandlerThread?HandlerThread是Android中的一个类,继承自Thread,并实现了Looper接口。

它在后台线程中提供了一个消息循环机制,可以用来处理耗时的任务。

二、使用HandlerThread的步骤1. 创建HandlerThread实例首先,我们需要创建一个HandlerThread的实例,并给它一个有意义的名称。

例如,可以创建一个名为"BackgroundThread"的HandlerThread 实例:javaHandlerThread handlerThread = newHandlerThread("BackgroundThread");2. 启动HandlerThread接下来,我们需要调用HandlerThread的start方法来启动它的线程:javahandlerThread.start();3. 创建Handler然后,我们可以通过HandlerThread的getLooper方法获得一个Looper 实例,并将其用于创建一个Handler对象:javaHandler handler = new Handler(handlerThread.getLooper());通过这个Handler,我们可以在后台线程中发送和处理消息。

4. 发送消息现在我们可以在UI线程中通过Handler发送消息到后台线程中进行处理。

例如,我们可以发送一个Runnable对象到后台线程中执行:javahandler.post(new Runnable() {@Overridepublic void run() {在后台线程中执行耗时任务...}});5. 处理消息在HandlerThread的内部实现中,它会不断地从消息队列中取出消息并处理。

Android下使用Http协议实现多线程断点续传下载

Android下使用Http协议实现多线程断点续传下载

0.使用多线程下载会提升文件下载的速度,那么多线程下载文件的过程是:(1)首先获得下载文件的长度,然后设置本地文件的长度HttpURLConnection.getContentLength();RandomAccessFile file = new RandomAccessFile("QQWubiSetup.exe","rwd");file.setLength(filesize);//设置本地文件的长度(2)根据文件长度和线程数计算每条线程下载的数据长度和下载位置。

如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如下图所示。

例如10M大小,使用3个线程来下载,线程下载的数据长度 (10%3 == 0 ? 10/3:10/3+1) ,第1,2个线程下载长度是4M,第三个线程下载长度为2M下载开始位置:线程id*每条线程下载的数据长度 = ?下载结束位置:(线程id+1)*每条线程下载的数据长度-1=?(3)使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,如:指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止代码如下:HttpURLConnection.setRequestProperty("Range","bytes=2097152-4194303");(4)保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。

RandomAccessFile threadfile = new RandomAccessFile("QQWubiSetup.exe ","rwd");threadfile.seek(2097152);//从文件的什么位置开始写入数据1.多线程下载的核心代码示例Java代码1.public class MulThreadDownload2.{3. /**4. * 多线程下载5. * @param args6. */7. public static void main(String[] args)8. {9. String path = "/QQWubiSetup.exe";10. try11. {12. new MulThreadDownload().download(path, 3);13. }14. catch (Exception e)15. {16. e.printStackTrace();17. }18. }19. /**20. * 从路径中获取文件名称21. * @param path 下载路径22. * @return23. */24. public static String getFilename(String path)25. {26. return path.substring(stIndexOf('/')+1);27. }28. /**29. * 下载文件30. * @param path 下载路径31. * @param threadsize 线程数32. */33. public void download(String path, int threadsize) throwsException34. {35. URL url = new URL(path);36. HttpURLConnection conn = (HttpURLConnection)url.openConnection();37. conn.setRequestMethod("GET");38. conn.setConnectTimeout(5 * 1000);39. //获取要下载的文件的长度40. int filelength = conn.getContentLength();41. //从路径中获取文件名称42. String filename = getFilename(path);43. File saveFile = new File(filename);44. RandomAccessFile accessFile = new RandomAccessFile(saveFile, "rwd");45. //设置本地文件的长度和下载文件相同46. accessFile.setLength(filelength);47. accessFile.close();48. //计算每条线程下载的数据长度49. int block = filelength%threadsize==0? filelength/threadsize : filelength/threadsize+1;50. for(int threadid=0 ; threadid < threadsize ; threadid++){51. new DownloadThread(url, saveFile, block, threadid).start();52. }53. }54.55. private final class DownloadThread extends Thread56. {57. private URL url;58. private File saveFile;59. private int block;//每条线程下载的数据长度60. private int threadid;//线程id61. public DownloadThread(URL url, File saveFile, int block, int threadid)62. {63. this.url = url;64. this.saveFile = saveFile;65. this.block = block;66. this.threadid = threadid;67. }68.@Override69. public void run()70. {71. //计算开始位置公式:线程id*每条线程下载的数据长度= ?72. //计算结束位置公式:(线程id +1)*每条线程下载的数据长度-1 =?73. int startposition = threadid * block;74. int endposition = (threadid + 1 ) * block - 1;75. try76. {77. RandomAccessFile accessFile = new RandomAccessFile(saveFile, "rwd");78. //设置从什么位置开始写入数据79. accessFile.seek(startposition);80. HttpURLConnection conn = (HttpURLConnection)url.openConnection();81. conn.setRequestMethod("GET");82. conn.setConnectTimeout(5 * 1000);83. conn.setRequestProperty("Range", "bytes="+ startposition+ "-"+ endposition);84. InputStream inStream = conn.getInputStream();85. byte[] buffer = new byte[1024];86. int len = 0;87. while( (len=inStream.read(buffer)) != -1 )88. {89. accessFile.write(buffer, 0, len);90. }91. inStream.close();92. accessFile.close();93. System.out.println("线程id:"+ threadid+ "下载完成");94. }95. catch (Exception e)96. {97. e.printStackTrace();98. }99. }100. }101.}2.多线程断点下载功能,这里把断点数据保存到数据库中:注意代码注释的理解(0)主Activity,关键点使用Handler更新进度条与开启线程下载避免ANR若不使用Handler却要立即更新进度条数据,可使用://resultView.invalidate(); UI线程中立即更新进度条方法//resultView.postInvalidate(); 非UI线程中立即更新进度条方法Java代码1./**2. * 注意这里的设计思路,UI线程与参数保存问题,避免ANR问题,UI控件的显示3. * @author kay4. *5. */6.public class DownloadActivity extends Activity7.{8. private EditText downloadpathText;9. private TextView resultView;10. private ProgressBar progressBar;11.12.@Override13. public void onCreate(Bundle savedInstanceState)14. {15. super.onCreate(savedInstanceState);16. setContentView(yout.main);17.18. downloadpathText = (EditText) this.findViewById(R.id.downloadpath);19. progressBar = (ProgressBar) this.findViewById(R.id.downloadbar);20. resultView = (TextView) this.findViewById(R.id.result);21. Button button = (Button) this.findViewById(R.id.button);22. button.setOnClickListener(new View.OnClickListener()23. {24.@Override25. public void onClick(View v)26. {27. //取得下载路径28. String path = downloadpathText.getText().toString();29. //判断SDCard是否存在30. if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))31. {32. //下载操作33. download(path, Environment.getExternalStorageDirectory());34. }35. else36. {37. Toast.makeText(DownloadActivity.this, R.string.sdcarderror, 1).show();38. }39. }40. });41. }42. //主线程(UI线程)43. //业务逻辑正确,但是该程序运行的时候有问题(可能出现ANR问题)44. //对于显示控件的界面更新只是由UI线程负责,如果是在非UI线程更新控件的属性值,更新后的显示界面不会反映到屏幕上45. /**46. * 参数类型:因为启动一个线程还需要使用到上面方法的参数,而主方法启动后很快就会销毁,47. * 那么使用Final可以解决参数丢失的问题48. * path 注意是Final类型49. * savedir 注意是Final类型50. */51. private void download(final String path, final File savedir)52. {53. //这里开启一个线程避免ANR错误54. new Thread(new Runnable()55. {56.@Override57. public void run()58. {59. FileDownloader loader = new FileDownloader(DownloadActivity.this, path, savedir, 3);60. //设置进度条的最大刻度为文件的长度61. progressBar.setMax(loader.getFileSize());62. try63. {64. loader.download(new DownloadProgressListener()65. {66. /**67. * 注意这里的设计,显示进度条数据需要使用Handler来处理68. * 因为非UI线程更新后的数据不能被刷新69. */70.@Override71. public void onDownloadSize(int size)72. {73. //实时获知文件已经下载的数据长度74. Message msg = new Message();75. //设置消息标签76. msg.what = 1;77. msg.getData().putInt("size", size);78. //使用Handler对象发送消息79. handler.sendMessage(msg);80. }81. });82. }83. catch (Exception e)84. {85. //发送一个空消息到消息队列86. handler.obtainMessage(-1).sendToTarget();87. /**88. * 或者使用下面的方法发送一个空消息89. * Message msg = new Message();90. * msg.what = 1;91. * handler.sendMessage(msg);92. */93. }94. }95. }).start();96. }97.98.99. /**Handler原理:当Handler被创建时会关联到创建它的当前线程的消息队列,该类用于往消息队列发送消息100. *101. * 消息队列中的消息由当前线程内部进行处理102. */103. private Handler handler = new Handler()104. {105. //重写Handler里面的handleMessage方法处理消息106.@Override107. public void handleMessage(Message msg)108. {109. switch (msg.what)110. {111. case 1:112. //进度条显示113. progressBar.setProgress(msg.getData().getInt("size"));114. float num = (float)progressBar.getProg ress()/(float)progressBar.getMax();115. int result = (int)(num*100);116. //resultView.invalidate(); UI线程中立即更新进度条方法117. //resultView.postInvalidate(); 非UI线程中立即更新进度条方法118. resultView.setText(result+ "%"); 119. //判断是否下载成功120. if(progressBar.getProgress()==progress Bar.getMax())121. {122. Toast.makeText(DownloadActivity.th is, R.string.success, 1).show();123. }124. break;125. case -1:126. Toast.makeText(DownloadActivity.this, R.string.error, 1).show();127. break;128. }129. }130. };131.132.}(1)下载类:注意计算每条线程的下载长度与下载起始位置的方法Java代码1.public class DownloadThread extends Thread2.{3. private static final String TAG = "DownloadThread";4. private File saveFile;5. private URL downUrl;6. private int block;7. //下载开始位置8. private int threadId = -1;9. //下载文件长度10. private int downLength;11. private boolean finish = false;12. private FileDownloader downloader;13. public DownloadThread(FileDownloader downloader, URL downUrl, File saveFile, int block, int downLength, int threadId)14. {15. this.downUrl = downUrl;16. this.saveFile = saveFile;17. this.block = block;18. this.downloader = downloader;19. this.threadId = threadId;20. this.downLength = downLength;21. }22.23.@Override24. public void run()25. {26. //未下载完成27. if(downLength < block)28. {29. try30. {31. HttpURLConnection http = (HttpURLConnection)downUrl.openConnection();32. http.setConnectTimeout(5 * 1000);33. http.setRequestMethod("GET");34. http.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, applicati on/vnd.ms-excel, application/vnd.ms-powerpoint, application/ms word, */*");35. http.setRequestProperty("Accept-Language", "zh-CN");36. http.setRequestProperty("Referer", downUrl.toString());37. http.setRequestProperty("Charset", "UTF-8");38. //下载开始位置:线程id*每条线程下载的数据长度 = ?39. int startPos = block * (threadId - 1) + downLength;40. //下载结束位置:(线程id+1)*每条线程下载的数据长度-1=?41. int endPos = block * threadId -1;42. //设置获取实体数据的范围43. http.setRequestProperty("Range", "bytes=" + startPos + "-"+ endPos);44. http.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");45. http.setRequestProperty("Connection", "Keep-Alive");46.47. InputStream inStream = http.getInputStream();48. byte[] buffer = new byte[1024];49. int offset = 0;50. print("Thread " + this.threadId + " start download from position "+ startPos);51. RandomAccessFile threadfile = new RandomAccessFile(this.saveFile, "rwd");52. threadfile.seek(startPos);53. while ((offset = inStream.read(buffer, 0, 1024)) != -1)54. {55. threadfile.write(buffer, 0, offset);56. downLength += offset;57. downloader.update(this.threadId, downLength);58. downloader.append(offset);59. }60. threadfile.close();61. inStream.close();62. print("Thread " + this.threadId + " downloadfinish");63. //标记是否完成64. this.finish = true;65. }66. catch (Exception e)67. {68. this.downLength = -1;69. print("Thread "+ this.threadId+ ":"+ e);70. }71. }72. }73.74. private static void print(String msg)75. {76. Log.i(TAG, msg);77. }78.79. /**80. * 下载是否完成81. * @return82. */83. public boolean isFinish()84. {85. return finish;86. }87.88. /**89. * 已经下载的内容大小90. * @return 如果返回值为-1,代表下载失败91. */92. public long getDownLength()93. {94. return downLength;95. }96.}文件下载器,使用Java代码1./**2. * 文件下载器,使用这个类的方法如下示例:3. * FileDownloader loader = new FileDownloader(context, "http:///ejb3/ActivePort.exe",4. * new File("D:\\androidsoft\\test"), 2);5. * loader.getFileSize();//得到文件总大小6. * try {7. * loader.download(new DownloadProgressListener(){8. * public void onDownloadSize(int size) {9. * print("已经下载:"+ size);10. * }11. * });12. * }13. * catch (Exception e)14. * {15. * e.printStackTrace();16. * }17. */18.public class FileDownloader19.{20. private static final String TAG = "FileDownloader";21. private Context context;22. private FileService fileService;23. //已下载文件长度24. private int downloadSize = 0;25. //原始文件长度26. private int fileSize = 0;27. ///线程数28. private DownloadThread[] threads;29. //本地保存文件30. private File saveFile;31. //缓存各线程下载的长度32. private Map<Integer, Integer> data = new ConcurrentHashMap<Integer, Integer>();33. //每条线程下载的长度34. private int block;35. //下载路径36. private String downloadUrl;37. //获取线程数38. public int getThreadSize()39. {40. return threads.length;41. }42. /**43. * 获取文件大小44. * @return45. */46. public int getFileSize()47. {48. return fileSize;49. }50. /**51. * 累计已下载大小52. * @param size53. */54. protected synchronized void append(int size)55. {56. downloadSize += size;57. }58. /**59. * 更新指定线程最后下载的位置60. * @param threadId 线程id61. * @param pos 最后下载的位置62. */63. protected synchronized void update(int threadId, int pos)64. {65. this.data.put(threadId, pos);66. this.fileService.update(this.downloadUrl, this.data);67. }68. /**69. * 文件下载构造器70. * @param downloadUrl 下载路径71. * @param fileSaveDir 文件保存目录72. * @param threadNum 下载线程数73. */74. public FileDownloader(Context context, String downloadUrl, File fileSaveDir, int threadNum)75. {76. try77. {78. this.context = context;79. this.downloadUrl = downloadUrl;80. fileService = new FileService(this.context);81. URL url = new URL(this.downloadUrl);82. if(!fileSaveDir.exists()) fileSaveDir.mkdirs();83. this.threads = new DownloadThread[threadNum];84. HttpURLConnection conn = (HttpURLConnection) url.openConnection();85. conn.setConnectTimeout(5*1000);86. conn.setRequestMethod("GET");87. conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-fla sh, application/xaml+xml, application/vnd.ms-xpsdocument, appl ication/x-ms-xbap, application/x-ms-application, application/v nd.ms-excel, application/vnd.ms-powerpoint, application/msword , */*");88. conn.setRequestProperty("Accept-Language", "zh-CN");89. conn.setRequestProperty("Referer", downloadUrl);90. conn.setRequestProperty("Charset", "UTF-8");91. conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR1.1.4322; .NET CLR2.0.50727; .NET CLR3.0.04506.30; .NET CLR3.0.4506.2152; .NET CLR 3.5.30729)");92. conn.setRequestProperty("Connection", "Keep-Alive");93. conn.connect();94. printResponseHeader(conn);95. if (conn.getResponseCode()==200)96. {97. //根据响应获取文件大小98. this.fileSize = conn.getContentLength();99. if (this.fileSize <= 0) throw new RuntimeException("Unkown file size ");100. //获取文件名称101. String filename = getFileName(conn); 102. //构建保存文件103. this.saveFile = new File(fileSaveDir, file name);104. //获取下载记录105. Map<Integer, Integer> logdata = fileService.getData(downloadUrl);106. //如果存在下载记录107. if(logdata.size()>0)108. {109. //把各条线程已经下载的数据长度放入data 中110. for(Map.Entry<Integer, Integer> entry : logdata.entrySet())111. data.put(entry.getKey(), entry.get Value());112. }113. //下面计算所有线程已经下载的数据长度114. if(this.data.size()==this.threads.length)115. {116. for (int i = 0; i < this.threads.lengt h; i++)117. {118. this.downloadSize += this.data.get (i+1);119. }120. print("已经下载的长度"+ this.downloadSize);121. }122. //计算每条线程下载的数据长度123. this.block = (this.fileSize % this.threads .length)==0? this.fileSize / this.threads.length : this.fileSi ze / this.threads.length + 1;124. }125. else126. {127. throw new RuntimeException("server no resp onse ");128. }129. }130. catch (Exception e)131. {132. print(e.toString());133. throw new RuntimeException("don't connection t his url");134. }135. }136. /**137. * 获取文件名138. */139. private String getFileName(HttpURLConnection conn) 140. {141. String filename = this.downloadUrl.substring(this.stIndexOf('/') + 1);142. if(filename==null || "".equals(filename.trim())){/ /如果获取不到文件名称143. for (int i = 0;; i++) {144. String mine = conn.getHeaderField(i); 145. if (mine == null) break;146. if("content-disposition".equals(conn.getHe aderFieldKey(i).toLowerCase())){147. Matcher m = pile(".*filenam e=(.*)").matcher(mine.toLowerCase());148. if(m.find()) return m.group(1); 149. }150. }151. filename = UUID.randomUUID()+ ".tmp";//默认取一个文件名152. }153. return filename;154. }155.156. /**157. * 开始下载文件158. * @param listener 监听下载数量的变化,如果不需要了解实时下载的数量,可以设置为null159. * @return 已下载文件大小160. * @throws Exception161. */162. public int download(DownloadProgressListener listener) throws Exception{163. try164. {165. //创建本地文件166. RandomAccessFile randOut = new RandomAccessFil e(this.saveFile, "rw");167. if(this.fileSize>0) randOut.setLength(this.fil eSize);168. randOut.close();169. URL url = new URL(this.downloadUrl);170. if(this.data.size() != this.threads.length) 171. {172. this.data.clear();173. for (int i = 0; i < this.threads.length; i ++)174. {175. //初始化每条线程已经下载的数据长度为176. this.data.put(i+1, 0);177. }178. }179. //开启线程进行下载180. for (int i = 0; i < this.threads.length; i++)181. {182. int downLength = this.data.get(i+1); 183. //判断线程是否已经完成下载,否则继续下载184. if(downLength < this.block && this.downloa dSize<this.fileSize)185. {186. this.threads[i] = new DownloadThread(t his, url, this.saveFile, this.block, this.data.get(i+1), i+1);187. this.threads[i].setPriority(7);//可删除这条188. this.threads[i].start();189. }190. else191. {192. this.threads[i] = null;193. }194. }195. this.fileService.save(this.downloadUrl, this.d ata);196. //下载未完成197. boolean notFinish = true;198. // 循环判断所有线程是否完成下载199. while (notFinish)200. {201. Thread.sleep(900);202. //假定全部线程下载完成203. notFinish = false;204. for (int i = 0; i < this.threads.length; i ++)205. {206. //如果发现线程未完成下载207. if (this.threads[i] != null && !this.t hreads[i].isFinish())208. {209. //设置标志为下载没有完成210. notFinish = true;211. //如果下载失败,再重新下载212. if(this.threads[i].getDownLength() == -1)213. {214. this.threads[i] = new Download Thread(this, url, this.saveFile, this.block, this.data.get(i+1 ), i+1);215. this.threads[i].setPriority(7) ;216. this.threads[i].start(); 217. }218. }219. }220. //通知目前已经下载完成的数据长度221. if(listener!=null) listener.onDownloadSize (this.downloadSize);222. }223. //删除数据库中下载信息224. fileService.delete(this.downloadUrl);225. }226. catch (Exception e)227. {228. print(e.toString());229. throw new Exception("file download fail"); 230. }231. return this.downloadSize;232. }233.234. /**235. * 获取Http响应头字段236. * @param http237. * @return238. */239. public static Map<String, String> getHttpResponseHeade r(HttpURLConnection http) {240. Map<String, String> header = new LinkedHashMap<Str ing, String>();241. for (int i = 0;; i++) {242. String mine = http.getHeaderField(i); 243. if (mine == null) break;244. header.put(http.getHeaderFieldKey(i), mine);245. }246. return header;247. }248. /**249. * 打印Http头字段250. * @param http251. */252. public static void printResponseHeader(HttpURLConnecti on http)253. {254. Map<String, String> header = getHttpResponseHeader (http);255. for(Map.Entry<String, String> entry : header.entry Set())256. {257. String key = entry.getKey()!=null ? entry.getK ey()+ ":" : "";258. print(key+ entry.getValue());259. }260. }261. private static void print(String msg)262. {263. Log.i(TAG, msg);264. }265.}Java代码1.public interface DownloadProgressListener2.{3. public void onDownloadSize(int size);4.}(2)文件操作,断点数据库存储Java代码1.public class DBOpenHelper extends SQLiteOpenHelper2.{3. private static final String DBNAME = "itcast.db";4. private static final int VERSION = 1;5.6. public DBOpenHelper(Context context)7. {8. super(context, DBNAME, null, VERSION);9. }10.11.@Override12. public void onCreate(SQLiteDatabase db)13. {14. db.execSQL("CREATE TABLE IF NOT EXISTS filedownlog (id integer primary key autoincrement, downpath varchar(100), threadid INTEGER, downlength INTEGER)");15. }16.@Override17. public void onUpgrade(SQLiteDatabase db, int oldVersion,int newVersion)18. {19. db.execSQL("DROP TABLE IF EXISTS filedownlog");20. onCreate(db);21. }22.}Java代码1./**2. * 文件下载业务bean3. */4.public class FileService5.{6. private DBOpenHelper openHelper;7. public FileService(Context context)8. {9. openHelper = new DBOpenHelper(context);10. }11. /**12. * 获取每条线程已经下载的文件长度13. * @param path14. * @return15. */16. public Map<Integer, Integer> getData(String path)17. {18. SQLiteDatabase db = openHelper.getReadableDatabase();19. Cursor cursor = db.rawQuery("select threadid, downlength from filedownlog where downpath=?", new String[]{path});20. Map<Integer, Integer> data = new HashMap<Integer, Integer>();21. while(cursor.moveToNext())22. {23. data.put(cursor.getInt(0), cursor.getInt(1));24. }25. cursor.close();26. db.close();27. return data;28. }29. /**30. * 保存每条线程已经下载的文件长度31. * @param path32. * @param map33. */34. public void save(String path, Map<Integer, Integer> map)35. {//int threadid, int position36. SQLiteDatabase db = openHelper.getWritableDatabase();37. db.beginTransaction();38. try39. {40. for(Map.Entry<Integer, Integer> entry : map.entrySet())41. {42. db.execSQL("insert into filedownlog(downpath,threadid, downlength) values(?,?,?)",43. new Object[]{path, entry.getKey(), entry.getValue()});44. }45. db.setTransactionSuccessful();46. }47. finally48. {49. db.endTransaction();50. }51. db.close();52. }53. /**54. * 实时更新每条线程已经下载的文件长度55. * @param path56. * @param map57. */58. public void update(String path, Map<Integer, Integer> map)59. {60. SQLiteDatabase db = openHelper.getWritableDatabase();61. db.beginTransaction();62. try{63. for(Map.Entry<Integer, Integer> entry : map.entrySet()){64. db.execSQL("update filedownlog set downlength=? where downpath=? and threadid=?",65. new Object[]{entry.getValue(), path,entry.getKey()});66. }67. db.setTransactionSuccessful();68. }finally{69. db.endTransaction();70. }71. db.close();72. }73. /**74. * 当文件下载完成后,删除对应的下载记录75. * @param path76. */77. public void delete(String path)78. {79. SQLiteDatabase db = openHelper.getWritableDatabase();80. db.execSQL("delete from filedownlog where downpath=?", new Object[]{path});81. db.close();82. }83.}。

android studio中的多线程编程例子

android studio中的多线程编程例子

android studio中的多线程编程例子在Android Studio中,多线程编程是一种常见且重要的技术,它可以帮助我们更有效地处理并发任务和提升应用的性能。

通过使用多线程,我们可以在应用中同时执行多个任务,从而提高用户体验。

下面我将为您提供一个Android Studio中的多线程编程的例子,帮助您更好地理解该概念和实现。

首先,我们需要在项目中创建一个新的Java类,用于定义我们的多线程任务。

假设我们要实现一个简单的计数器,可以在后台进行自增操作,并将结果显示在应用界面上。

```javapublic class CounterThread extends Thread {private boolean isRunning = true;private int counter = 0;private Handler handler;public CounterThread(Handler handler) {this.handler = handler;}@Overridepublic void run() {while (isRunning) {try {// 模拟自增操作counter++;// 发送消息给主线程更新UIMessage message = new Message();message.obj = "当前计数: " + counter;handler.sendMessage(message);// 使线程休眠1秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public void stopThread() {isRunning = false;}}```在MainActivity中,我们需要处理UI更新的部分,以及创建和启动我们的CounterThread。

安卓中知识点总结

安卓中知识点总结

安卓中知识点总结作为一名Android开发者,了解和掌握Android开发的知识点是非常重要的。

本文将对Android开发涉及的各种知识点进行总结,包括Java语言基础、Android框架、界面设计、数据库操作、网络请求、性能优化等方面的知识点。

一、Java语言基础1. 类和对象类是Java语言中的基本概念,它是对象的模板。

对象是类的实例,是具体的实体。

了解类和对象的概念是Java编程的基础。

2. 继承和多态继承是Java语言中非常重要的特性,它使得子类可以继承父类的属性和方法。

多态是继承的延伸,它使得一个对象可以以多种形态出现,提高了程序的灵活性和扩展性。

3. 接口和抽象类接口和抽象类都是Java中用来实现多态和封装的机制,它们可以让程序员定义一个函数,并且由实现类来实现该函数的具体功能。

4. 异常处理异常处理是Java语言中的重要机制,在处理IO异常、运行时异常等方面都有着重要作用。

5. 泛型泛型是Java中的一个重要特性,它使得类或方法可以接受任意类型的数据作为参数,提高了代码的复用性和灵活性。

6. 并发并发是指在同一时间段内同时运行多个程序或多个线程。

在Android开发中,了解并发编程的知识点可以帮助我们编写高效的多线程应用。

7. I/O流I/O流是Java中用来进行输入输出操作的重要概念,了解文件操作、网络操作、序列化等知识点对Android开发非常重要。

二、Android框架1. ActivityActivity是Android应用的一个重要组件,它负责提供一个用户界面来展示和与用户交互。

了解Activity的生命周期、启动方式、传递数据等知识点是非常重要的。

2. FragmentFragment是Android中用来实现复杂界面的一种重要组件,它可以在一个Activity中管理多个界面碎片。

了解Fragment的生命周期、使用方式、通信方式等知识点是非常重要的。

3. ServiceService是Android中用来实现后台任务的一种组件,它可以在后台执行长时间运行的任务。

Android移动应用开发实验指导书.docx

Android移动应用开发实验指导书.docx

《Android移动应用开发》实验指导书课程代码:总课时数:适用专业:院(系)名称:实验一深入理解Activity目标(1)掌握Activity的开发、配置和使用。

(2)掌握Intent的几种常用的属性。

(3)Android系统内置Intent的使用。

(4)了解Activity的生命周期实验软、硬件环境硬件:PC电脑一台;配置:winxp或win7系统,内存大于4G,硬盘250G及以上JDK1.7 、Eclipse、ADT、Android SDK实验主要技术基础(1)活动是Android的四大组件之一,它是一种可以包含用户界面的组件,主要用于和用户进行交互。

(2)Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。

任务:1、请在AndroidManifest.xml文件中配置SecondActivity;配置Intent的Action属性为com.sise.intent.action.JHY_ACTION。

配置Category属性为com.sise.intent.category.JHY_CATEGORY通过隐式Intent的使用从FirstActivity,编写代码,运行程序,预期效果启动SecondActivity如下所示。

图1 程序运行初始化界面 图2 点击图1中的按钮后的运行结果。

传递数据到SecondActivity,并使用Intent从FirstActiv2、请使用显式Intent启动SecondActivity编写代码,运行程序,预期效果如下所示。

图1 程序运行初始化界面图2 点击图1中的按钮后的运行结果3、使用Intent传递数据从SecondActivity返回数据到FirstActivity中去。

编写代码,运行程序,预期效果如下所示。

图1 程序运行初始化界面图2 点击图1按钮运行结果图3 点击图2按钮运行结果实验方法与步骤(1)创建活动Activity是Android系统提供的一个活动基类所有的活动都必须直接或间接继承此类才能拥有活动的特性。

【免费下载】android开发入门教程

【免费下载】android开发入门教程

IIT教程网Android开发入门教程★视频说明★这套android开发入门教程文档是我平时学习android的时候收集整理的一些android开发入门教程;都保存在自己的百度云网盘里面了;★视频目录★1名称:Android游戏开发高手进阶2名称:Android SDK开发基础入门教程3名称:浙江大学Android开发精品教程4名称:Android项目实现系列视频教程5名称:Android平台一日游开发经典教学视频名称:密西西比河谷州立大学Android应用程序开发教学视频7名称:黑马程序员Android核心基础视频教程(55集)8名称:Android开发视频教程--腾讯微博项目9名称:Android游戏开发视频实战篇【13集】10名称:Mars老师Android开发教学视频(重制版)11名称:Sandy安卓应用开发讲解视频课程【附源码】12名称:《Android开发入门与实战体验》视频教程【16章】13名称:Android开发高级应用课程视频专题14名称:8天快速掌握Android视频15名称:Android工具软件合集【更新中】16名称:321手机视频项目开发视频课程名称:Android短信智能管理器开发课件与视频18名称:豆瓣阅读项目开发视频与源码19名称:植物大战僵尸项目开发视频与源码20名称:红孩子手机客户端项目开发视频课程21名称:3G游戏guessWho项目开发视频22名称:手机流媒体视频播放器项目开发视频23名称:安卓JNI与底层开发项目视频与源码24名称:Android开发基础视频教程25名称:手机安全卫士项目开发视频26名称:Android项目开发:手机彩票系列视频27名称:Android案例与项目:6fun视频与源码28名称:百度地图项目开发培训视频与源码29名称:Android手机应用开发入门视频教程30名称:Android游戏开发视频教程之数独31名称:Android项目开发之简单微信视频教程32名称:Android项目视频教程之手机防盗软件33名称:新浪微博Android客户端开发视频教程(36讲)34名称:J2ME移动开发实战教学系列视频教程35名称:J2ME手机开发编程菜鸟进阶视频教程36名称:J2ME开发全方位基础教程37名称:J2ME移动开发视频教程与实例(18讲)38名称:JavaME手机开发大全-视频教程及源码(19集) 39名称:ITjob 全套android视频教程40名称:[千锋3G学院]Android开发项目实例教程41名称:千锋3G学院]Android开发视频教程42名称:使用Flash Professional CS5创作一个简单的Android游戏视频教程43名称:使用Flex构建Android和iOS应用程序视频教程44名称:伟谷州立大学开放课程:Android应用程序开发45名称:基于Android的软件管理器开发教学视频46名称:Java基本教程Android应用程序开发47名称:Android游戏开发视频教程48名称:基于Android的通讯录开发教学视频49名称:Google Android开发入门与实战随书视频50名称:Android视频教程51名称:Sundy's 《Android深入浅出》《Android高级应用课程》《Android开发视频教程》52名称:Java4Android视频教程53名称:疯狂软件_疯狂Java_李韩飞老师_Android项目_新浪微博Android客户端项目开发视频教程54名称:北风网Android应用实战:淘宝网手机客户端全程实录(第一季)》共10课时/更新完毕55名称:大话优酷、酷六类视频网站Android客户端软件开发56名称:魔乐MLDN 李兴华教你Android开发实战57名称:[西安刘凯]android内容58名称:《Sundy--Android嵌入式底层开发课程共享版》《linux嵌入式系统开发.移植》59名称:善知堂android就业视频60名称:3G手机开发之Android应用开发61名称:Android开发从零开始(共43集)62名称:腾讯微博Android客户端开发(共9集)63名称:『若水新闻』客户端开发教程64名称:Android视频- Android初级到高级开发视频教程/Android开发视65名称:Android高级应用课程共享版66名称:Android深入浅出视频教程67名称:网络文件同步项目68名称:[西安刘凯][java&android][好友互.项目]69名称:[西安刘凯][java&android][简单微信]IIT教程网70名称:网老罗Android开发视频教程-安卓巴士。

多线程技术在android手机开发中的应用

多线程技术在android手机开发中的应用

@O er e v rd i p bi v i ade esg( s g g u l od n l saeMes e c h M a ms){
信息通信 个单独 的线程里 。这意味着应用程序所 做的事情 如果在主 线程里 占用了太长的时间的话 , 就会 引发 ( 应用程序无响

闫伟等: 多线程技术在 a dod手机开发 中的应用 n ri
po rsB reMa( a e. ti Sz0 ; rges a. t x1 d r eFl i ) s o g e e
prva eTe t e e ut e ; i t x Viw r s lVi w
sg a e方法 发送消息 。把耗时较 多的任 务放 在子线程 中进行 , 这种技术是开发中不可或缺的 ,在联网的应用程序和手机游
戏中表现得尤为重要 。
p v eP o r s Ba r g e s r i t r a r g e s r o r s Ba ; p
应) 对话框 , 因为应用程序并没有给 自己机 会来处理输入事件 或者意 图广播 , 这样一来就会造成程序响应速度变慢 , 在这种 情况下 ,就需要把那些耗 费时间比较 多的事情 放到一个新的 线程 中进行 , 到这些事情完成之后 , 刷新主 U 的消息发 等 将 I
送 给 主 线 程 , 主 U 进 行 更 行 , 个 过程 如 图 2所 示 。这 就 对 I 这
在 主 线程 中定 义 h de, n a lr并为 这 个 hn l 实 现 hn l sa e a de r a de sg Me 方 法 , 后 在 子 线 程 中 调用 主 线 程 的 h n l , 过其 sn Me. 然 ade 通 r ed s
3 具体 的实现 过 程

Android应用开发从入门到精通

Android应用开发从入门到精通

Android应用开发从入门到精通第一章:介绍Android应用开发的基础概念Android应用开发是指基于Android操作系统平台开发的移动应用程序。

Android是一个基于Linux的开放源代码平台,它提供了强大的开发工具和丰富的API(应用程序接口),使开发者能够创建各种各样的应用程序,包括游戏、社交媒体、电子商务和工具类应用等。

Android应用开发的核心概念包括Activity、Fragment、布局文件、资源文件、Intent等。

Activity是Android应用的主要组件,每个Activity代表了应用的一个界面。

Fragment是一个可重用的界面组件,可以在Activity中动态加载和替换。

布局文件定义了Activity或Fragment中的界面元素的排列方式,可以使用XML语言编写。

资源文件包括图片、字符串、颜色等,用于应用的各种资源的管理。

Intent用于在不同的组件之间进行通信和传递数据。

第二章:Android应用开发环境的搭建要进行Android应用开发,需要搭建相应的开发环境。

首先,需要下载并安装Java Development Kit(JDK),然后下载并安装Android Studio,它是官方推荐的Android开发工具。

安装完Android Studio后,需要配置Android SDK(软件开发工具包)。

Android SDK包含了众多的开发工具和API,可以满足不同应用的需求。

配置SDK的过程通常包括选择需要安装的组件和设置相应的环境变量。

安装完成后,就可以开始进行Android应用的开发了。

第三章:Android应用的UI设计用户界面(UI)是Android应用的重要组成部分,好的UI设计能够提高用户体验。

Android提供了丰富的UI元素和布局管理器,开发者可以根据应用的需求自由选择和设计UI。

常用的UI元素包括文本框、按钮、图像视图、列表视图等。

Android提供了一套用于绘制和交互的UI组件,开发者可以通过XML文件或者代码方式来创建UI界面。

Android开发教程之使用 Web Workers 来加速您的移动 Web 应用程序

Android开发教程之使用 Web Workers 来加速您的移动 Web 应用程序


手机软件开发培训第一品牌
智能手机浏览器上的 Web Worker 支持很不错,而且一直在不断改进。 这就提出了一个问题:什么时候需要在移动 Web 应用程序中使用 Workers?答案很简单:需要完成耗时的任务的任何时候。有些示例展 示了如何将 Workers 用于执行密集的数学计算,比如计算 1 万位数的 圆周率。很可能您永远也不需要在 Web 应用程序上执行这样一个计算, 在移动 Web 应用程序上执行这种计算的几率则更小。但是,从远程资源 检索数据则相当常见,这也是本文示例的关注点。 在这个示例中,您将从 eBay 检索一个 Daily Deals(每天都在变化的交 易)列表。这个交易列表包含关于每笔交易的简短信息。更详细的信息 可以通过使用 eBay 的 Shopping API 获取。当用户浏览这个交易列表 选择感兴趣的商品时,您将使用 Web Workers 来预取这个附加信息。 要从您的 Web 应用程序访问所有这些 eBay 数据,您需要通过使用一个 泛型代理(generic proxy)来处理浏览器的同源策略。一个简单的 Java servlet 将用于这个代理,它包含在本文的代码中,但不在这里单独 展示。相反,我们将把注意力集中在处理 Web Workers 的代码上。清 单 3 展示了这个交易应用程序的基本 HTML 页面。

手机软件开发培训第一品牌
var worker = new Worker("worker.js"); worker.onmessage = function(message){ // do stuff }; worker.postMessage(someDataToDoStuffWith); 在 清单 1 中,您可以看到使用 Web Workers 的三个基本步骤。 首先,您创建一个 Worker 对象并向它传递将在新线程中执行的 脚本的 URL。Worker 将执行的所有代码都必须包含在一个 Worker 脚本中,该脚本的 URL 将被传递到这个 Worker 的构造 函数中。这个 Worker 脚本的 URL 受到浏览器的同源策略的限 制 — 它必须来自加载这个页面的同一个域,该页面已加载正在创 建这个 Web Worker 的页面脚本。

最全的Android开发开发资料

最全的Android开发开发资料

开发人员资料大全(开发人员必看)
有率最高癿智能手机操作系统。这个文档里整理大量优质癿Android开収资料,网上癿资料众多,参 都是很经典癿资料,里面有些暂时用丌到癿,大家可以作为开収目录收藏起来,在需要癿时候选择 简介
开 发 教 程(初 级)
Android 是一种基亍 Linux® V2.6 内核癿综吅操作环境。本与题提供癿教程、技术文 章首先带大家了觋 Android 开収,迚而深入到 Android 开収癿各个方面。 android癿中文开収教程,对android开収感兴趣癿朋友可以看看,是个丌错癿入门教 程。 简单易懂,对初学Android癿人来说有着很好癿帮劣,吅集一共包括4大部分,以 Android中文帮劣文档为核心部分内容。 初学者癿福音,从9个方面详绅介绍android基础应用。 Android开収教程笔记完全版~从Android基础介绍到系统构架详述,再到Android应 用详觋,建议入门学者学习。 本篇分三大部分:从android系统结构不SDK使用、android应用程序概述和框架和 android癿UI系统实现,详述Android应用开収。 目前很多Android软件和游戏中存在恶意行为戒收集用户隐私问题,手机优化大师癿 APK安装器将会检查每个应用癿请求权限,保证用户癿安全,本篇就是mTweak总结癿 APK权限大全。 Android平台号称是首个为秱劢终端打造癿真正开放和完整癿秱劢软件。本文汇总整理 了时下关亍Google Android技术教程癿下载资源,仅供参考。 快速入门学习是本文要介绍癿内容,主要是来了觋并学习Android 2.2入门学习癿内 容,具体关亍Android 2.2内容癿详觋来看本文。 本篇以Android应用开収一问一答癿形式,帮劣新手更快了觋Android癿相关知识,収 展前景以及基础知识等内容。 从Android癿出现、収展、用途和应用癿各方面迚行详绅说明,从而帮劣新手尽快了觋 Android,抛砖引玉。 从27个丌同侧面对Android开収迚行讱觋,相信新手们会从中叐益良多。 比较丌错癿入门读物,介绍了怎样搭建环境乊类癿基础知识。 从Android开収环境癿搭建和用户界面入手,为初学者理清Android学习癿脉绚。 从Android基础知识不开収,到各种驱劢程序,有了详尽介绍,相信对初学者有很大帮 劣。 Android为我们带来了大量癿新名词,Android丌仅是一类手机癿总称、一个手机开収 平台、一个虚拟java操作系统、一个开収社区、一个开収标准、一堆代码,它已成为一 个新癿潮流。 下面介绍癿一些方法可以帮劣你癿应用程序“瘦身”戒者说“Android提升开収性能十 大要点”,以便它们在今天和明天癿Android讴备上最顸畅地运行。 Android开収教程系列一共17篇文章,从丌同方面讱觋Android开収。

android线程间通信的几种方法

android线程间通信的几种方法

android线程间通信的几种方法
在Android开发中,线程间通信是一项重要的技术,通常用于在不同的线程间传递数据或通知。

下面介绍几种实现线程间通信的方法: 1. Handler
Handler是Android中最常用的线程间通信机制之一,它允许在不同线程间发送和处理消息。

在UI线程中创建一个Handler对象,
然后可以使用它来向其他线程发送消息或将消息传递回UI线程进行
处理。

2. BroadcastReceiver
BroadcastReceiver是一种广播机制,可以在应用程序内部和应用程序之间传递消息。

通过注册和发送广播,不同的线程可以相互通信,从而达到线程间通信的目的。

3. Messenger
Messenger是一种轻量级的IPC(进程间通信)机制,它允许不
同的线程使用Message对象进行通信。

Messenger通过IPC方式传递消息,可以实现跨进程的线程间通信。

4. ContentProvider
ContentProvider是一种用于访问和共享数据的机制,它可以将不同线程之间的数据进行共享。

通过ContentProvider,线程可以在不同的进程中读取和写入数据,从而达到线程间通信的目的。

总之,在Android开发中,线程间通信是非常重要的,我们需要根据具体的需求选择不同的方法来实现线程间的数据传递和通信。


上介绍的几种方法都是非常常用的线程间通信机制,开发者需要根据具体的情况选择最适合的方法来完成线程间的通信。

android中线程池用法

android中线程池用法

在Android中,可以使用线程池来管理线程,提高应用程序的响应性能。

以下是一些在Android中常见的线程池及其用法:1. **FixedThreadPool**:* 创建一个固定数量的线程池,当线程池中的线程都被占用时,新提交的任务会被阻塞直到有线程可用。

* 示例:```java`ExecutorService executorService = Executors.newFixedThreadPool(10);executorService.submit(() -> {// 任务代码});````2. **CachedThreadPool**:* 创建一个可缓存的线程池,当线程池中的线程数量超过核心线程数时,多余的线程会被缓存起来,当有新任务提交时,会尝试复用这些缓存的线程。

* 示例:```java`ExecutorService executorService = Executors.newCachedThreadPool();executorService.submit(() -> {// 任务代码});````3. **SingleThreadExecutor**:* 创建一个单线程的线程池,所有任务都会在一个线程中顺序执行。

* 示例:```java`ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.submit(() -> {// 任务代码});````4. **ThreadPoolExecutor**:* 创建一个自定义配置的线程池,可以设置核心线程数、最大线程数、任务队列等。

* 示例:```java`ThreadPoolExecutor executorService = new ThreadPoolExecutor(5, // 核心线程数10, // 最大线程数60L, // 空闲线程存活时间(秒)TimeUnit.SECONDS, // 时间单位new ArrayBlockingQueue<Runnable>(100), // 任务队列new ThreadPoolExecutor.CallerRunsPolicy() // 当线程池已满时,新提交的任务在调用者线程中运行);executorService.submit(() -> {// 任务代码});````5. **ScheduledThreadPoolExecutor**:* 创建一个可调度的线程池,可以定时执行或周期性地执行任务。

Android开发教程与视频教程类专题资料免费下载整理合集

Android开发教程与视频教程类专题资料免费下载整理合集

Android开发教程与视频教程类专题资料免费下载整理合集《Android开发从零开始视频教程》【2.3 GB】/jiaocheng/shipin/26275.html《善知堂Android就业班系列培训视频教程(基于android4.03)》更新到第3季【1.4GB】/jiaocheng/shipin/31370.html《老罗Android开发视频教程》【2.3 GB】/jiaocheng/shipin/32886.html《Android系统级深入开发—移植与调试》扫描版【65.3MB】/book/jisuanji/32701.html《善知堂Android就业班系列培训视频教程(基于android4.03)》【1.2 GB】/jiaocheng/shipin/26491.html《3G手机开发之Android应用开发》共8天课程/更新完毕【5GB】/jiaocheng/shipin/26316.html《Android视频教程》(Android Video Course)【3.1GB】/jiaocheng/shipin/25928.html《大话优酷、酷六类视频网站Android客户端软件开发》共21讲【1.8GB】/jiaocheng/shipin/26412.html《Android基础教程》(Hello,Android)扫描版【10.1 MB】/book/jisuanji/33960.html《Java4Android视频教程》【1.3 GB】/jiaocheng/shipin/26223.html《北风网Android应用实战:淘宝网手机客户端全程实》【682.4 MB】/jiaocheng/shipin/26441.html《Android开发教程》更新至项目实战第01集【2.4 GB】/jiaocheng/shipin/31071.html《魔乐MLDN 李兴华教你Android开发实战》(Android视频)2.3【2.9GB】/jiaocheng/shipin/26354.html《Android 深入浅出教程》【693.3MB】/jiaocheng/shipin/26318.html《腾讯微博Android客户端开发课程》【604.8MB】/jiaocheng/shipin/26327.html《Android应用开发全程实录电子书》《Android 2.0游戏开发实践宝典》【2.3GB】/jiaocheng/shipin/26072.html《伟谷州立大学开放课程:Android应用程序开发》(Open Valley course : Developing Android Applications)中英字幕更新完毕【419 MB】/jiaocheng/shipin/31757.html《基于Android的通讯录开发教学视频》【437.7 MB】/jiaocheng/shipin/26258.html《基于Android的软件管理器开发教学视频》【127.9 MB】/jiaocheng/shipin/26271.html《Android核心技术与实例详解—Android开发起步》【1.4MB】/kejian/jisuanji/10848.html《Android最新美国新闻动态导读》(AndroidWeekly)【204.9 MB】/ziliao/28733.html《Android程序开发初级教程》【977.2KB】/kejian/jisuanji/10847.html《深入浅出Android》【637.5KB】/kejian/jisuanji/10934.html《Android 应用》(Amazing Android Apps For Dummies)英文版【70 MB】/book/jisuanji/33023.html《Google Android SDK开发范例大全》(Google Android SDK)Google Android SDK 【207.8 MB】/jiaocheng/shipin/25408.html《使用Flex构建Android和iOS应用程序视频教程》(Building Android and iOS Applications with Flex)【769.3 MB】/jiaocheng/shipin/26368.html《Android编程入门教程andbook中文版》【2.7MB】/kejian/jisuanji/10846.html《2012android职业就业机会研讨会录音发布Sundy's 《Android深入浅出》》开放式课程V1.3【174.3MB】/jiaocheng/shipin/26374.html《使用Flash Professional CS5创作一个简单的Android游戏视频教程》( Flash Professional CS5 Creating A Simple Game For Android Devices)【742.7MB】/jiaocheng/shipin/26225.html《Android模拟器》(android-3.0-emulator for veket)多国语言版【332.8MB】/ruanjian/duomeiti/13717.html《MAYA中级建模教程》(Digital Tutors Maya | Maya Intermediate: Female Android Modeling)【2.2 GB】/jiaocheng/shipin/20132.html《PCAdvisor安卓特刊》(The Complete Guide to Google Android)【42.8MB】/zazhi/6750.html《Google Android开发入门与实战随书视频》WMV【1.4GB】/jiaocheng/shipin/25132.html《Flex&Hero&Flash Builder &Burrito&预览版测试视频教程》【265.4MB】/jiaocheng/shipin/26152.html。

android多线程下载技术详解

android多线程下载技术详解

Android 多线程、断点续传下载技术1.为什么使用该技术?答:(1)之所以采用多线程下载是因为考虑到手机,及移动设备的cup处理能力,让下载任务多抢占cup资源,从而加快了下载的速度,提高了用户体验(2)断点续传技术,就是在下载过程中如果网络出现问题,导致文件没有下载完,那么下次下载时,接着上次终端位置继续下载,从而减轻了服务器的负担。

2.下面我们就开始建一个多线程下载的项目,来体验多线程下载的优势,项目的结构如下2.1设计UImain.xml代码如下:<?xml version="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res /android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><TextViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/path"/><EditTextandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:text="/kcn/pc/K anbox_10012.exe"android:id="@+id/path"/><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/button"android:id="@+id/button"/><ProgressBarandroid:layout_width="fill_parent"android:layout_height="20px"style="?android:attr/progressBarStyleHorizontal"android:id="@+id/downloadbar"/><TextViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center"android:id="@+id/result"/></LinearLayout>其中引用的string.xml如下:<?xml version="1.0"encoding="utf-8"?><resources><string name="hello">Hello World, SmartDownload!</string><string name="app_name">SMART多线程断点下载器</string><string name="path">下载路径</string><string name="button">下载</string><string name="success">下载完成</string><string name="error">下载失败</string><string name="sdcarderror">SDCard不存在或者写保护</string></resources>3.数据库阶段:3.1编写数据库工具类DBOpenHelerpackage com.smart.db;import android.content.Context;import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper;public class DBOpenHelper extends SQLiteOpenHelper {private static final String DBNAME = "smart.db";private static final int VERSION = 1;public DBOpenHelper(Context context) {super(context, DBNAME, null, VERSION);}@Overridepublic voiddb.execSQL("CREATE TABLE IF NOT EXISTS SmartFileDownlog (id integer primary key autoincrement, downpath varchar(100), threadid INTEGER, downlength INTEGER)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("DROP TABLE IF EXISTS SmartFileDownlog");onCreate(db);}}3.2对各个线程的下载记录进行数据库的操作,编写Fileservice 类代码如下package com.smart.db;import java.util.HashMap;import java.util.Map;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase; /*** 业务bean**/public class FileService {private DBOpenHelper openHelper;public FileService(Context context) { openHelper = new DBOpenHelper(context);}/*** 获取每条线程已经下载的文件长度* @param path* @return*/public Map<Integer, Integer> getData(String path){openHelper.getReadableDatabase();Cursor cursor = db.rawQuery("select threadid, downlength from SmartFileDownlog where downpath=?", new String[]{path});Map<Integer, Integer> data = newHashMap<Integer, Integer>();while(cursor.moveToNext()){data.put(cursor.getInt(0),cursor.getInt(1));}cursor.close();db.close();return data;}/*** 保存每条线程已经下载的文件长度* @param path* @param map*/public void save(String path, Map<Integer, Integer> map){//int threadid, int positionopenHelper.getWritableDatabase();db.beginTransaction();try{for(Map.Entry<Integer, Integer> entry : map.entrySet()){db.execSQL("insert intoSmartFileDownlog(downpath, threadid, downlength) values(?,?,?)",new Object[]{path, entry.getKey(), entry.getValue()});}db.setTransactionSuccessful();}finally{db.endTransaction();}db.close();}/*** 实时更新每条线程已经下载的文件长度* @param path* @param map*/public void update(String path, Map<Integer, Integer> map){SQLiteDatabase db =openHelper.getWritableDatabase();db.beginTransaction();try{for(Map.Entry<Integer, Integer> entry : map.entrySet()){db.execSQL("update SmartFileDownlog set downlength=? where downpath=? and threadid=?",new Object[]{entry.getValue(), path, entry.getKey()});}db.setTransactionSuccessful();}finally{db.endTransaction();}db.close();}/*** 当文件下载完成后,删除对应的下载记录* @param path*/public void delete(String path){SQLiteDatabase db =openHelper.getWritableDatabase();db.execSQL("delete from SmartFileDownlog where downpath=?", new Object[]{path});db.close();}}4.实现文件下载阶段4.1建立SmartFileDownloader类用来实现文件的下载功能代码如下package com.smart.impl;import java.io.File;import java.io.RandomAccessFile;import .HttpURLConnection;import .URL;import java.util.LinkedHashMap;import java.util.Map;import java.util.UUID;import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher;import java.util.regex.Pattern;import android.content.Context;import android.util.Log;import com.smart.db.FileService;public class SmartFileDownloader {private static final String TAG = "SmartFileDownloader";private Context context;private FileService fileService;/* 已下载文件长度 */private int downloadSize = 0;/* 原始文件长度 */private int fileSize = 0;/* 线程数 */private SmartDownloadThread[] threads;/* 本地保存文件 */private File saveFile;/* 缓存各线程下载的长度*/private Map<Integer, Integer> data = new ConcurrentHashMap<Integer, Integer>();/* 每条线程下载的长度 */private int block;/* 下载路径 */private String downloadUrl;/*** 获取线程数*/public int getThreadSize() {return threads.length;}/*** 获取文件大小* @return*/public int getFileSize() {return fileSize;}* 累计已下载大小* @param size*/protected synchronized void append(int size) { downloadSize += size;}/*** 更新指定线程最后下载的位置* @param threadId 线程id* @param pos 最后下载的位置*/protected void update(int threadId, int pos) { this.data.put(threadId, pos);}/*** 保存记录文件*/protected synchronized void saveLogFile() { this.fileService.update(this.downloadUrl, this.data);}* 构建文件下载器* @param downloadUrl 下载路径* @param fileSaveDir 文件保存目录* @param threadNum 下载线程数*/public SmartFileDownloader(Context context, String downloadUrl, File fileSaveDir, int threadNum) {try {this.context = context;this.downloadUrl = downloadUrl;fileService = newFileService(this.context);URL url = new URL(this.downloadUrl);if(!fileSaveDir.exists())fileSaveDir.mkdirs();this.threads = newSmartDownloadThread[threadNum];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("Referer", downloadUrl);conn.setRequestProperty("Charset","UTF-8");conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR2.0.50727; .NET CLR3.0.04506.30; .NET CLR3.0.4506.2152; .NET CLR 3.5.30729)");conn.setRequestProperty("Connection", "Keep-Alive");conn.connect();printResponseHeader(conn);if (conn.getResponseCode()==200) {this.fileSize =conn.getContentLength();//根据响应获取文件大小if (this.fileSize <= 0) throw new RuntimeException("Unkown file size ");String filename = getFileName(conn);this.saveFile = new File(fileSaveDir, filename);/* 保存文件 */Map<Integer, Integer> logdata = fileService.getData(downloadUrl);if(logdata.size()>0){for(Map.Entry<Integer, Integer> entry : logdata.entrySet())data.put(entry.getKey(),entry.getValue());}this.block = (this.fileSize %this.threads.length)==0? this.fileSize /this.threads.length : this.fileSize /this.threads.length + 1;if(this.data.size()==this.threads.length){for(int i = 0; i < this.threads.length; i++) {this.downloadSize +=this.data.get(i+1);}print("已经下载的长度"+this.downloadSize);}}else{throw new RuntimeException("server no response ");}} catch (Exception e) {print(e.toString());throw new RuntimeException("don't connection this url");}}/*** 获取文件名*/private String getFileName(HttpURLConnection conn) {String filename =this.downloadUrl.substring(stI ndexOf('/') + 1);if(filename==null ||"".equals(filename.trim())){//如果获取不到文件名称for (int i = 0;; i++) {String mine = conn.getHeaderField(i);if (mine == null) break;if("content-disposition".equals(conn.getHeader FieldKey(i).toLowerCase())){Matcher m =pile(".*filename=(.*)").matcher(mine.t oLowerCase());if(m.find()) return m.group(1);}}filename = UUID.randomUUID()+ ".tmp";//默认取一个文件名}return filename;}/*** 开始下载文件* @param listener 监听下载数量的变化,如果不需要了解实时下载的数量,可以设置为null* @return已下载文件大小* @throws Exception*/public intdownload(SmartDownloadProgressListener listener) throws Exception{try {RandomAccessFile randOut = new RandomAccessFile(this.saveFile, "rw");if(this.fileSize>0)randOut.setLength(this.fileSize);randOut.close();URL url = new URL(this.downloadUrl);if(this.data.size() !=this.threads.length){this.data.clear();//清除数据for (int i = 0; i < this.threads.length; i++) {this.data.put(i+1, 0);}}for(int i = 0; i < this.threads.length; i++) {int downLength = this.data.get(i+1);if(downLength < this.block &&this.downloadSize<this.fileSize){ //该线程未完成下载时,继续下载this.threads[i] = new SmartDownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);this.threads[i].setPriority(7);this.threads[i].start();}else{this.threads[i] = null;}}this.fileService.save(this.downloadUrl, this.data);boolean notFinish = true;//下载未完成while (notFinish) {// 循环判断是否下载完毕Thread.sleep(900);notFinish = false;//假定下载完成for (int i = 0; i < this.threads.length; i++){if (this.threads[i] != null&& !this.threads[i].isFinish()) {notFinish = true;//下载没有完成if(this.threads[i].getDownLength() == -1){//如果下载失败,再重新下载this.threads[i] = new SmartDownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);this.threads[i].setPriority(7);this.threads[i].start();}}}if(listener!=null)listener.onDownloadSize(this.downloadSize);}fileService.delete(this.downloadUrl);} catch (Exception e) {print(e.toString());throw new Exception("file download fail");}return this.downloadSize;}/*** 获取Http响应头字段* @param http* @return*/public static Map<String, String> getHttpResponseHeader(HttpURLConnection http) { Map<String, String> header = new LinkedHashMap<String, String>();for (int i = 0;; i++) {String mine = http.getHeaderField(i);if (mine == null) break;header.put(http.getHeaderFieldKey(i), mine);}return header;}/*** 打印Http头字段* @param http*/public static voidprintResponseHeader(HttpURLConnection http){ Map<String, String> header = getHttpResponseHeader(http);for(Map.Entry<String, String> entry : header.entrySet()){String key = entry.getKey()!=null ? entry.getKey()+ ":" : "";print(key+ entry.getValue());}}//打印日志private static void print(String msg){ Log.i(TAG, msg);}}4.2下载过程中的线程实现建立SmartDownloadThread类具体代码如下:package com.smart.impl;import java.io.File;import java.io.InputStream;import java.io.RandomAccessFile;import .HttpURLConnection;import .URL;import android.util.Log;public class SmartDownloadThread extends Thread { private static final String TAG = "SmartDownloadThread";private File saveFile;private URL downUrl;private int block;/* *下载开始位置 */private int threadId = -1;private int downLength;private boolean finish = false;private SmartFileDownloader downloader;public SmartDownloadThread(SmartFileDownloader downloader, URL downUrl, File saveFile, int block, int downLength, int threadId) {this.downUrl = downUrl;this.saveFile = saveFile;this.block = block;this.downloader = downloader;this.threadId = threadId;this.downLength = downLength;}@Overridepublic void run() {if(downLength < block){//未下载完成try {HttpURLConnection http = (HttpURLConnection) downUrl.openConnection();http.setConnectTimeout(5 * 1000);http.setRequestMethod("GET");http.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, */*");http.setRequestProperty("Accept-Language","zh-CN");http.setRequestProperty("Referer", downUrl.toString());http.setRequestProperty("Charset", "UTF-8");int startPos = block * (threadId - 1) + downLength;//开始位置int endPos = block * threadId -1;//结束位置http.setRequestProperty("Range","bytes=" + startPos + "-"+ endPos);//设置获取实体数据的范围http.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR2.0.50727; .NET CLR3.0.04506.30; .NET CLR3.0.4506.2152; .NET CLR 3.5.30729)");http.setRequestProperty("Connection", "Keep-Alive");InputStream inStream =http.getInputStream();byte[] buffer = new byte[1024];int offset = 0;print("Thread "+ this.threadId+ " start download from position "+ startPos);RandomAccessFile threadfile = new RandomAccessFile(this.saveFile, "rwd");threadfile.seek(startPos);while((offset = inStream.read(buffer, 0, 1024)) != -1) {threadfile.write(buffer, 0, offset);downLength += offset;downloader.update(this.threadId, downLength);downloader.saveLogFile();downloader.append(offset);}threadfile.close();inStream.close();print("Thread " + this.threadId + " download finish");this.finish = true;} catch (Exception e) {this.downLength = -1;print("Thread "+ this.threadId+ ":"+ e);}}}private static void print(String msg){Log.i(TAG, msg);}/*** 下载是否完成* @return*/public boolean isFinish() {return finish;}/*** 已经下载的内容大小* @return如果返回值为-1,代表下载失败*/public long getDownLength() {return downLength;}}4.3 建立interface SmartDownloadProgressListener 侦听线程的下载进度代码如下:package com.smart.impl;public interface SmartDownloadProgressListener { public void onDownloadSize(int size);}5.建立activity 实现下载的触发,和界面的实时更新具体代码如下:package com.smart.activoty.download;import java.io.File;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ProgressBar;import android.widget.TextView;import android.widget.Toast;importcom.smart.impl.SmartDownloadProgressListener; import com.smart.impl.SmartFileDownloader;public class SmartDownloadActivity extends Activity {private ProgressBar downloadbar;private EditText pathText;private TextView resultView;private Handler handler = new Handler(){@Override//信息public void handleMessage(Message msg) { switch (msg.what) {case 1:int size = msg.getData().getInt("size");downloadbar.setProgress(size);float result =(float)downloadbar.getProgress()/(float)downloadbar.getMax();int p = (int)(result*100);resultView.setText(p+"%");if(downloadbar.getProgress()==downloadbar.getM ax())Toast.makeText(SmartDownloadActivity.this, R.string.success, 1).show();break;case -1:Toast.makeText(SmartDownloadActivity.this, R.string.error, 1).show();break;}}};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.main);Button button =(Button)this.findViewById(R.id.button);downloadbar =(ProgressBar)this.findViewById(R.id.downloadbar); pathText =(EditText)this.findViewById(R.id.path);resultView =(TextView)this.findViewById(R.id.result);button.setOnClickListener(newView.OnClickListener() {@Overridepublic void onClick(View v) {String path =pathText.getText().toString();if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){File dir =Environment.getExternalStorageDirectory();//文件保存目录download(path, dir);}else{Toast.makeText(SmartDownloadActivity.this,R.string.sdcarderror, 1).show();}}});}//对于UI控件的更新只能由主线程(UI线程)负责,如果在非UI 线程更新UI控件,更新的结果不会反映在屏幕上,某些控件还会出错private void download(final String path, final File dir){new Thread(new Runnable() {@Overridepublic void run() {try {SmartFileDownloader loader = new SmartFileDownloader(SmartDownloadActivity.this, path, dir, 3);int length = loader.getFileSize();//获取文件的长度downloadbar.setMax(length);loader.download(new SmartDownloadProgressListener(){@Overridepublic void onDownloadSize(int size) {//可以实时得到文件下载的长度Message msg = new Message();msg.what = 1;msg.getData().putInt("size", size);handler.sendMessage(msg);}});} catch (Exception e) {Message msg = new Message();//信息提示msg.what = -1;msg.getData().putString("error", "下载失败");//如果下载错误,显示提示失败!handler.sendMessage(msg);}}}).start();//开始}}6.到此为止运行会报错,因为没有向sdcard的协数据的权限,访问Internet的权限这需要在AndroidManifest.xml配置具体代码如下:<?xml version="1.0"encoding="utf-8"?><manifestxmlns:android="/apk/res /android"package="com.smart.activoty.download"android:versionCode="1"android:versionName="1.0"><application android:icon="@drawable/icon" android:label="@string/app_name"><activityandroid:name=".SmartDownloadActivity"android:label="@string/app_name"> <intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="UNCHER"/> </intent-filter></activity></application><uses-sdk android:minSdkVersion="8"/><!-- 访问internet权限 --><uses-permissionandroid:name="android.permission.INTERNET"/><!-- 在SDCard中创建与删除文件权限 --><uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FI LESYSTEMS"/><!-- 往SDCard写入数据权限 --><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_S TORAGE"/></manifest>。

【朝花夕拾】Android多线程之(三)runOnUiThread篇——程序猿们的贴心小棉袄

【朝花夕拾】Android多线程之(三)runOnUiThread篇——程序猿们的贴心小棉袄

【朝花⼣拾】Android多线程之(三)runOnUiThread篇——程序猿们的贴⼼⼩棉袄runOnUiThread()的使⽤以及原理实在是太简单了,简单到笔者开始都懒得单独开⼀篇⽂章来写它。

当然这⾥说的简单,是针对对Handler⽐较熟悉的童鞋⽽⾔的。

不过⿇雀虽⼩,五脏俱全,runOnUiThread()好⽍也算得上是⼀⽅诸侯,在⼦线程切换到主线程的众多⽅法中,有着⾃⼰的⼀席之地,所以,必须得给它单独列传。

好了,闲话休提,⾔归正传。

runOnUiThread()是Activity类中的⽅法,它⽤于从⼦线程中切换到主线程来执⾏⼀些需要再主线程执⾏的操作。

这⾥先直接看⼀个例⼦,看看它是如何使⽤的:1public class MainActivity extends AppCompatActivity {2private TextView textView;3 @Override4protected void onCreate(Bundle savedInstanceState) {5super.onCreate(savedInstanceState);6 setContentView(yout.activity_main);7 textView = findViewById(_test);8new Thread(new Runnable() {9 @Override10public void run() {11//do something takes long time in the work-thread12 runOnUiThread(new Runnable() {13 @Override14public void run() {15 textView.setText("test");16 }17 });18 }19 }).start();20 }21 }简单吧,在⼦线程中直接调⽤runOnUiThread⽅法,第15⾏就切换到主线程了,直接修改UI。

多线程下载的原理

多线程下载的原理

多线程下载的原理
多线程下载是指通过同时启动多个线程来实现文件的分段下载,以提高下载速度的一种技术。

在传统的单线程下载中,下载文件时只有一个线程负责从服务器下载文件数据并保存到本地。

而在多线程下载中,我们可以同时启动多个线程去请求不同的文件片段,再将这些文件片段合并成完整的文件。

这种并发下载的方式可以充分利用带宽资源,提高整体下载速度。

具体实现多线程下载的原理如下:
1. 首先,将文件的大小进行分割,计算出每个线程应该下载的文件片段。

可以根据文件大小平均分配给不同的线程,确保各个线程下载的数据量相近。

2. 在多线程下载中,需要使用多个线程同时请求服务器端的文件数据。

每个线程负责下载自己被分配的文件片段,并将其保存到本地磁盘中的临时文件。

3. 下载过程中,需要确保多个线程并发地执行下载任务,并且能够保持各个线程之间的同步。

可以使用线程池来管理多个下载线程,控制线程的启动、暂停、终止等操作。

4. 每个线程下载完成自己的文件片段后,需要将其写入到本地临时文件中。

下载完成后,需要合并各个线程下载的文件片段,将其拼接成完整的文件。

5. 在文件下载过程中,可以实时监测下载进度,并提供用户界面展示下载速度、已下载文件大小等相关信息。

综上所述,多线程下载通过并发地执行下载任务,将文件分割成多个片段进行下载,最后将这些片段合并成完整的文件,以提高下载速度。

这种技术可以在一定程度上充分利用带宽资源,提高下载效率。

《Android应用开发技术(第2版)》课件07网络编程-多线程

《Android应用开发技术(第2版)》课件07网络编程-多线程

12
Handler涉及的概念
概念
主线程 (UI线程)
子线程 (工作线程)
消息 (Message)
消息队列 (Message Queue)
处理者 (Handler)
循环器 (Looper)
定义
作用
备注
当应用程序第1次启动时,会同时 自动开启1条主线程
人为手动开启的线程
处理与UI相关的事件,如更新、操作等 执行耗时操作,如网络请求、数据加载等
ቤተ መጻሕፍቲ ባይዱcorePoolSize Thread Thread
Thread maximumPoolSize 线程回收
18
ThreadPoolExecutor
使用ThreadPoolExecutor的基本步骤包括:
① 创建任务类,重写run()方法 ② 使用Executors的工厂方法创建线程池 ③ 向线程池提交任务 ④ 关闭线程池
创建 (2) new Handler()
message1
(7) handler.handleMessage()
message2 message3 message4
(6) handler.dispatchMessage()
(3) Looper.loop()
message1
MessageQueue对象
第7章 Android网络编程
➢ sendEmptyMessage(int what):发送空消息 ➢ sendEmptyMessageDelayed(int what, long delayMillis):指定延时多少毫秒后发送空信息 ➢ sendMessage(Message msg):立即发送信息 ➢ sendMessageDelayed(Message msg, long delayMillis):指定延时多少毫秒后发送信息 ➢ hasMessage(int what):检查消息队列中是否包含what属性为指定值的消息 ➢ post(Runnable r) ➢ postAtTime(Runnable r, long uptimeMillis) ➢ postDelayed(Runnable r, long delayMillis)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
▲图 8-10 线程职责 /* 线程体是 Clock 对象本身,线程名字为"Clock" */ clockThread = new Thread(new Runnable() {
@Override public void run() {
while (isRunning) { try { Thread.currentThread().sleep(1000); timer++; labelTimer.setText("逝去了 " + timer + " 秒"); Log.d(TAG, "lost time " + timer); } catch (InterruptedException e) { e.printStackTrace(); }
while (isRunning) { try { Thread.currentThread().sleep(1000); timer++; labelTimer.setText("逝去了 " + timer + " 秒"); Log.d(TAG, "lost time " + timer); } catch (InterruptedException e) { e.printStackTrace(); }
} } }); clockThread.start(); /* 启动线程 */ } } 程序打包运行结果出现了异常,如图 8-8 所示。
▲图 8-8 运行结果异常图 我们打开 LogCat 窗口,出错日志信息如图 8-9 所示。
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,力根保通据护过生高管产中线工资敷艺料设高试技中卷术资配0料不置试仅技卷可术要以是求解指,决机对吊组电顶在气层进设配行备置继进不电行规保空范护载高高与中中带资资负料料荷试试下卷卷高问总中题体资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度备题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况中卷下,安与要全过加,度强并工看且作护尽下关可都于能可管地以路缩正高小常中故工资障作料高;试中对卷资于连料继接试电管卷保口破护处坏进理范行高围整中,核资或对料者定试对值卷某,弯些审扁异核度常与固高校定中对盒资图位料纸置试,.卷保编工护写况层复进防杂行腐设自跨备动接与处地装理线置,弯高尤曲中其半资要径料避标试免高卷错等调误,试高要方中求案资技,料术编试交写5、卷底重电保。要气护管设设装线备备置敷4高、调动设中电试作技资气高,术料课案技术,管以术来架及避等系免多统不项启必方动要式方高,案中为;资解对料决整试高套卷中启突语动然文过停电程机气中。课高因件中此中资,管料电壁试力薄卷高、电中接气资口设料不备试严进卷等行保问调护题试装,工置合作调理并试利且技用进术管行,线过要敷关求设运电技行力术高保。中护线资装缆料置敷试做设卷到原技准则术确:指灵在导活分。。线对对盒于于处调差,试动当过保不程护同中装电高置压中高回资中路料资交试料叉卷试时技卷,术调应问试采题技用,术金作是属为指隔调发板试电进人机行员一隔,变开需压处要器理在组;事在同前发一掌生线握内槽图部内纸故,资障强料时电、,回设需路备要须制进同造行时厂外切家部断出电习具源题高高电中中源资资,料料线试试缆卷卷敷试切设验除完报从毕告而,与采要相用进关高行技中检术资查资料和料试检,卷测并主处且要理了保。解护现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(yout.main);
btnEnd = (Button) findViewById(R.id.btnEnd); btnEnd.setOnClickListener(new OnClickListener() {
@Override public void run() {
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,力根保通据护过生高管产中线工资敷艺料设高试技中卷术资配0料不置试仅技卷可术要以是求解指,决机对吊组电顶在气层进设配行备置继进不电行规保空范护载高高与中中带资资负料料荷试试下卷卷高问总中题体资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度备题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况中卷下,安与要全过加,度强并工看且作护尽下关可都于能可管地以路缩正高小常中故工资障作料高;试中对卷资于连料继接试电管卷保口破护处坏进理范行高围整中,核资或对料者定试对值卷某,弯些审扁异核度常与固高校定中对盒资图位料纸置试,.卷保编工护写况层复进防杂行腐设自跨备动接与处地装理线置,弯高尤曲中其半资要径料避标试免高卷错等调误,试高要方中求案资技,料术编试交写5、卷底重电保。要气护管设设装线备备置敷4高、调动设中电试作技资气高,术料课中并中3试、件资且包卷管中料拒含试路调试绝线验敷试卷动槽方设技作、案技术,管以术来架及避等系免多统不项启必方动要式方高,案中为;资解对料决整试高套卷中启突语动然文过停电程机气中。课高因件中此中资,管料电壁试力薄卷高、电中接气资口设料不备试严进卷等行保问调护题试装,工置合作调理并试利且技用进术管行,线过要敷关求设运电技行力术高保。中护线资装缆料置敷试做设卷到原技准则术确:指灵在导活分。。线对对盒于于处调差,试动当过保不程护同中装电高置压中高回资中路料资交试料叉卷试时技卷,术调应问试采题技用,术金作是属为指隔调发板试电进人机行员一隔,变开需压处要器理在组;事在同前发一掌生线握内槽图部内纸故,资障强料时电、,回设需路备要须制进同造行时厂外切家部断出电习具源题高高电中中源资资,料料线试试缆卷卷敷试切设验除完报从毕告而,与采要相用进关高行技中检术资查资料和料试检,卷测并主处且要理了保。解护现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
Android 开发中的多线程编程技术
2011 年 10 月 03 日 00:05 来源:it168 网站 作者:关东升 赵志荣 编辑:景保玉
Android 中的线程 在 Android 平台中多线程应用很广泛,在 UI 更新、游戏开发和耗时处理(网络通信等) 等方面都需要多线程。Android 线程涉及的技术有: Handler;Message;MessageQueue;Looper;HandlerThread。 Android 线程应用中的问题与分析 为了介绍这些概念,我们把计时器的案例移植到 Android 系统上,按照在 Frame 方式 修改之后的代码清单 8-4,完整代码请参考 chapter8_3 工程中 chapter8_3 代码部分。 【代码清单 8-4】 public class chapter8_3 extends Activity {
private String TAG = "chapter8_3"; private Button btnEnd; private TextView labelTimer; private Thread clockThread; private boolean isRunning = true; private int timer = 0;
这样的处理违背了 Android 多线程编程规则,系统会抛出异常“Only the original thread that created a view hierarchy can touch its views”。 要解决这个问题,就要明确主线程和子线程的职责。主线程的职责是创建、显示和更 新 UI 控件、处理 UI 事件、启动子线程、停止子线程;子线程的职责是计算逝去的时间和向 主线程发出更新 UI 消息,而不是直接更新 UI。它们的职责如图 8-11 所示。
@Override public void onClick(View v) {
isRunning = false; } });
labelTimer = (TextView) findViewById(belTimer);
/* 线程体是 Clock 对象本身,线程名字为"Clock" */ clockThread = new Thread(new Runnable() {
} } });
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,力根保通据护过生高管产中线工资敷艺料设高试技中卷术资配0料不置试仅技卷可术要以是求解指,决机对吊组电顶在气层进设配行备置继进不电行规保空范护载高高与中中带资资负料料荷试试下卷卷高问总中题体资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度备题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况中卷下,安与要全过加,度强并工看且作护尽下关可都于能可管地以路缩正高小常中故工资障作料高;试中对卷资于连料继接试电管卷保口破护处坏进理范行高围整中,核资或对料者定试对值卷某,弯些审扁异核度常与固高校定中对盒资图位料纸置试,.卷保编工护写况层复进防杂行腐设自跨备动接与处地装理线置,弯高尤曲中其半资要径料避标试免高卷错等调误,试高要方中求案资技,料术编试交写5、卷底重电保。要气护管设设装线备备置敷4高、调动设中电试作技资气高,术料课中并中3试、件资且包卷管中料拒含试路调试绝线验敷试卷动槽方设技作、案技术,管以术来架及避等系免多统不项启必方动要式方高,案中为;资解对料决整试高套卷中启突语动然文过停电程机气中。课高因件中此中资,管料电壁试力薄卷高、电中接气资口设料不备试严进卷等行保问调护题试装,工置合作调理并试利且技用进术管行,线过要敷关求设运电技行力术高保。中护线资装缆料置敷试做设卷到原技准则术确:指灵在导活分。。线对对盒于于处调差,试动当过保不程护同中装电高置压中高回资中路料资交试料叉卷试时技卷,术调应问试采题技用,术金作是属为指隔调发板试电进人机行员一隔,变开需压处要器理在组;事在同前发一掌生线握内槽图部内纸故,资障强料时电、,回设需路备要须制进同造行时厂外切家部断出电习具源题高高电中中源资资,料料线试试缆卷卷敷试切设验除完报从毕告而,与采要相用进关高行技中检术资查资料和料试检,卷测并主处且要理了保。解护现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
相关文档
最新文档