L'impostazione di background della vista causa OutOfMemoryError

Sto solo cercando di cambiare l'image di background dell'app, non ha ancora nulla e voglio solo cambiare lo background dell'attività principale in un'image. Viene visualizzato correttamente nell'anteprima, ma quando vengo a eseguirlo sia su un emulatore o sul mio dispositivo fisico, ottengo questo errore.

Lancio di OutOfMemoryError "Imansible allocare una allocazione di byte di 604786188 con 4194208 byte gratuiti e 230 MB fino all'OOM"

  • Ricevitore SMS Android non funzionante
  • Come impostare layout_span attraverso il codice
  • Come ordinare i punti geo-punti in base alla distanza dalla posizione corrente in Android
  • import com.google.android.gms.common.api.GoogleApiClient; non può essere risolto
  • Come mantenere una sola istanza di un frammento quando si passa con NavigationDrawer?
  • trascina, zoom immagini senza android di matrix
  • L'image è inferiore a 1,5 MB, quindi non ho idea di perché non esaurirebbe la memory o cercare di assegnargli molto.

    tutto quello che faccio è stato aperto un progetto vuoto e cambiare lo background del layout relativo.

    La cosa strana è se eseguo l'applicazione su un emulatore di nexus 4 funziona bene, ma un collegamento 5 anche sulla stessa versione di android getta questo errore.

    EDIT

    Non viene più visualizzato l'errore di cui sopra ma si verifica il seguente errore al lancio dell'applicazione indipendentemente dall'emulatore utilizzato.

    FATAL EXCEPTION: main Process: com.jacksteel.comp4, PID: 2164 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.jacksteel.comp4/com.jacksteel.comp4.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2236) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390) at android.app.ActivityThread.access$800(ActivityThread.java:151) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5257) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference at android.app.Activity.findViewById(Activity.java:2072) at com.jacksteel.comp4.MainActivity.<init>(MainActivity.java:20) at java.lang.reflect.Constructor.newInstance(Native Method) at java.lang.Class.newInstance(Class.java:1606) at android.app.Instrumentation.newActivity(Instrumentation.java:1066) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2226)             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)             at android.app.ActivityThread.access$800(ActivityThread.java:151)             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)             at android.os.Handler.dispatchMessage(Handler.java:102)             at android.os.Looper.loop(Looper.java:135)             at android.app.ActivityThread.main(ActivityThread.java:5257)             at java.lang.reflect.Method.invoke(Native Method)             at java.lang.reflect.Method.invoke(Method.java:372)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

    EDIT 2 Codice sorgente

      package com.jacksteel.comp4; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.RelativeLayout; public class MainActivity extends AppCompatActivity { private RelativeLayout Bg = (RelativeLayout) findViewById(R.id.MainBg); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Bitmap bitmap = decodeSampledBitmapFromResource(getResources(),R.drawable.redboxes,Bg.getWidth(), Bg.getHeight()); Resources res = getResources(); BitmapDrawable backgroundDrawable = new BitmapDrawable(res, bitmap); Bg.setBackgroundDrawable(backgroundDrawable); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } 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; } public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); } } 

    Aggiorna EDIT 3

    Codice sorgente aggiornato

     @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final RelativeLayout Bg = (RelativeLayout) findViewById(R.id.MainBg); Bg.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Bg.getViewTreeObserver().removeGlobalOnLayoutListener(this); Bitmap bitmap = decodeSampledBitmapFromResource(getResources(), R.drawable.redboxes, Bg.getWidth(), Bg.getHeight()); Resources res = getResources(); BitmapDrawable backgroundDrawable = new BitmapDrawable(res, bitmap); Bg.setBackgroundDrawable(backgroundDrawable); } }); } 

    Errore aggiornato

     FATAL EXCEPTION: main Process: com.jacksteel.comp4, PID: 1872 java.lang.OutOfMemoryError: Failed to allocate a 107347980 byte allocation with 1048576 free bytes and 63MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609) at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444) at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:467) at com.jacksteel.comp4.MainActivity.decodeSampledBitmapFromResource(MainActivity.java:93) at com.jacksteel.comp4.MainActivity$1.onGlobalLayout(MainActivity.java:27) at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:912) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1881) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5257) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

  • WebView Text Zoom Issue in Android
  • Come popolare TableLayout con ImageView dynamicmente in android jdk?
  • Come impostare l'intervallo di tempo utilizzando la barra di ricerca
  • come utilizzare getListView () in Attività?
  • Scorribile TextView in Widget Android
  • NoClassDefFoundError: android.support.design.internal.NavigationMenu su Android 4.2.2 (wiko)
  • One Solution collect form web for “L'impostazione di background della vista causa OutOfMemoryError”

    AGGIORNARE

    Dovresti mettere l'image che verrà caricata con BitmapFactory.decodeResource() alla directory drawable-nodpi per evitare la scalatura della densità utilizzata nel nome di directory drawable-<density> alla densità dello schermo del dispositivo.

    Nel tuo caso hai inserito l'image nella directory drawable-hdpi e il tuo dispositivo ha xxhdpi schermo xxhdpi in BitmapFactory.decodeResource() con l'image inSampleSize=2 stata scalata 2x (da hdpi a xxhdpi ) e 2x ridimensionata (da inSampleSize ) size e causando l'arresto di applicazioni da OutOfMemoryError .

    RISPOSTA ORIGINALE

    1.5MB è la dimensione dell'image compressa. Quando lo si carica su ImageView o su background di un'altra visuale, Bitmap viene creata implicitamente. In Bitmap each pixel dell'image richiede 4 byte. Quindi, se l'image ha una risoluzione di 4096×4096 pixel, occorrono 64 megabyte di memory, anche se l'image potrebbe essere riempita con un solo colore e richiede solo pochi kilobyte compressi a png o jpeg.

    Dovresti determinare la dimensione reale della tua vista e caricare l'image scalata:

     view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { view.getViewTreeObserver().removeGlobalOnLayoutListener(this); Bitmap bitmap = ImageUtils.decodeSampledBitmapFromFile(backgroundImageFile, view.getWidth(), view.getHeight()); view.setBackground(new BitmapDrawable(getResources(), bitmap)); } }); 

    C'è il mio metodo di utilità per caricare Bitmap scalato da File :

     public class ImageUtils { public static Bitmap decodeSampledBitmapFromFile(File file, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(file.getAbsolutePath(), options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(file.getAbsolutePath(), options); } 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) { // Calculate ratios of height and width to requested height and width final int heightRatio = Math.floor((float) height / (float) reqHeight); final int widthRatio = Math.floor((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } } 

    È ansible utilizzare altri methods BitmapFactory per decodificare Bitmap BitmapFactory di stream, risorse e byte.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.