2017-03-16 19 views
-5

を割り当てることができませんでした私は取得していますJSONオブジェクトがhttps://newsapi.org/v1/sourcesJSONオブジェクトが大きすぎます。 OutOfMemoryException例外:バイト

からである。しかし、それは、アレイ内の69個のオブジェクトを返し、アプリが、私はJSONを解析するために使用していますArrayListにそれほど多くのメモリを割り当てることができませんJSONオブジェクトが大きすぎる

03-16 13:19:51.985 14275-14275/com.example.user.bulletin E/AndroidRuntime: FATAL EXCEPTION: main 
Process: com.example.user.bulletin, PID: 14275 
java.lang.OutOfMemoryError: Failed to allocate a 506340012 byte allocation with 4369064 free bytes and 377MB until OOM 
at dalvik.system.VMRuntime.newNonMovableArray(Native Method) 
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:620) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:455) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1152) 
at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:724) 
at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:575) 
at android.content.res.Resources.getDrawable(Resources.java:767) 
at android.content.Context.getDrawable(Context.java:525) 
at android.support.v4.content.ContextCompatApi21.getDrawable(ContextCompatApi21.java:30) 
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:372) 
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:202) 
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:190) 
at android.support.v7.content.res.AppCompatResources.getDrawable(AppCompatResources.java:100) 
at android.support.v7.widget.AppCompatImageHelper.loadFromAttributes(AppCompatImageHelper.java:54) 
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:66) 
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:56) 
at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:106) 
at android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1021) 
at android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1080) 
at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:47) 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:769) 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:858) 
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861) 
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:861) 
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:518) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:426) 
at com.example.user.bulletin.RecyclerHelpers.SourceAdapter.onCreateViewHolder(SourceAdapter.java:41) 
at com.example.user.bulletin.RecyclerHelpers.SourceAdapter.onCreateViewHolder(SourceAdapter.java:25) 
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6321) 
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5509) 
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5394) 
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5390) 
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2149) 
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1533) 
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1496) 
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:593) 
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3537) 
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:2979) 
at android.view.View.measure(View.java:19756) 
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715) 
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461) 
03-16 13:19:51.985 14275-14275/com.example.user.bulletin E/AndroidRuntime:  at android.view.View.measure(View.java:19756) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) 
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139) 
at android.view.View.measure(View.java:19756) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 
at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:393) 
at android.view.View.measure(View.java:19756) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) 
at android.view.View.measure(View.java:19756) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464) 
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758) 
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640) 
at android.view.View.measure(View.java:19756) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6124) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) 
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:687) 
at android.view.View.measure(View.java:19756) 
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2283) 
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1370) 
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1619) 
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1258) 
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6348) 
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871) 
at android.view.Choreographer.doCallbacks(Choreographer.java:683) 
at android.view.Choreographer.doFrame(Choreographer.java:619) 
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6123) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
03-16 13:19:55.608 14275-14287/com.example.user.bulletin W/art: Suspending all threads took: 27.278ms 

:オブジェクト

は、私は次のエラーを持っています。

レイアウトエラーです。これをどうすれば解決できますか?

SourceParser.java

package com.example.user.bulletin.JSON; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.os.AsyncTask; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 
import android.widget.Toast; 
import com.example.user.bulletin.RecyclerHelpers.SourceAdapter; 
import com.example.user.bulletin.RecyclerHelpers.SourceItem;  
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject;  
import java.util.ArrayList; 

/** 
* Created by User on 14-03-2017. 
*/ 

public class SourceParser extends AsyncTask<Void, Void, Boolean> { 

    Context c; 
    String jsonData; 
    RecyclerView rv; 
    String TAG = "NOT bla bla"; 
    ProgressDialog pd; 
    ArrayList<SourceItem> sources; 

    //String id, name, description, url, category, langCode, contCode, smallLogoUrl, medLogoUrl, largeLogoUrl; 

    public SourceParser(Context c, String jsonData, RecyclerView rv) { 
     this.c = c; 
     this.jsonData = jsonData; 
     this.rv = rv; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     pd = new ProgressDialog(c); 
     pd.setTitle("Please wait..."); 
     pd.setMessage("Loading list of news sources"); 
     pd.show(); 
    } 

