Android 使用AsyncTask实现并发?
我正在开发一个Android应用程序,从我的web服务器下载图像。所有代码都运行良好。我正在使用Asynctask将图像下载到SD卡 我的连接速度为4mbps,但我的应用程序下载3幅图像(2.5MB)大约需要8分钟。我读过Asynctask自动管理线程创建的其他地方,那么现在我可以做些什么来实现并发性呢 我在下面发布我的代码。下面的代码用于将映像从服务器下载到SD卡的Asynctask活动Android 使用AsyncTask实现并发?,android,concurrency,android-asynctask,Android,Concurrency,Android Asynctask,我正在开发一个Android应用程序,从我的web服务器下载图像。所有代码都运行良好。我正在使用Asynctask将图像下载到SD卡 我的连接速度为4mbps,但我的应用程序下载3幅图像(2.5MB)大约需要8分钟。我读过Asynctask自动管理线程创建的其他地方,那么现在我可以做些什么来实现并发性呢 我在下面发布我的代码。下面的代码用于将映像从服务器下载到SD卡的Asynctask活动 public class BitmapDownloaderTask extends AsyncTask&l
public class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String url;
Bitmap bitmap1;
String sdCard;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
bitmap1 = downloadBitmap(params[0]);
boolean avail = isMemorySizeAvailableAndroid(bitmap1.getRowBytes(),
Environment.isExternalStorageEmulated());
if (avail) {
try {
sdCard = Environment.getExternalStorageDirectory().toString()
+ "/MyCatalogue";
File f1 = new File(sdCard);
if (!f1.exists()) {
f1.mkdirs();
}
String filename1 = params[0].substring(params[0]
.lastIndexOf("/") + 1);
File file1 = new File(f1.toString(), filename1);
OutputStream stream1 = new FileOutputStream(file1);
bitmap1.compress(CompressFormat.JPEG, 100, stream1);
Log.w("Abhishek", "card is " + sdCard);
} catch (Exception e) {
e.printStackTrace();
}
}
Log.w("ImageDownloader", "Success bitmap is" + bitmap1);
return downloadBitmap(params[0]);
}
protected static boolean isMemorySizeAvailableAndroid(long download_bytes,
boolean isExternalMemory) {
boolean isMemoryAvailable = false;
long freeSpace = 0;
// if isExternalMemory get true to calculate external SD card available
// size
if (isExternalMemory) {
try {
StatFs stat = new StatFs(Environment
.getExternalStorageDirectory().getPath());
freeSpace = (long) stat.getAvailableBlocks()
* (long) stat.getBlockSize();
if (freeSpace > download_bytes) {
isMemoryAvailable = true;
} else {
isMemoryAvailable = false;
}
} catch (Exception e) {
e.printStackTrace();
isMemoryAvailable = false;
}
} else {
// find phone available size
try {
StatFs stat = new StatFs(Environment.getDataDirectory()
.getPath());
freeSpace = (long) stat.getAvailableBlocks()
* (long) stat.getBlockSize();
if (freeSpace > download_bytes) {
isMemoryAvailable = true;
} else {
isMemoryAvailable = false;
}
} catch (Exception e) {
e.printStackTrace();
isMemoryAvailable = false;
}
}
return isMemoryAvailable;
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
static Bitmap downloadBitmap(String url) {
final AndroidHttpClient client = AndroidHttpClient
.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode
+ " while retrieving bitmap from " + url);
return null;
} else {
Log.w("ImageDownloader", "Success " + statusCode
+ " while retrieving bitmap from " + url);
}
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) {
// Could provide a more explicit error message for IOException or
// IllegalStateException
getRequest.abort();
Log.w("ImageDownloader", "Error while retrieving bitmap from "
+ url);
} finally {
if (client != null) {
client.close();
}
}
return null;
}
}
公共类BitmapDownloaderTask扩展异步任务{
私有字符串url;
位图位图位图1;
字符串SD卡;
私有最终WeakReference imageViewReference;
公共位图下载任务(ImageView ImageView){
imageViewReference=新的WeakReference(imageView);
}
@凌驾
//实际下载方法,在任务线程中运行
受保护位图doInBackground(字符串…参数){
//params来自execute()调用:params[0]是url。
bitmap1=下载位图(参数[0]);
布尔值avail=isMemorySizeAvailableAndroid(bitmap1.getRowBytes(),
环境。isExternalStorageEmulated());
如果(可用){
试一试{
sdCard=Environment.getExternalStorageDirectory().toString()
+“/MyCatalog”;
文件f1=新文件(SD卡);
如果(!f1.exists()){
f1.mkdirs();
}
字符串filename1=params[0]。子字符串(params[0]
.lastIndexOf(“/”+1);
File file1=新文件(f1.toString(),filename1);
OutputStream1=新文件OutputStream(文件1);
bitmap1.compress(CompressFormat.JPEG,100,stream1);
Log.w(“阿披实”,“卡是”+SD卡);
}捕获(例外e){
e、 printStackTrace();
}
}
Log.w(“ImageDownloader”,“成功位图为”+bitmap1);
返回下载位图(参数[0]);
}
受保护的静态布尔值isMemorySizeAvailableAndroid(长下载字节,
布尔isExternalMemory){
布尔值isMemoryAvailable=false;
长自由空间=0;
//如果isExternalMemory为true,则计算可用的外部SD卡
//大小
如果(isExternalMemory){
试一试{
StatFs stat=新StatFs(环境
.getExternalStorageDirectory().getPath());
freeSpace=(long)stat.getAvailableBlocks()
*(long)stat.getBlockSize();
如果(自由空间>下载字节){
isMemoryAvailable=true;
}否则{
isMemoryAvailable=false;
}
}捕获(例外e){
e、 printStackTrace();
isMemoryAvailable=false;
}
}否则{
//查找可用电话号码
试一试{
StatFs stat=new StatFs(Environment.getDataDirectory()
.getPath());
freeSpace=(long)stat.getAvailableBlocks()
*(long)stat.getBlockSize();
如果(自由空间>下载字节){
isMemoryAvailable=true;
}否则{
isMemoryAvailable=false;
}
}捕获(例外e){
e、 printStackTrace();
isMemoryAvailable=false;
}
}
返回isMemoryAvailable;
}
@凌驾
//下载图像后,将其与imageView关联
受保护的void onPostExecute(位图){
如果(isCancelled()){
位图=空;
}
if(imageViewReference!=null){
ImageView=imageViewReference.get();
如果(imageView!=null){
设置图像位图(位图);
}
}
}
静态位图下载位图(字符串url){
最终AndroidHttpClient客户端=AndroidHttpClient客户端
.newInstance(“安卓”);
最终HttpGet getRequest=新HttpGet(url);
试一试{
HttpResponse response=client.execute(getRequest);
final int statusCode=response.getStatusLine().getStatusCode();
if(statusCode!=HttpStatus.SC\u OK){
Log.w(“ImageDownloader”,“Error”+状态码
+从“+url”检索位图时);
返回null;
}否则{
Log.w(“ImageDownloader”,“Success”+状态码
+从“+url”检索位图时);
}
最终HttpEntity=response.getEntity();
如果(实体!=null){
InputStream InputStream=null;
试一试{
inputStream=entity.getContent();
最终位图位图=位图工厂
.解码流(输入流);
返回位图;
}最后{
如果(inputStream!=null){
inputStream.close();
}
entity.consumercontent();
}
}
}捕获(例外e){
//可以为IOException或提供更明确的错误消息
//非法国家例外
getRequest.abort();
Log.w(“ImageDownloader”,“从中检索位图时出错”
+网址);
}最后{
如果(客户端!=null){
client.close();
}
}
返回null;
}
}
为什么在开始和结束时在doInBackground()中下载图像两次?您可以直接返回刚下载的位图
如果您的最小sdk级别>=11,则可以使用参数“THREAD\u POOL\u EXECUTOR”调用AsyncTask的executeOnExecutor以实现并发性
如果您的min sdk级别<11,您可以通过引用AsyncTask的源代码来实现AsyncTask new API。为什么在开始和结束时在doInBackground()中下载映像两次?您可以直接返回刚下载的位图 如果您的最小sdk级别>=11,则可以使用参数“THREAD\u POOL\u EXECUTOR”调用AsyncTask的executeOnExecutor以实现并发性 如果您的最小sdk级别<11,则可以实现Asy
new BitmapDownloaderTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "your urls");