Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7959347
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T04:33:31+00:00 2026-06-04T04:33:31+00:00

I hope the title is not mis-leading. I am trying to implement onRetainNonConfigurationInstance() of

  • 0

I hope the title is not mis-leading. I am trying to implement onRetainNonConfigurationInstance() of an AsyncTask of loading images and am getting this error "Java.lang.RuntimeException:Unable to retain Activity". Here is my code for onRetainNonConfigurationInstance():

public Object onRetainNonConfigurationInstance(){
  //final ListView listview = list;

  final int count = list.getChildCount();
    final LoadedImage[] mylist = new LoadedImage[count];

    for(int i = 0; i < count; i++){
        final ImageView v = (ImageView)list.getChildAt(i); // getting error here
        mylist[i] = new LoadedImage(((BitmapDrawable) v.getDrawable()).getBitmap());
    }
    return mylist;
}

Here is the Logcat:

05-18 08:43:15.385: E/AndroidRuntime(28130): java.lang.RuntimeException: Unable to retain activity {com.MyApps.ImageGen/com.MyApps.ImageGen.Wallpapers}: java.lang.ClassCastException: android.widget.LinearLayout
05-18 08:43:15.385: E/AndroidRuntime(28130):    at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:2989)
05-18 08:43:15.385: E/AndroidRuntime(28130):    at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3100)
05-18 08:43:15.385: E/AndroidRuntime(28130):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3216)
05-18 08:43:15.385: E/AndroidRuntime(28130):    at android.app.ActivityThread.access$1600(ActivityThread.java:132)

Here is my layout with the ListView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:cacheColorHint="#00000000"
    android:listSelector="@android:color/transparent" >
</ListView>     
</LinearLayout>

Here is how I setup the ListView:

private void setupViews() { 
        list = (ListView)findViewById(android.R.id.list);
        list.setDivider(null);
        list.setDividerHeight(0);
        imageAdapter = new ImageAdapter(getApplicationContext());
        list.setAdapter(imageAdapter);
        list.setOnItemClickListener(this);
}

my async task and Item Adapter:

class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {


    @Override
    protected Object doInBackground(Object... params) {

        Bitmap bitmap = null;
        Bitmap newbitmap = null;
        Uri uri = null;

        String [] img = {MediaStore.Images.Media._ID};

        String state = Environment.getExternalStorageState();

        if(Environment.MEDIA_MOUNTED.equals(state)){    

        cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, img, null, null, null);

        } else {
        // cursor = getContentResolver().query(MediaStore.Images.Media.INTERNAL_CONTENT_URI, img, null, null, null);

         inInternalStorage = true;
        }

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
        int size = cursor.getCount();

        if(size == 0){
            //Toast.makeText(getApplicationContext(), "There are no Images on the sdcard", Toast.LENGTH_SHORT).show();
            //System.out.println("size equals zero");

            Wallpaper.this.runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText(getApplicationContext(), "There are no Images on the sdcard", Toast.LENGTH_SHORT).show();
                }
            });

            return params;
        }else {

        }

        for(int i = 0; i < size; i++){
            cursor.moveToPosition(i);
            int ImageId = cursor.getInt(column_index);

            if(inInternalStorage == true){
             uri = Uri.withAppendedPath(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "" + ImageId);
         }else {
             uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + ImageId);
         }


         try {
             BitmapFactory.Options options = new BitmapFactory.Options();
             options.inJustDecodeBounds = true;

             BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);

             int imageHeight = options.outHeight;
             int imageWidth = options.outWidth;
             String imageType = options.outMimeType;

             Log.i(TAG, "imageheight = " + imageHeight);
             Log.i(TAG, "imagewidth = " + imageWidth);
             Log.i(TAG, "imageType = " + imageType);

             //options.inSampleSize=4;

             options.inSampleSize = calculateInSampleSize(options, imageWidth, imageHeight);

            options.inJustDecodeBounds = false;
             //bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
             bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);

             if(bitmap != null){
                 newbitmap = Bitmap.createScaledBitmap(bitmap, 180, 180, true);
                 bitmap.recycle();
             }
             if(newbitmap != null){
                 publishProgress(new LoadedImage(newbitmap));

             }
         }catch(IOException e){

         }
         //cursor.close();
        }
        cursor.close();
        return null;    
    }

    @Override
    public void onProgressUpdate(LoadedImage... value){
        addImage(value);
    }

       @Override
        protected void onPostExecute(Object result) {
            setProgressBarIndeterminateVisibility(false);
        }
}

private static class LoadedImage {
    Bitmap mBitmap;

    LoadedImage(Bitmap bitmap) {
        mBitmap = bitmap;
    }

    public Bitmap getBitmap() {
        return mBitmap;
    }
}

/*Image Adapter to populate grid view of images*/

public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();


    public ImageAdapter(Context context){
        this.mContext = context;
    }

    public void addPhotos(LoadedImage photo){
        photos.add(photo);
    }

    @Override
    public int getCount() {
        return photos.size();
    }


    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ImageView image;
        ViewHolder holder;

        if(convertView == null){
            LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            //convertView = inflater.inflate(R.layout.image_list,null);
            convertView = inflater.inflate(R.layout.media_view, null);
            holder = new ViewHolder();

            holder.image = (ImageView)convertView.findViewById(R.id.media_image_id);

            //holder.item_name = (TextView)convertView.findViewById(R.id.media_image_id);

            convertView.setTag(holder); 
        } else{
            holder = (ViewHolder)convertView.getTag();
        }   
        //holder.image.setLayoutParams(new GridView.LayoutParams(100, 100));

         //String item_name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME));

            holder.image.setImageBitmap(photos.get(position).getBitmap());    

            //holder.item_name.setText(item_name);

        return convertView;
    }
}

