首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我的Android应用程序损坏了SD卡

我的Android应用程序损坏了SD卡
EN

Stack Overflow用户
提问于 2010-07-20 20:08:53
回答 2查看 664关注 0票数 6

我在Android市场上发布了一款应用程序,后来我不得不将其删除,因为大约一半的评论都是抱怨SD卡损坏的人。我已经检查了几次代码,没有发现任何可能损坏SD卡的东西。所有涉及外部存储的事情都是将流保存为图像,然后将其读取到ImageView中。

这就是根活动中用来创建文件夹的名称。目录路径存储在公共静态变量中。

代码语言:javascript
复制
//Get the SD Card directory
    String external = Environment.getExternalStorageDirectory().getAbsolutePath() + "/appfolder/";

    CACHE_DIRECTORY = external + ".cache/";
    SAVED_DIRECTORY = external + "saved/";

    File cache = new File(CACHE_DIRECTORY);
    File saved = new File(SAVED_DIRECTORY);
    cache.mkdirs();
    saved.mkdirs();

下面是下载和复制图像的代码(当它们被移动到保存的目录时)。

代码语言:javascript
复制
public static void saveImage(File file, URL url) throws IOException {
    BufferedInputStream bis = new BufferedInputStream(url.openStream());
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
    int bytes;
    while ((bytes = bis.read()) != -1) {
        bos.write(bytes);
    }
    bos.close();
    bis.close();
}

public static void copy(File fileIn, File fileOut) throws IOException {
    BufferedInputStream bin = new BufferedInputStream(new FileInputStream(fileIn));
    BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(fileOut));
    int bytes;
    while ((bytes = bin.read()) != -1) {
        bout.write(bytes);
    }
    bin.close();
    bout.close();
}

这是网络I/O的后台线程

代码语言:javascript
复制
public void run() {
    for (String url : thumbnails) {
        if (url != null) {
            String[] urlParts = url.split("/");
            String imageName = urlParts[urlParts.length - 1];
            File file = new File(Main.CACHE_DIRECTORY + imageName);
            if (!file.exists() || file.length() == 0) {
                try {
                    Image.saveImage(file, new URL(url));
                } catch (IOException e) {}
            }
        actx.runOnUiThread(reload);
        }
    }
}

其中,reload是用于更新适配器的runnable,缩略图是字符串urls的数组,图像名称是带有图像扩展名的唯一10-11位数字(特别是.jpeg、.png、.gif )。

这是在异步任务的后台运行的类似代码。

代码语言:javascript
复制
String imageUrl = (String)params[0];
    String[] imageUrlParts = imageUrl.split("/");
    String imageName = imageUrlParts[imageUrlParts.length - 1];
    URL fullImageUrl;
    try {
        fullImageUrl = new URL(imageUrl);
    } catch (MalformedURLException me) {
        cancel(true);
        return null;
    }

    File file = new File(Main.CACHE_DIRECTORY + imageName);
    try {
        URLConnection ucon = fullImageUrl.openConnection();
        int requestedSize = ucon.getContentLength();
        long fileSize = file.length();
        //Either the file does not exist, or it exists but was cancelled early due to
        //User or IOException, so it needs to be redownloaded
        if (!file.exists() || ((file.exists()) && fileSize < (requestedSize * 0.8))) {
            mLoad.setMax(requestedSize);
            BufferedInputStream bis = new BufferedInputStream(ucon.getInputStream());
            BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(file));
            int bytes;
            int count = 0;
            while ((bytes = bis.read()) != -1) {
                bout.write(bytes);
                count++;
                //Updates in increments of 2kb
                if (count % 2048 == 0) {
                    publishProgress(count);
                }
            }
            bis.close();
            bout.close();
        }

        if (save) {
            File saveFile = new File(Main.SAVED_DIRECTORY + imageName);
            copy(file, saveFile);
        }
    } catch (IOException e) {
        cancel(true);
        return null;
    } catch (OutOfMemoryError e) {
        cancel(true);
        return null;
    }

我能找到的损坏SD卡的唯一实例是http://code.google.com/p/android/issues/detail?id=2500

该应用程序是基于Android 1.6构建的,该bug不能通过仿真器或HTC Desire在2.1update1上进行个人测试来重现。

编辑:我已经研究了其他一些问题,这些问题会不会是因为我没有刷新缓冲的输出流而引起的?有什么大不了的吗?

EN

回答 2

Stack Overflow用户

发布于 2010-07-21 04:22:00

我认为有两件事可能是相关的:

在writing.

  • Catching OutOfMemoryError通常不是一个好主意的情况下,你应该对finally{ }块中的流调用.close(),这样它们就会被关闭,以防出现错误或强制关闭。虚拟机已耗尽内存,许多事情将处于不可预知的糟糕状态,在这种情况下最好中止。

我的赌注是在finally块上,可能与OutOfMemoryError发生有关,而不是由于catch而导致应用程序中止,从而导致进一步的错误。

票数 2
EN

Stack Overflow用户

发布于 2013-04-23 07:46:15

我假设你说的是文件系统损坏,而不是SD卡的硬件损坏。Android应用程序在沙箱中运行,所以我认为应用程序(几乎)不可能破坏文件系统。

这可能是一个android特有的bug,它是由你的代码正在做的事情触发的。

我不得不承认,复制字节是一种糟糕的做法。您应该尝试复制512或1024字节的块。

另外,我将使用内部存储来存储临时文件:Android Storage Options

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3289710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档