2015-10-27 85 views
-7

我的應用程序不斷崩潰,我無法理解它有什麼問題,一直在尋找答案無處不在,從我的理解,人們說這是因爲設備內存不足,但我不明白是什麼造成這種情況?Android應用程序繼續崩潰OutOfMemoryError

  1. 是因爲我的res/drawable文件夾中有太多圖片嗎?
  2. 是因爲我的res/drawable文件夾中有一個相當高分辨率的圖像?

如果問題是上述問題之一,那麼解決方案是什麼?把圖片放在資產文件夾裏或者是什麼?下面是錯誤堆棧。 謝謝。

MainActivity.java

public class MainActivity extends Activity { 

Class <? extends Activity> classVariable; 
int last_level; 
TextView text_play, text_level, game_title; 
RelativeLayout playBtn, levelBtn; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    playBtn = (RelativeLayout) findViewById(R.id.playBtn); 
    levelBtn = (RelativeLayout) findViewById(R.id.levelBtn); 
    game_title = (TextView) findViewById(R.id.game_title); 
    text_play = (TextView) findViewById(R.id.text_play); 
    text_level = (TextView) findViewById(R.id.text_level); 

    Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/snap-itc.ttf"); 
    text_play.setTypeface(tf); 
    text_level.setTypeface(tf); 
    game_title.setTypeface(tf); 

    // Check if file exists 
    File file = getBaseContext().getFileStreamPath("levels.json"); 
    if (file.exists()) { 
     // Get the JSON Object from the data 
     JSONObject parent = this.parseJSONData(); 

     try { 
      last_level = parent.getInt("level"); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 

    switch (last_level) { 
     case 1: 
      classVariable = Level002Activity.class; 
      break; 
     case 2: 
      classVariable = Level003Activity.class; 
      break; 
     case 3: 
      classVariable = Level004Activity.class; 
      break; 
     case 5: 
      classVariable = Level005Activity.class; 
      break; 
     default: 
      classVariable = Level001Activity.class; 
    } 

    playBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent i = new Intent(getApplicationContext(), 
        Level002Activity.class); 
      startActivity(i); 
     } 
    }); 

    levelBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent in = new Intent(getApplicationContext(), 
        Level001Activity.class); 
      startActivity(in); 
     } 
    }); 

} 

public JSONObject parseJSONData() { 
    String JSONString = null; 
    JSONObject jsonObject = null; 
    try { 
     // Open the inputStream to the file 
     FileInputStream fin = openFileInput("levels.json"); 

     int sizeOfJSONFile = fin.available(); 

     // array that will store all the data 
     byte[] bytes = new byte[sizeOfJSONFile]; 

     // reading data into the array from the file 
     fin.read(bytes); 

     // close the input stream 
     fin.close(); 

     JSONString = new String(bytes, "UTF-8"); 
     jsonObject = new JSONObject(JSONString); 

    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } catch (JSONException x) { 
     x.printStackTrace(); 
     return null; 
    } 
    return jsonObject; 
} 

} 

它不斷出現呼籲ChooseLevelActivity.class

ChooseLevelActivity.java

public class ChooseLevelActivity extends Activity implements View.OnClickListener { 

ImageView level001, level002, level003, level004, level005; 
int last_level, best_move; 
String best_time, level_selected; 
TextView levelName, bestMove, bestTime; 
Class <? extends Activity> classVariable; 
Button playBtn; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.choose_level); 

    level001 = (ImageView) findViewById(R.id.level001); 
    level002 = (ImageView) findViewById(R.id.level002); 
    level003 = (ImageView) findViewById(R.id.level003); 
    level004 = (ImageView) findViewById(R.id.level004); 
    level005 = (ImageView) findViewById(R.id.level005); 

    levelName = (TextView) findViewById(R.id.level_name); 
    bestMove = (TextView) findViewById(R.id.best_move); 
    bestTime = (TextView) findViewById(R.id.best_time); 
    playBtn = (Button) findViewById(R.id.playBtn); 

    // Get the JSON Object from the data 
    JSONObject parent = parseJSONData("levels.json"); 

    // Array of ImageView 
    final ImageView[] levelsArray = {level001, level002, level003, level004, level005}; 

    // This will store all the values inside "best_move and time" in an element string 
    try { 
     last_level = parent.getInt("level"); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 

    for(int i = 0; i < last_level; i++) { 
     levelsArray[i].setVisibility(View.VISIBLE); 
     levelsArray[i].setOnClickListener(this); 
    } 
} 