static class ViewHolder {
   ImageView image;
   TextView item_name;
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    Cursor cursor = null;
    int image_column_index = 0;
    String[] proj = {MediaStore.Images.Media.DATA};

    String state = Environment.getExternalStorageState();

  if(Environment.MEDIA_MOUNTED.equals(state)){


    cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,proj,null, null,null);
  }else{
      cursor = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI,proj,null, null,null);

  }
    cursor.moveToPosition(position);
    image_column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);


    String info = cursor.getString(image_column_index);
    Intent imageviewer  = new Intent(getApplicationContext(), ViewImage.class);
           imageviewer.putExtra("pic_name", info);
           startActivity(imageviewer);

     cursor.close();
}

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 = 2;

if (height > reqHeight || width > reqWidth) {
    if (width > height) {
        inSampleSize = Math.round((float)height / (float)reqHeight);
    } else {
        inSampleSize = Math.round((float)width / (float)reqWidth);
    }
}

/*final int REQUIRED_SIZE = 180;

int scale = 1;
if(reqWidth > REQUIRED_SIZE || reqHeight > REQUIRED_SIZE){
    scale = (int)Math.pow(2, (int)Math.round(Math.log(REQUIRED_SIZE/(double)Math.max(reqHeight, reqWidth)) / Math.log(0.5)));
}*/

return inSampleSize;

}

other Methods within Async Task:

private void loadImages() {
 final Object data = getLastNonConfigurationInstance();
 if(data == null){
     new LoadImagesFromSDCard().execute();
 }else {
     final LoadedImage[] photos = (LoadedImage[])data;
     if(photos.length == 0){

        new LoadImagesFromSDCard().execute();
     }
     for(LoadedImage photo:photos){
         addImage(photo);
    }
 }

}

private void addImage(LoadedImage... value) {

    for(LoadedImage photo: value){
        imageAdapter.addPhotos(photo);  
        imageAdapter.notifyDataSetChanged();
    }

}

I am assuming I should first get the root element before I get the ListView from the logcat error, but I don’t know how, I can’t seem to find a suitable method from the documentation.

P.S: I am using an Activity and not a ListActivity.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T04:33:32+00:00Added an answer on June 4, 2026 at 4:33 am

    The exception tells you that you try to do an invalid cast. My guess is that your row layout isn’t a simple ImageView like you assume with the cast in the onRetainNonConfigurationInstance(), instead your row layout probably has a parent Linearlayout that wraps the ImageView(and other views?!). When you call the method getChildAt you get that parent Linearlayout which you try to cast to a ImageView. Instead you should do this:

    //...
    for(int i = 0; i < count; i++){
            LinearLayout parent = (LinearLayout)list.getChildAt(i);
            final ImageView v = (ImageView) parent.findViewById(R.id.the_id_of_the_imageview_from_theRow_layout);
            mylist[i] = new LoadedImage(((BitmapDrawable) v.getDrawable()).getBitmap());
    }
    

    Note: The getChildAt method returns the rows views for the visible rows only so if you try to access the View for a row that isn’t currently visible you’ll most likely end up with a NullPointerException(you should get the drawables directly from the adapter and not from parsing all the rows Views).

    Edit based on the comments:

    If I understood your problem, the behavior you see it’s normal. You didn’t say how you ended up getting the bitmaps in the onRetainNonConfigurationInstance but my guess is that you just save the images from the ListView rows that are currently visible to the user. When it’s time to restore the adapter with the images from getLastNonConfigurationInstance() you end up getting only those images which were previously visible. This will get worse if you rotate the phone again as, most likely, there are fewer images visible in landscape orientation then in the portrait orientation.

    I don’t know if this will work but you could try to modify the LoadedImage class to store the id of the image from MediaStore.Images.Media. When it’s time to save the configuration, stop the LoadImagesFromSDCard task and nullify all the images(remove the Bitmap to which LoadedImage points)from the LoadedImages ArrayList(in the adapter) except the ones that are currently visible to the user. Send the photos ArrayList from your adapter through
    onRetainNonConfigurationInstance.

    When it’s time to restore the adapter set the photos ArrayList of your new adapter to the one you got back and put the ListView to the position of the visible images(so the user sees the sent images). In the getView method of your adapter you’ll put a default image(like loading…) when you have a null value for the Bitmap in the associated LoadedImage class. Start a new LoadImagesFromSDCard task to get the images and parse them again. When you get the id from MediaStore.Images.Media you’ll check if a LoadedImage with this id exists in the adapter and if it has a Bitmap set to it. If it doesn’t exist(or it doesn’t have a Bitmap associated) then load the image and put it in the adapter, if not the image already exists and move to the next one.

    I don’t know if the solution above will work or if it’s efficient. I would recommend you to modify the code and load images on demand instead of loading all up in a big task.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I hope the title is not too confusing. I am trying to make folders
I'm not even sure about how to title this qn. But, hope there is
Not exactly how sure how to title this question, so I hope the title
The title is probably not accurate but I hope that reading this post you
I hope the title and following text are clear, I'm not very familiar with
(I hope this is a valid question) As I stated in my title, I'm
I hope my title is not misleading, but what I'm looking for is a
I hope the title doesn't sound too subjective; I absolutely do not mean to
I hope the title of this question is somewhat clear, I couldn't figure out
Sorry if my title is not clear, I'm not sure how to word this.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.