Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing or Incorrect images and backgrounds randomly throughout app lifecycle

I was hoping someone here might have an idea what causes this sort of behaviour:

Throughout my application, in seemingly random places and in random conditions I'm observing this strange UI issue. Images are on occasion being loaded black (with the correct bounds) or with the incorrect image source (again, with the correct bounds). This effects ImageViews and has effected android:background tags with references to colour resources.

My application relies on 6 library projects, it runs Native Code via a Service and Activities in the App use GlSurfaceViews (although, not all Activities which display the problem contain OpenGL components). The problem could I suppose be from any of these places or a combination of them through using large amounts of memory.

You can see this behaviour in the following screen shots:

  • This is actually a 6 or so pixel wide column separator image which has been incorrectly drawn into my ImageView (the ImageView seems to have correctly sized itself).

    Torn

  • When going out of the Application and then back in again (repeatedly) it instead appeared (and remained) like so:

    Black

  • After a Force Clear and a Clear App Data it returned to the correct format:

    This is the original:

As you can also see the Magnifying Glass image next to it is displaying fine in each of these. The problems with these missing/incorrect images and backgrounds seems to happen randomly, throughout the application lifecycle, and I've been unable to find a way of reproducing it.

The layouts for these images are nothing special, I'm not doing anything funny during the rendering lifecycle (i'm not overriding onDraw() or onMeasure() or the like). The source of these images aren't being set dynamically but via the XML.

As you can see from the above example, it's not a build issue as it occurs between app lifecycles not between installs. It's also happening on different devices, Samsung 8.9, Acer Iconia Tab, Motarola XOOM,

It seems to me to be some sort of error with the reference table, could it perhaps have been nudged by my native code? Or is it an effect of me in some stages of the application using too much memory?

Here's the XML source for the above example:

<LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/browseProgressWrapper"
                android:layout_width="match_parent"
                android:layout_height="@dimen/actionbar_compat_height"
                android:orientation="horizontal">
    <RelativeLayout android:layout_width="@dimen/search_bar_width"
                    android:layout_height="match_parent">       
        <EditText       android:id="@+id/browseFilter"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginTop="4dp"
                        android:layout_marginLeft="5dp"         
                        android:imeOptions="actionSearch"
                        android:background="@drawable/edit_text_blue"
                        android:maxLength="30"/>
        <ImageView      android:id="@+id/clearSearch"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentRight="true"
                        android:layout_centerVertical="true"
                        android:src="@drawable/ic_input_delete"
                        android:layout_marginRight="5dp"/>
    </RelativeLayout>                   
    <ImageView      android:id="@+id/browseFilterButton"
                    android:src="@drawable/ic_menu_search"
                    android:scaleType="center"
                    android:layout_width="@dimen/actionbar_compat_height"
                    android:layout_height="@dimen/actionbar_compat_height"
                    android:layout_gravity="center_vertical"
                    android:minWidth="@dimen/actionbar_compat_height"/>         
</LinearLayout>

A more full description of the code / layout surrounding another such occurrence I happened to get the screenshot for:

I have a "Settings" Activity which restarts my app after saving new settings details. It does this by stopping a Service, calling a new Activity (the Splash Activity) and finishing itself:

   mConfiguration.save();
   mConfiguration = new Configuration(Configuration.getInstance());
   getActivity().stopService(new Intent(getActivity(), NativeService.class));
   getActivity().finish();
   startActivity(new Intent(getActivity(), SplashActivity.class));

Most of the time (and on most devices) this works fine, the Splash Activity contains an image which loads correctly. Sometimes though on some devices the Splash Activity loads either an incorrect resource (what my testers refer as "an upside down Nike tick") or just a blank box (as seen below). Does anyone know why?

enter image description here

Here is the Layout for the Splash page, as you can see it's pretty simple, no surprises:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/ContentBackgroundColor"
    android:orientation="vertical" >

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="2" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/manager_android_400" />

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Large"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="2" />

</LinearLayout>

Theory tested and debunct:

I've theorised that this could be a processor/memory issue where the Layout isn't being drawn fully before the Splash screen exits and moves onto the next Activity so I put in this piece of code:

    image = (ImageView) findViewById(R.id.image);
    image.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        
        @Override
        public void onGlobalLayout() {
            image.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            moveToStartScreen.start();
        }
    });

The hope was the code above would make sure the Image is definitely loaded before moving onto the Start page but seems to have had no observable effect.

Another Theory

I was also wondering if this could be being caused by the R.id / R.colour / R.drawable resources some how being currupted in program execution? Does anyone know why that might happen.

Could my native code be running rampant on some memory addresses that Android isn't correctly allocating?

Has anybody noticed this before - or perhaps know why this behaviour occurs?

like image 830
Graeme Avatar asked Sep 24 '12 10:09

Graeme


1 Answers

Graeme, I had almost the same problem and found out that it was a reported bug of the android plattform. It was corrected in the 3.0 version I think. Which API are you compiling with? Try to build with the last available api and be sure to compile with JDK 1.6

If your problem is related to this bug, this should fix the problem.

like image 95
Sebastian Breit Avatar answered Sep 20 '22 17:09

Sebastian Breit