@Override 
public void onClick(View v) { 

    switch (v.getId()) { 
     case R.id.level001: 
      level_selected = "level001"; 
      classVariable = Level001Activity.class; 
      break; 
     case R.id.level002: 
      level_selected = "level002"; 
      classVariable = Level002Activity.class; 
      break; 
     case R.id.level003: 
      level_selected = "level003"; 
      classVariable = Level003Activity.class; 
      break; 
     case R.id.level004: 
      level_selected = "level004"; 
      classVariable = Level004Activity.class; 
      break; 
     case R.id.level005: 
      level_selected = "level005"; 
      classVariable = Level005Activity.class; 
      break; 
    } 

    String fileName = "record_" + level_selected + ".json"; 

    // Get the JSON Object from the data 
    JSONObject parents = parseJSONData(fileName); 

    // This will store all the values inside "best_move and time" in an element string 
    try { 
     best_move = parents.getInt("best_move"); 
     best_time = parents.getString("best_time"); 
    } catch (JSONException e) { 
     // e.printStackTrace(); 
    } 

    levelName.setText("Level " + level_selected.substring(5)); 
    bestMove.setText("Best Move: " + best_move); 
    bestTime.setText("Best Time: " + best_time); 

    playBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent i = new Intent(getApplicationContext(), 
        classVariable); 
      startActivity(i); 
      finish(); 
     } 
    }); 

} 

public JSONObject parseJSONData(String file) { 
    String JSONString = null; 
    JSONObject jsonObject = null; 
    try { 
     // Open the inputStream to the file 
     FileInputStream fin = openFileInput(file); 

     int sizeOfJSONFile = fin.available(); 

     // array that will store all the data 
     byte[] bytes = new byte[sizeOfJSONFile]; 

     // reading data into the array from the file 
     fin.read(bytes); 

     // close the input stream 
     fin.close(); 

     JSONString = new String(bytes, "UTF-8"); 
     jsonObject = new JSONObject(JSONString); 

    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } catch (JSONException x) { 
     x.printStackTrace(); 
     return null; 
    } 
    return jsonObject; 
} 
} 

錯誤堆棧時錯誤:

Process: com.example.ed.pieces, PID: 12939 
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ed.pieces/com.example.ed.pieces.Level001Activity}: android.view.InflateException: Binary XML file line #289: Binary XML file line #289: Error inflating class <unknown> 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
     at android.app.ActivityThread.-wrap11(ActivityThread.java) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:148) 
     at android.app.ActivityThread.main(ActivityThread.java:5417) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: android.view.InflateException: Binary XML file line #289: Binary XML file line #289: Error inflating class <unknown> 
     at android.view.LayoutInflater.inflate(LayoutInflater.java:539) 
     at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
     at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
     at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:393) 
     at android.app.Activity.setContentView(Activity.java:2166) 
     at com.example.ed.pieces.Level001Activity.onCreate(Level001Activity.java:62) 
     at android.app.Activity.performCreate(Activity.java:6237) 
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
     at android.app.ActivityThread.-wrap11(ActivityThread.java) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
     at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Caused by: android.view.InflateException: Binary XML file line #289: Error inflating class <unknown> 
     at android.view.LayoutInflater.createView(LayoutInflater.java:645) 
     at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
     at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694) 
     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762) 
     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
     at android.view.LayoutInflater.rInflate(LayoutInflater.java:835) 
     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
     at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
     at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
     at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
     at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
     at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:393) 
        at android.app.Activity.setContentView(Activity.java:2166) 
        at com.example.ed.pieces.Level001Activity.onCreate(Level001Activity.java:62) 
        at android.app.Activity.performCreate(Activity.java:6237) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
        at android.app.ActivityThread.-wrap11(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 


Caused by: java.lang.reflect.InvocationTargetException 
     at java.lang.reflect.Constructor.newInstance(Native Method) 
     at android.view.LayoutInflater.createView(LayoutInflater.java:619) 
     at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 10240012 byte allocation with 4194304 free bytes and 7MB 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.drawable.Drawable.createFromResourceStream(Drawable.java:1080) 
     at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635) 
     at android.content.res.Resources.loadDrawable(Resources.java:2540) 
     at android.content.res.TypedArray.getDrawable(TypedArray.java:870) 
     at android.view.View.<init>(View.java:3948) 
     at android.widget.ImageView.<init>(ImageView.java:145) 
     at android.widget.ImageView.<init>(ImageView.java:140) 
     at android.widget.ImageView.<init>(ImageView.java:136) 