    @Override 
    protected void onPostExecute(Boolean isParsed) { 
     super.onPostExecute(isParsed); 
     pd.dismiss(); 
     if(isParsed){ 
      //bind 
      SourceAdapter adapter = new SourceAdapter(c, sources); 
      rv.setAdapter(adapter); 
      rv.setLayoutManager(new LinearLayoutManager(c)); 
     }else 
      Toast.makeText(c, "Unable to parse", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    protected Boolean doInBackground(Void... params) { 
     return parse(); 
    } 

    private boolean parse(){ 
     try{ 

      JSONObject object = new JSONObject(jsonData); 
      JSONArray jsonArray = object.getJSONArray("sources"); 
      JSONObject jsonObject; 
      sources = new ArrayList<>(); 
      sources.clear(); 
      Log.d(TAG, object.toString()); 

      for(int i=0; i<5; i++){ //jsonArray.length() 

       jsonObject = jsonArray.getJSONObject(i);  

       String id = jsonObject.getString("id"); 
       String name = jsonObject.getString("name"); 
       String description = jsonObject.getString("description"); 
       String url = jsonObject.getString("url"); 
       String category = jsonObject.getString("category"); 
       String langCode = jsonObject.getString("language"); 
       String contCode = jsonObject.getString("country"); 

       JSONObject urlObject = jsonObject.getJSONObject("urlsToLogos"); 
       String smallLogoUrl = urlObject.getString("small"); 
       String medLogoUrl = urlObject.getString("medium"); 
       String largeLogoUrl = urlObject.getString("large"); 

       sources.add(new SourceItem(id, name, description, url, category, langCode, contCode, smallLogoUrl, medLogoUrl, largeLogoUrl)); 

       String printThis = "\nNew Source - \nid : "+id+"\nname : "+ name+"\ndescription : "+description+"\nurl"+url+"\ncategory : "+category +"\nLangCode : "+langCode +"\ncontCode : "+ contCode+"\nsmall url : "+smallLogoUrl +"\nmed url : "+ medLogoUrl+"\nlarge url : "+largeLogoUrl; 
       Log.d(TAG, printThis); 

       } 

       return true; 
     } catch (JSONException e) { 
      e.printStackTrace(); 
      return false; 
     } 
    } 
} 
+0

は、おそらくこれがお手伝いしますhttp://stackoverflow.com/q/9390368/6171845:ここでは、ターゲットの幅と高さに基づいて、2つの電源があるサンプルサイズの値を計算する方法があります –

+0

@Kartikは以下の答えをチェックします。 – Gattsu

+0

[Android:java.lang.OutOfMemoryErrorの重複:OOMまで2097152バイトの空きバイトと2MBの23970828バイトの割り当てを割り当てられませんでした](http://stackoverflow.com/questions/32244851/androidjava-lang-outofmemoryerror-failed- 23970828バイト割り当て) –

答えて

2

あなたは、動的ヒープサイズを増やすことはできませんが、使用することによって、より使用することを要求することができます。

android:largeHeap="true"

manifest.xmlには、マニフェストにこれらの行が追加されていることがあります。アプリケーションのプロセスが大のDalvikヒープを使用して作成するかどうか

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:largeHeap="true" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 

。これは、アプリケーション用に作成されたすべてのプロセスに適用されます。これは、プロセスにロードされた最初のアプリケーションにのみ適用されます。複数のアプリケーションがプロセスを使用できるように共有ユーザーIDを使用している場合は、すべてこのオプションを一貫して使用する必要があります。そうしないと、予測できない結果が生じます。 ほとんどのアプリではこれが必要ではありません。代わりに、全体的なメモリ使用量を減らしてパフォーマンスを向上させることに焦点を合わせるべきです。これを有効にしても、使用可能なメモリが固定的に増加することは保証されません。一部のデバイスは、使用可能なメモリの合計によって制約されるためです。

実行時に使用可能なメモリサイズを照会するには、getMemoryClass()またはgetLargeMemoryClass()のメソッドを使用します。何を得る


明らか

  • 、あなたはOutOfMemoryErrorの減少リスクを意味し、より大きなヒープを取得します。
  • あなたが失う何

  • あなたが目に見えるヒッチングを引き起こす可能性がありますいくつかのフレームを、失うことがあります。ヒープを大きくすると、ガベージコレクションに時間がかかります。ガベージコレクタは、基本的にはライブのオブジェクト全体を走査する必要があるためです。通常、ガベージコレクションの休止時間は約5msです。大したことではないと思うかもしれません。しかし、ミリ秒ごとにカウントされます。 Androidデバイスは16 msごとに画面を更新する必要があり、GC時間が長くなると、フレーム処理時間が16ミリ秒の障壁を超える可能性があり、目に見えるヒッチを引き起こす可能性があります。

  • また、アプリを切り替えると遅くなります。Androidシステムは、LRUキャッシュ内のプロセスを、最近使用されていないプロセスよりも先に終了させることができますが、どのプロセスが最もメモリ集中型であるかを考慮する必要があります。したがって、ヒープを大きくすると、プロセスがバックグラウンドになるとプロセスが強制終了する可能性が高くなります。つまり、ユーザーが他のアプリケーションから自分のものに切り替えるのに時間がかかることがあります。プロセスがフォアグラウンドになると、他のバックグラウンドプロセスも追い出される可能性が高くなります。あなたのアプリから他のアプリに切り替えることにも時間がかかります。

結論:

を極力largeHeapオプションを使用しないでください。パフォーマンスが低下し、ユーザーエクスペリエンスが低下することがあります。


イメージサンプリングをより深く得ることができます:たとえば

それが最終的にImageViewに128x96ピクセルのサムネイルで表示されます場合は、それがメモリに1024×768ピクセルの画像をロードする価値はありません。

デコーダに画像のサブサンプリングを指示し、小さいバージョンをメモリにロードするには、BitmapFactory.OptionsオブジェクトにinSampleSizetrueを設定します。例えば、解像度が2048x1536であり、inSampleSizeが4で復号された画像は、約512x384のビットマップを生成する。これをメモリにロードすると、フルイメージの場合は12MBではなく0.75MBが使用されます(ビットマップ構成がARGB_8888の場合)。

public static int calculateInSampleSize(
     BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) > reqHeight 
       && (halfWidth/inSampleSize) > reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 

    return inSampleSize; 
} 

Note: A power of two value is calculated because the decoder uses a final value by rounding down to the nearest power of two, as per the inSampleSize documentation.

関連する問題