Android 用线程来实现远程下载

简介:

        很多时候我们需要在Android设备上下载远程服务器上的图片进行显示,今天eoe给了我们两种比较好的方法来实现远程图片的下载。下面我们就先来看看第一个方法 

        方法一、我们直接可以通过Android提供的Http类访问远程服务器,这里我们用到了AndroidHttpClientSDK 2.2中新出的方法,API Level8,大家需要注意下,静态访问可以直接调用,如果SDK版本较低可以考虑ApacheHttp库,当然HttpURLConnectionURLConnection也可以。下面我们就来看看代码:

Java代码:

static Bitmap downloadBitmapByCwj(String url) { 
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android123"); 
final HttpGet getRequest = new HttpGet(url); 

try { 
HttpResponse response = client.execute(getRequest); 
final int statusCode = response.getStatusLine().getStatusCode(); 
if (statusCode != HttpStatus.SC_OK) { 
Log.e("cwjDebug", "Error " + statusCode + " while retrieving bitmap from " + url); 
return null; 
} 

final HttpEntity entity = response.getEntity(); 
if (entity != null) { 
InputStream inputStream = null; 
try { 
inputStream = entity.getContent(); 
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 
return bitmap; 
} finally { 
if (inputStream != null) { 
inputStream.close(); 
} 
entity.consumeContent(); 
} 
} 
} catch (Exception e) { 
getRequest.abort(); 
Log.e("android123Debug", "Error while retrieving bitmap from " + url, e.toString()); 
} finally { 
if (client != null) { 
client.close(); 
} 
} 
return null; 
}


        这里eoe开发网提醒大家,BitmapFactory类的decodeStream方法在网络超时或较慢的时候无法获取完整的数据,这里我们通过继承FilterInputStream类的skip方法来强制实现flush流中的数据,主要原理就是检查是否到文件末端,告诉http类是否继续。我们来看看代码:

Java代码:
static class FlushedInputStream extends FilterInputStream { 
public FlushedInputStream(InputStream inputStream) { 
super(inputStream); 
} 

@Override 
public long skip(long n) throws IOException { 
long totalBytesSkipped = 0L; 


while (totalBytesSkipped < n) { 
long bytesSkipped = in.skip(n - totalBytesSkipped); 


if (bytesSkipped == 0L) { 
int byte = read(); 
if (byte < 0) { 
break; // we reached EOF 
} else { 
bytesSkipped = 1; // 我们读到一个字节
} 
} 
totalBytesSkipped += bytesSkipped; 
} 
return totalBytesSkipped; 


} 


}



       这个就是我们大家常见到的方法了。大多数的都可以支持,不想上面的那个方法,只有SDK2.2才有的。从Android 1.5固件开始Google提供了一个AsyncTask类来帮助开发者处理异步下载的实现,相对于Thread而言他可以运行在UI线程中,其内部的实现是从Java 5开始的并发包concurrent中派生而来的,总体实现比较可靠就是资源占用略大了些。不过使用起来比简单。这里下载图片类ImageDownloader类的download方法可以很好的处理实现UI显示等操作,参数一url为远程server上文件的url,第二个参数为imageview对象,可以直接让imageview显示出下载的远程图片。

Java代码:

public class ImageDownloader { 

public void download(String url, ImageView imageView) { 
BitmapDownloaderTask task = new BitmapDownloaderTask(imageView); 
task.execute(url); 
} 
} 

}



       有关具体的AsyncTask类实现,考虑到图片可能较大,为了给JVM充分的空间存储,这里eoe推荐大家使用弱引用来保存ImageView对象。

Java代码:

