【问题标题】:How to check if context can still be used in android?如何检查上下文是否仍然可以在android中使用?
【发布时间】:2014-08-09 10:28:27
【问题描述】:

在我的 android 应用程序中,我有一个异步任务,它下载图像并将其保存到外部存储,然后重复直到下载所有图像。这可能需要一段时间,我从调用它的 Activity 中引用上下文,在每个下载的图像异步中引用几次。

在此过程中,用户可能已经按下或结束上下文。

如何检查我是否仍然可以在异步任务中使用它?

这是我的异步任务代码:

package async;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import common.Common;
import common.FishCategory;
import http.Network;
import interfaces.ImageDownloader;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Environment;
import android.provider.MediaStore;

public class Async_getAllFishPics extends AsyncTask<FishCategory, Void, FishCategory> {

    String link;
    ImageDownloader callerContext;
    List<FishCategory> categoryList;

    public Async_getAllFishPics(ImageDownloader callerContext, List<FishCategory> categoryList) {
        this.callerContext = callerContext;
        this.categoryList = categoryList;

        for (FishCategory fish : categoryList) {
            link = fish.getLink();
            if (!link.equals("")) {
                String imgpath = Common.getImagePath(link);
                File file = new File(android.os.Environment.getExternalStorageDirectory(), imgpath);
                if (!file.exists() && Network.isNetworkAvailable((Context)callerContext)) {
                    execute(fish);
                    break;
                }
            }
        }
    }

    @Override
    protected FishCategory doInBackground(FishCategory... fishes) {
        Bitmap bitmap = Network.DownloadImage((Context) callerContext, link);

        try {
            saveImage(bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return fishes[0];
    }

    @Override
    protected void onPostExecute(FishCategory fish) {
        try {
            fish.setLink(link);
            new Async_getAllFishPics(callerContext, categoryList);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private void saveImage(Bitmap bitmap) throws IOException {
        if (bitmap != null) {
            String path = Environment.getExternalStorageDirectory().toString();

            String imgpath = Common.getImagePath(link);

            File file = new File(path, imgpath);
            file.getParentFile().mkdirs();

            String abs = file.getAbsolutePath();

            OutputStream fOut = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);

            fOut.flush();
            fOut.close();

            MediaStore.Images.Media.insertImage(((Activity)callerContext).getContentResolver(),abs,file.getName(),file.getName());
        }   
    }
}

【问题讨论】:

  • 如果您正在做一些可能需要很长时间的事情,那么您应该使用Service 来代替它自己的Context。或者,您可以签入finish() 并在那里停止任务

标签: java android multithreading android-asynctask thread-safety


【解决方案1】:

为什么不改用 ApplicationContext 呢?至少在您关闭应用程序之前,您将确定上下文将存在。

context.getApplicationContext()

【讨论】:

  • 如果我在 Activity 关闭时尝试访问 .getApplicationContext() 的结果会怎样?
  • @omega 我不确定你的意思。如果您将应用程序上下文作为异步任务的上下文传递,那么您用于访问 ApplicationContext 的活动是否已关闭都没有关系。
  • 例如,如果上下文活动中有一个非静态的全局变量,那么如果上下文已关闭,如果我尝试访问它会发生什么?另外我在这里使用上下文MediaStore.Images.Media.insertImage(((Activity)callerContext).getContentResolver(),abs,file.getName(),file.getName());,然后会发生什么?
  • 活动上下文!=应用程序上下文。异步任务可能被杀死的唯一方法是在应用程序关闭时,而不是活动。无论哪种方式,您都无法访问异步任务,它位于另一个线程上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2018-03-25
  • 2015-12-01
  • 2013-03-10
  • 2013-12-31
相关资源
最近更新 更多