2011-10-17 5 views
1

私はWebサーバーに接続し、バイナリデータを受け取るプロジェクトに取り組んでいます。私の問題は、Webサーバーからデータをダウンロードするときです。私がログインの要求を送信したり、いくつかの設定を有効にする場合、問題はありません。しかし、私はバイナリデータをダウンロードする要求を送信すると、それは私にOutOfMemoryExceptionを投げている。ここで私が使用しているコードは次のとおりです。LogCatからAndroid HttpEntityUtils OutOfMemoryException

public byte[] activateColl(int index) { 
     createCancelProgressDialog("","Communcating with you...","Cancel"); 

     byte[] buffer = new byte[1024]; 
     try { 
       httpclient = new DefaultHttpClient(); 
       httppost = new HttpPost("http://www.rpc.frbr.com"); 

       TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); 
       String deviceId = tm.getDeviceId(); 
       Log.w("device_identificator","device_identificator : "+deviceId); 
       String resolution = Integer.toString(getWindow().getWindowManager().getDefaultDisplay().getWidth())+ "x" + 
              Integer.toString(getWindow().getWindowManager().getDefaultDisplay().getHeight()); 
       Log.w("device_resolution","device_resolution : "+resolution); 
       String version = "Android " + Build.VERSION.RELEASE; 
       Log.w("device_os_type","device_os_type : "+version); 
       Log.w("device_identification_string","device_identification_string : "+version); 
       String locale = getResources().getConfiguration().locale.toString(); 
       Log.w("set_locale","set_locale : "+locale); 
       String clientApiVersion = null; 

       PackageManager pm = this.getPackageManager(); 
       PackageInfo packageInfo = pm.getPackageInfo(this.getPackageName(), 0); 
       clientApiVersion = packageInfo.versionName; 
       Log.w("client_api_ver","client_api_ver : "+clientApiVersion); 

       hash = getAuthHash(); 

       TelephonyManager tMgr =(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); 
       phoneNumber = tMgr.getLine1Number(); 
       Log.i("Phone","Phone Number : "+phoneNumber); 

       Log.w("INDEX","INDEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX : "+Integer.toString(index)); 

       String timestampSQL = "SELECT dbTimestamp FROM users"; 
       Cursor cursor = systemDbHelper.executeSQLQuery(timestampSQL); 
       if(cursor.getCount()==0){ 
        Log.i("Cursor","TimeStamp Cursor Empty!"); 
       } else if(cursor.getCount()>0){ 
        cursor.moveToFirst(); 
        timeStamp = cursor.getString(cursor.getColumnIndex("dbTimestamp")); 
       } 


       postParameters = new ArrayList<NameValuePair>(); 
       postParameters.add(new BasicNameValuePair("debug_data","1")); 
       postParameters.add(new BasicNameValuePair("client_auth_hash", hash)); 
       postParameters.add(new BasicNameValuePair("timestamp", timeStamp)); 
       postParameters.add(new BasicNameValuePair("mobile_phone", phoneNumber)); 
       postParameters.add(new BasicNameValuePair("activate_collections",Integer.toString(index))); 
       postParameters.add(new BasicNameValuePair("device_identificator", deviceId)); 
       postParameters.add(new BasicNameValuePair("device_resolution", resolution)); 

       httppost.setEntity(new UrlEncodedFormEntity(postParameters)); 

       HttpResponse response = httpclient.execute(httppost); 
       Log.w("Response ","Status line : "+ response.getStatusLine().toString()); 

       buffer = EntityUtils.toByteArray(response.getEntity()); 

      } catch (ParseException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (NameNotFoundException e) { 
       e.printStackTrace(); 
      } 
       return buffer; 
     } 

エラー:

