2014-09-06 72 views
0

我無法完全理解如何實現我想要的功能。我試圖從drawables文件夾中加載一個隨機圖像到圖像視圖。我通過抓取所有drawable的引用並將id放入int數組來完成此操作。我比隨機選擇一個介於零和最大數組長度之間的數字,並使用該圖像填充圖像視圖。Android內存不足錯誤,將圖像中的隨機圖像加載到一個圖像中查看

當我旋轉屏幕太多,而不是太多的隨機圖像已被加載到內存我猜測,因爲內存不足異常被拋出時,會出現問題。

我試圖回收使用後,但如果我再次拉回該圖像,我得到一個試圖重用再循環位圖錯誤。

問題活動

package com.example.hip_hoptrivia; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.graphics.Bitmap; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.util.SparseArray; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ImageView; 
import android.widget.TextView; 
import android.widget.Toast; 

public class QuestionsActivity extends ActionBarActivity { 

    private JSONObject dataBase = null; 
    private JSONArray triviaQuestions = null; 
    private int currentQuestion = 0, currentDrawable; 
    //setup random question images 
    private int[] questionImages = new int[] {R.drawable.boswell_cheo_mural, R.drawable.buddha, R.drawable.dq, 
    R.drawable.equipment, R.drawable.graffiti, R.drawable.huge_image, R.drawable.rappers, R.drawable.spray_paint, 
    R.drawable.wza}; 

    private static final String FILE_NAME = "questiondata.txt"; 
    private static final String TAG_QUESTION = "Question"; 
    private static final String TAG_ANSWER = "Answer"; 
    private static final String TAG_INFO = "Info"; 
    private static final String TAG_TRIVIA = "Trivia"; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_questions); 
     createData(); 
     createQuestion(); 
     buttonSetup(); 

    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

/*  ImageView imageView = (ImageView)findViewById(R.id.randomImage); 
     Drawable drawable = imageView.getDrawable(); 
     if (drawable instanceof BitmapDrawable) { 
      BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; 
      Bitmap bitmap = bitmapDrawable.getBitmap(); 
      bitmap.recycle(); 
      bitmap = null; 
     }*/ 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.questions, 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. 
     if(MyUtilities.NavigateActionItems(this , item)) 
      return true; 
     else 
      return super.onOptionsItemSelected(item); 

    } 

    private void createData(){ 

     String result = MyUtilities.parseLocalFile(this , FILE_NAME); 

     if(result != null){ 
      try{ 
       dataBase = new JSONObject(result); 
       triviaQuestions = dataBase.getJSONArray(TAG_TRIVIA); 

      }catch(JSONException e){ 
       e.printStackTrace(); 
      } 

     }else{ 
      Log.e("Parsing", "coudln't extract"); 
     } 


    } 

    private void createQuestion(){ 
     try{ 
      JSONObject s = triviaQuestions.getJSONObject(currentQuestion); 
      String question = s.getString(TAG_QUESTION); 

      //Clear Input Text 
      EditText userInputEditText = (EditText)findViewById(R.id.userInput); 
      userInputEditText.setText(""); 

      //Place Question Text 
      TextView questionTextView = (TextView)findViewById(R.id.currentQuestion); 
      questionTextView.setText(question); 

      //Create random image that goes with text 
      ImageView randomImage = (ImageView)findViewById(R.id.randomImage); 
      //Random number such that [Min + (int)(Math.random() * ((Max - Min) + 1))] 
      currentDrawable = (int)(Math.random() * ((questionImages.length-1) + 1)); 
      randomImage.setImageResource(questionImages[currentDrawable]); 


     }catch(JSONException e){ 
      e.printStackTrace(); 
     } 
    } 

    private void checkAnswer(){ 
     try{ 
      JSONObject s = triviaQuestions.getJSONObject(currentQuestion); 
      String answer = s.getString(TAG_ANSWER); 
      EditText userInputEditText = (EditText)findViewById(R.id.userInput); 
      String userAnswer = userInputEditText.getText().toString(); 


      //check if input is correct 
      if(answer.equalsIgnoreCase(userAnswer)){ 
       ++currentQuestion; 
       createQuestion(); 
      }else{ 
       Toast.makeText(getApplicationContext(), "Wrong", 
          Toast.LENGTH_LONG).show(); 
      } 

     }catch(JSONException e){ 
      e.printStackTrace(); 
     } 

    } 

    private void buttonSetup(){ 
     Button submitButton = (Button) findViewById(R.id.submitButton); 
     submitButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       //On input check if correct answer 
       checkAnswer(); 
      } 
     }); 
    } 
} 

佈局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.hip_hoptrivia.QuestionsActivity" > 

    <EditText 
     android:id="@+id/userInput" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:layout_marginBottom="112dp" 
     android:ems="10" > 

     <requestFocus /> 
    </EditText> 

    <TextView 
     android:id="@+id/currentQuestion" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/userInput" 
     android:layout_centerHorizontal="true" 
     android:layout_marginBottom="115dp" 
     android:text="Medium Text" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 


    <Button 
     android:id="@+id/submitButton" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignTop="@+id/userInput" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="48dp" 
     android:text="Submit" /> 

    <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/randomImage" 
     android:layout_above="@+id/currentQuestion" 
     android:layout_centerHorizontal="true" /> 

</RelativeLayout> 

回答

1

首先,由於內存不足的錯誤可能是一個嚴重的問題時顯示圖像,你需要正確地約Displaying Bitmaps Effeciently參考。

其次

I have tried to recycle the after usage, but if I pull that image back up again i get a trying to reuse recycled bitmap error.

你應該使用

((BitmapDrawable)imageView.getDrawable()).getBitmap().recycle(); 

改變到一個新的圖像前。

現在如果您試圖交換已經回收的圖像,則此功能無法使用。因此,你會得到

Canvas: trying to use a recycled bitmap error 

在你onDestroy()你可以嘗試

@Override 
public void onDestroy() { 
super.onDestroy(); 
imageView.setImageDrawable(null); 
} 

替換imageViewImageView name.Hope這會有所幫助。

+0

看來只是添加imageView.setImageDrawable(null)修復了問題。我認爲,它保持操作系統在切換時保持對圖像的引用,從而將其標記爲gc。非常感謝!我會認爲,通過將可引用的引用切換爲它會丟失對舊映像的引用。儘管如此,似乎你必須明確。 – 2014-09-06 08:09:04

+0

你對gc的理解完全正確。如果此答案解決了您的問題,請單擊答案左側的「正確標記」接受答案。通過接受答案,它將幫助訪問此問題的任何其他人。 – 2014-09-06 15:00:00

+0

因此,如果它解決了你的問題,永遠不要忘記接受答案。如果你真的很喜歡答案,你也可以通過點擊「UP」符號來提高答案。 – 2014-09-06 15:02:15