class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> { 
private String url; 
private final WeakReference<ImageView> imageViewReference; //使用WeakReference解决内存问题

public BitmapDownloaderTask(ImageView imageView) { 
imageViewReference = new WeakReference<ImageView>(imageView); 
} 

@Override 
protected Bitmap doInBackground(String... params) { //实际的下载线程,内部其实是concurrent线程,所以不会阻塞

return downloadBitmap(params[0]); 
} 

@Override 
protected void onPostExecute(Bitmap bitmap) { //下载完后执行的
if (isCancelled()) { 
bitmap = null; 
} 

if (imageViewReference != null) { 
ImageView imageView = imageViewReference.get(); 
if (imageView != null) { 
imageView.setImageBitmap(bitmap); //下载完设置imageview为刚才下载的bitmap对象
} 
} 
} 
} 


相关文章
|
7天前
|
存储 缓存 Android开发
安卓Jetpack Compose+Kotlin, 使用ExoPlayer播放多个【远程url】音频,搭配Okhttp库进行下载和缓存,播放完随机播放下一首
这是一个Kotlin项目,使用Jetpack Compose和ExoPlayer框架开发Android应用,功能是播放远程URL音频列表。应用会检查本地缓存,如果文件存在且大小与远程文件一致则使用缓存,否则下载文件并播放。播放完成后或遇到异常,会随机播放下一首音频,并在播放前随机设置播放速度(0.9到1.2倍速)。代码包括ViewModel,负责音频管理和播放逻辑,以及UI层,包含播放和停止按钮。
|
1月前
|
开发工具 Android开发 git
Windows下载android2.2完整源码(转)
Windows下载android2.2完整源码(转)
41 3
|
1月前
|
Java Android开发
android 下载图片的问题
android 下载图片的问题
18 3
|
6天前
|
存储 Java 调度
Android面试题之Kotlin协程到底是什么?它是线程吗?
本文探讨了协程与线程的区别,指出协程并非线程,而是轻量级的线程替代。协程轻量体现在它们共享调用栈,内存占用少,仅需几个KB。协程切换发生在用户态,避免了昂贵的内核态切换。在Kotlin中,协程通过Continuation对象实现上下文保存,允许高效并发执行,而不会像线程那样消耗大量资源。通过`runBlocking`和`launch`示例展示了协程的非阻塞挂起特性。总结来说,协程的轻量主要源于内存占用少、切换开销低和高并发能力。
11 0
|
7天前
|
缓存 Android开发 Kotlin
【安卓app开发】kotlin Jetpack Compose框架 | 先用OKhttp下载远程音频文件再使用ExoPlayer播放
使用 Kotlin 的 Jetpack Compose 开发安卓应用时,可以结合 OkHttp 下载远程音频文件和 ExoPlayer 进行播放。在 `build.gradle` 添加相关依赖后,示例代码展示了如何下载音频并用 ExoPlayer 播放。代码包括添加依赖、下载文件、播放文件及简单的 Compose UI。注意,示例未包含完整错误处理和资源释放,实际应用需补充这些内容。
|
8天前
|
存储 Android开发 Kotlin
开发安卓app OKhttp下载后使用MediaPlayer播放
在Android Jetpack Compose应用程序中,要使用OkHttp下载远程音频文件并在本地播放,你需要完成以下几个步骤: 1. **添加依赖**:确保`build.gradle`文件包含OkHttp和Jetpack Compose的相关依赖。 2. **下载逻辑**:创建一个`suspend`函数,使用OkHttp发起网络请求下载音频文件到本地。 3. **播放逻辑**:利用`MediaPlayer`管理音频播放状态。 4. **Compose UI**:构建用户界面,包含下载和播放音频的按钮。
|
12天前
|
JSON 编解码 Apache
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
13 1
|
16天前
|
Java Linux 数据库
59. 【Android教程】多线程
59. 【Android教程】多线程
12 0
|
23天前
|
XML 存储 开发工具
Android Studio如何将APK下载
【5月更文挑战第16天】
|
1月前
|
Android开发 Kotlin API
Android插件化探索与发现,kotlin协程切换线程
Android插件化探索与发现,kotlin协程切换线程