0

私はAndroidにはかなり新しく、URLからjpgをダウンロードして使用するためにキャッシュする必要があるアプリです。OutputStreamの問題... OutofBoundsException

public class download_image extends AsyncTask<String, Void, String> { 
    int count; 
    @Override 
    protected String doInBackground(String... urls) { 
     try { 
      String root = getFilesDir().toString(); 
      URL imgurl = new URL(urls[0]); // Form a URL object from string. 
      URLConnection c = imgurl.openConnection(); //Open connection. 
      int length_of_file = c.getContentLength();  // Get size of target jpg 
      Log.v("Background Response","Length fo target img = "+length_of_file); 
      InputStream i = new BufferedInputStream(imgurl.openStream(),length_of_file); 

      //Make target image file... 
      final File image = new File(getApplicationContext().getCacheDir().toString(),"image.jpg"); 

      OutputStream o = new FileOutputStream(image); 
      byte data[] = new byte[length_of_file]; 
      long total = 0; 
      while ((count = i.read(data))!=1){ 
       total+=count; 
       o.write(data,0,count); 
      } 

      o.flush(); 
      o.close(); 
      i.close(); 

     } catch (MalformedURLException m) { 
      Log.e("Exception", m.toString()); 
     } catch (IOException i) { 
      Log.e("Exception", i.toString()); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(String s) { 
     System.out.println("Downloaded"); 
     super.onPostExecute(s); 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 
} 

問題があると思われるその流れか何かの上に配列データ[]:

は、私がこれまでに複数の参照(と私自身の工夫)からこれに持っていますか? 私はそれを理解できません。私は、InputStreamのバッファをlength_of_file = getContentLength()のファイルサイズと同じにしようとしました。

ご協力いただければ幸いです! これまでのところ、他の問題をかなり楽しくしています(内部フォルダを書き込むようにして、非同期タスクとは何ですか...私は元々HTTPConnectionsに必要なことを知らなかった)。

08-04 15:51:22.938 13454-13486/com.example.johnny.fibre V/Background Response: Length fo target img = 106620 
08-04 15:51:23.058 13454-13486/com.example.johnny.fibre E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2 
                      Process: com.example.johnny.fibre, PID: 13454 
                      java.lang.RuntimeException: An error occurred while executing doInBackground() 
                       at android.os.AsyncTask$3.done(AsyncTask.java:325) 
                       at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) 
                       at java.util.concurrent.FutureTask.setException(FutureTask.java:223) 
                       at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
                       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
                       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
                       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                       at java.lang.Thread.run(Thread.java:761) 
                      Caused by: java.lang.ArrayIndexOutOfBoundsException: length=106620; regionStart=0; regionLength=-1 
                       at java.util.Arrays.checkOffsetAndCount(Arrays.java:4857) 
                       at libcore.io.IoBridge.write(IoBridge.java:490) 
                       at java.io.FileOutputStream.write(FileOutputStream.java:316) 
                       at com.example.johnny.fibre.Home$download_image.doInBackground(Home.java:476) 
                       at com.example.johnny.fibre.Home$download_image.doInBackground(Home.java:456) 
                       at android.os.AsyncTask$2.call(AsyncTask.java:305) 
                       at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)  
                       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)  
                       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)  
                       at java.lang.Thread.run(Thread.java:761)  

答えて

0

getContentLength()length of the content headerはなく、あなたがダウンロードしている画像のサイズを返します。この場合、作成しようとするイメージに合う大きさではない配列を割り当てている可能性が非常に高いです!代わりにbyte配列を割り当てる

、なぜByteArrayOutputStreamにあなたが読み込まれたデータをストリームし、作業が完了していたら、ストリームにgetBytes()を呼び出すことで、結果をフェッチしませんか?

こうすることで、画像の長さをまったく知る必要はありません。あなたがする必要があるのは、InputStreamの最後に達するまでデータを読み続けるだけです。

Click here for an example of how to use a ByteArrayOutputStream

また、helper utilitiesをAndroidランタイムに組み込むこともできます。具体的には、URLから画像データを取得するように設計されています。

+0

ありがとうございます。 ByteArrayOutputStreamを調べて問題がある場合は返されます。 イメージを必要とするたびにアクティブなインターネットソケットを使用するのではなく、将来の使用のためにイメージをキャッシュしたいので、ヘルパーユーティリティが出ているようです。 – Jcov

+0

私が参照したヘルパーユーティリティを使用する場合は、初期化時または最初にオンラインコールを行うことができます。次に、ローカルモデル内のイメージへの参照を保存して、ネットワークのクエリを続ける必要はありません。 –

関連する問題