2010-07-20 18 views
6

मैंने एंड्रॉइड बाजार पर एक ऐप जारी किया है जिसे मुझे तब से नीचे लेना पड़ा क्योंकि टिप्पणियों में से लगभग आधे लोग क्षतिग्रस्त एसडी कार्ड की शिकायत कर रहे थे। मैं कुछ बार कोड पर गया हूं और कुछ भी नहीं मिला जो एसडी कार्ड को नुकसान पहुंचा सकता है। ऐसा होता है कि बाहरी भंडारण में छवियों के रूप में धाराओं की बचत होती है, जिसे छविव्यू में पढ़ा जाता है।मेरा एंड्रॉइड ऐप हानिकारक एसडी कार्ड

यह फ़ोल्डर्स बनाने के लिए रूट गतिविधि में कहा जाता है। निर्देशिका पथ सार्वजनिक स्थैतिक चर में संग्रहीत हैं।

//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(); 

और निम्नलिखित छवियों को डाउनलोड करने और उन्हें कॉपी करने के लिए कोड है (जब उन्हें सहेजी गई निर्देशिका में स्थानांतरित किया जा रहा है)।

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(); 
} 

और यह मैं/हे

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); 
     } 
    } 
} 

कहाँ पुनः लोड एक एडाप्टर अद्यतन करने के लिए एक runnable है, थंबनेल स्ट्रिंग यूआरएल की एक सरणी है नेटवर्क के लिए एक पृष्ठभूमि धागा है और छवि नाम एक अनूठा 10- है एक छवि एक्सटेंशन (.jpeg, .png, .gif विशेष रूप से) के साथ 11 अंक संख्या।

और यह एक समान कोड है जो एसिंक्टास्क की पृष्ठभूमि में चलाया जाता है।

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; 
    } 

केवल उदाहरण मैं क्षतिग्रस्त एसडी कार्ड का मिल सकता है http://code.google.com/p/android/issues/detail?id=2500

एप्लिकेशन को Android 1.6 पर बनाया गया है और बग एचटीसी डिजायर साथ एमुलेटर या व्यक्तिगत परीक्षण के माध्यम से recreatable नहीं है 2.1update1 पर।

संपादित करें: मैंने कुछ अन्य प्रश्नों को देखा है और क्या समस्याएं उत्पन्न हो सकती हैं जो buffered आउटपुट स्ट्रीम को फ्लश नहीं कर रही हैं? क्या यह एक बड़ा सौदा है?

+0

क्या आप क्षतिग्रस्त sdcards द्वारा मतलब है? वास्तव में क्या होता है? – Macarse

+0

जहां उपयोगकर्ता को "भ्रष्ट एसडी कार्ड" संदेश मिल जाता है जब इसे घुमाया जा रहा है और उन्हें इसे फिर से काम करने के लिए प्रारूपित करना होगा। – daniel

+0

ओह! खतरनाक कोड: | hehe! – Jorgesys

उत्तर

2

मैं दो चीजें हैं जो संबंधित हो सकती है देखें:

  • आप एक finally{ } ब्लॉक के भीतर धाराओं पर .close() बुलाना चाहिए ताकि वे मामले में बंद हो जाती हैं उसमें कोई त्रुटि है या लिखते समय करीब बाध्य करते हैं।
  • पकड़ना OutOfMemoryError आमतौर पर एक अच्छा विचार नहीं है। वीएम मेमोरी से बाहर हो गया है और बहुत सी चीजें खराब अप्रत्याशित स्थिति में होंगी, उन मामलों में निरस्त करने के लिए सबसे अच्छा।

मेरे शर्त finally ब्लॉक, संभवतः एक OutOfMemoryError हो रहा है और catch की वजह से एप्लिकेशन निरस्त नहीं करने के लिए संबंधित, कुछ त्रुटि और नीचे के कारण पर है।

+0

धन्यवाद। मैं परिवर्तनों को लागू करूंगा और इसे एक छोटे से बाजार में पुनः अपलोड करूँगा और देख सकता हूं कि क्या वही समस्याएं उत्पन्न हुई हैं। – daniel

0

मुझे लगता है कि आप फाइल सिस्टम भ्रष्टाचार और एसडी कार्ड के हार्डवेयर क्षति के बारे में बात नहीं कर रहे हैं। एंड्रॉइड ऐप्स सैंडबॉक्स में चलते हैं, इसलिए मुझे लगता है कि एक ऐप के लिए फाइल सिस्टम को नुकसान पहुंचाने के लिए यह लगभग असंभव होगा।

शायद यह एक एंड्रॉइड विशिष्ट बग है जो आपके कोड को कुछ कर रहा है।

मुझे इस बात से सहमत होना है कि बाइट कॉपी करना खराब अभ्यास है। आपको इसके बजाए 512 या 1024 बाइट्स के ब्लॉक कॉपी करने का प्रयास करना चाहिए।

इसके अलावा मैं tmp फ़ाइलों के लिए आंतरिक भंडारण का प्रयोग करेंगे: Android Storage Options

संबंधित मुद्दे