+2

沒有好的理想來發表兩次相同的問題。 –

+0

是什麼?我沒有兩次發佈相同的問題 – Charas

+0

@Charas設置爲imageview之前,使用位圖壓縮高分辨率圖像。 – Aditya

回答

0

如果您的圖像分辨率很高,我建議您使用緩衝區加載圖像。

String defCoverPath = "drawable/" + "def_cover" + ".png"; 
yourView.setBackgroundDrawable(LoadResourceImage(defCoverPath)); 


public static BitmapDrawable LoadResourceImage(String resPath){ 
     AssetManager assets = MyApp.GetContext().getResources().getAssets(); 
     BitmapDrawable bitmapDrawable = new BitmapDrawable(); 

     try { 
      InputStream buffer = new BufferedInputStream((assets.open(resPath))); 
      Bitmap bitmap = BitmapFactory.decodeStream(buffer); 
      bitmapDrawable = new BitmapDrawable(MyApp.GetContext().getResources(), bitmap); 
     }catch (FileNotFoundException e){ 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return bitmapDrawable; 
    } 
+0

謝謝你的回答,讓我試試你的答案在一瞬間.. – Charas

1

內存不足錯誤

的內存不足錯誤是很常見的錯誤,當您正在爲多張圖片集或大的位圖或一些動畫的東西有關係的應用程序開發。在這種情況下,我們必須非常小心和高效地處理圖像或對象分配和釋放。 OOM錯誤出現在分配跨越堆限制或您的進程需要跨越堆限制的內存量時。

在Android中,每個應用程序都在Linux進程中運行。每個Linux進程都有一個運行在其中的虛擬機(Dalvik虛擬機)。一個進程可以要求的內存有一個限制,對於不同的設備它有所不同,對於手機和平板電腦也不同。當某些進程需要比限制更高的內存時,它會導致錯誤,即內存不足錯誤。

試試這可能幫助你在manifest文件中添加這個標籤。

android:largeHeap="true" 

將分配一大堆你的應用程序

要轉換可繪製成位圖,使用此,

Drawable myDrawable = getResources().getDrawable(R.drawable.logo); 
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap(); 

使用這種方法,可以解碼圖像

public static Bitmap decodeImageFile(File f,int WIDTH,int HIGHT){ 
      try { 
       //Decode image size 
       BitmapFactory.Options o = new BitmapFactory.Options(); 
       o.inJustDecodeBounds = true; 
       BitmapFactory.decodeStream(new FileInputStream(f),null,o); 

       //The new size we want to scale to 
       final int REQUIRED_WIDTH=WIDTH; 
       final int REQUIRED_HIGHT=HIGHT; 
       //Find the correct scale value. It should be the power of 2. 
       int scale=1; 
       while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT) 
        scale*=2; 

       //Decode with inSampleSize 
       BitmapFactory.Options o2 = new BitmapFactory.Options(); 
       o2.inSampleSize=scale; 
       return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
      } catch (FileNotFoundException e) {} 
      return null; 
      } 

然後在使用此方法時調用此方法:

Bitmap b = decodeImageFile(f, 1280, 720); 
+0

謝謝!讓我試着實現你的答案,我想我找到了造成問題的圖像,但是圖像的大小隻有100KB,在android中它被認爲太大了? – Charas