2014-09-06 75 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