10-17 17:53:00.198: ERROR/AndroidRuntime(15486): java.lang.OutOfMemoryError 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at org.apache.http.util.ByteArrayBuffer.expand(ByteArrayBuffer.java:57) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at org.apache.http.util.ByteArrayBuffer.append(ByteArrayBuffer.java:75) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at org.apache.http.util.EntityUtils.toByteArray(EntityUtils.java:80) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at com.stampii.stampii.synchronization.Synchronization.deactivateColl(Synchronization.java:843) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at com.stampii.stampii.synchronization.Synchronization.onCreate(Synchronization.java:116) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at android.app.ActivityThread.access$2300(ActivityThread.java:135) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at android.os.Handler.dispatchMessage(Handler.java:99) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at android.os.Looper.loop(Looper.java:144) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at android.app.ActivityThread.main(ActivityThread.java:4937) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at java.lang.reflect.Method.invokeNative(Native Method) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at java.lang.reflect.Method.invoke(Method.java:521) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
10-17 17:53:00.198: ERROR/AndroidRuntime(15486):  at dalvik.system.NativeStart.main(Native Method) 

任意のアイデアは、それを修正する方法?私はバッファのサイズを50 * 1024に増やそうとしましたが、それでも助けにはなりません。

EDIT:エラーであることをラインにスロー:アンドロイドで

buffer = EntityUtils.toByteArray(response.getEntity()); 
+0

バイト配列ではどうしますか?サーバーはどれくらいのデータを送信しますか?あなたは 'HttpEntity.getContent()'の 'InputStream'で直接作業するか、それを一時ファイル' HttpEntity.writeTo(OutputStream) 'に書き込んでから作業する方法はありますか? –

+0

私は同じ行に例外を投げかけています。 –

答えて

1

あなただけがあなたのエンティティをデコードしようとしている間に排気ます限られたヒープサイズを、持っています。私はあなたがクライアントにあなたのデータを送るためにhttp chunkingを使う必要があると思う(または何かが間違ってしまい、EntityUtilsはもっと大きな配列を必要とすると思う)。問題はバイト配列であり、小さくない。投稿:

  1. Detect application heap size in Android
  2. Android heap size on different phones/devices and OS versions
1

[OK]を、これを試してみてください。..

HttpResponse response = httpclient.execute(httppost);   
// get response entity 
HttpEntity entity = response.getEntity();   
// convert entity response to string 
    if (entity != null) 
    {  
    InputStream is = entity.getContent();  
    // convert stream to string  
    result = convertStreamToString(is);  
    result = result.replace("\n", "");  

    } 

conversion of InputStream to Stringのために

public String convertStreamToString(InputStream inputStream) 
{ 
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream)); 
StringBuilder total = new StringBuilder(); 
String line; 
    while ((line = r.readLine()) != null) { 
    total.append(line); 
    } 
return total.toString(); 
} 

または

(org.apache.commons.io.IOUtils)のApache Commonsのライブラリを使用しています。

String total = IOUtils.toString(inputStream); 

または単に一時ファイルに書き込み、

HttpEntity.writeTo(OutputStream); 

[OK]をフィリップReichartはorg.apache.http.utilのパッケージから、提案されたユーザごとのよう。

EntityUtils.toString(); 

は、encoding format with String Conversionを許可する方法です。

あなたはまだOutOfMemory Errorを取得することをお知らせください。

ありがとうございました。

+0

'convertStreamToString(is)'は実装を見ていなくても間違っています(サーバーからのエンコーディング情報はありません。['EntityUtils.toString(HttpEntity)'](http://developer.android.com/reference/ org/apache/http/util/EntityUtils.html#toString(org.apache.http.HttpEntity)))、そして応答から文字列を生成するのはもちろん、普通のバイナリデータがあまりにも大きすぎると失敗します。 –

+0

@Philipp Reichart - はい私はそれを知っていたので、私はここに3つの解決策を書いて、彼には何が適切な解決策であるかをチェックさせてください。 – user370305

+0

実際には 'convertStreamToString()'にエラーが表示されます。どうすれば使用できますか、またはいくつかのライブラリをインポートする必要があります。なぜなら、メソッドの作成エラー以外は何も表示していないからです。手伝ってくれてありがとう! –