0

I'm trying to develop an android app that could list all app and their cache's. But I'm facing a problem that whenever I tap on generated list I'm getting force close because java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.

So I'm trying to convert my AsyncTask code to Thread Hadler, can any body please help me out with this problem. Here is my code

public class Messages extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);



    msgList = (ListView) findViewById(R.id.MessageList);

    applicationCacheSize = new ArrayList<Long>();
    applicationPackageName = new ArrayList<String>();
    applicationName = new ArrayList<String>();

    cacheApplicationName = new ArrayList<String>();

    details = new ArrayList<MessageDetails>();
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            pd = ProgressDialog.show(Messages.this, "Loading..",
                    "Please Wait", true, false);
        }// End of onPreExecute method

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

            for (ApplicationInfo packageInfo : packages) 
            {
                try 
                {
                    Context mContext = createPackageContext(packageInfo.packageName, CONTEXT_IGNORE_SECURITY);
                    PackageManager pm = mContext.getPackageManager();
                    ApplicationInfo ai;
                    try {
                        ai = pm.getApplicationInfo( mContext.getPackageName(), 0);
                    } catch (final NameNotFoundException e) {
                        ai = null;
                    }
                    final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
                    appNames.add(applicationName);
                    appPackageName.add(packageInfo.packageName);
                    appCache.add(mContext.getCacheDir());

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


            for(int i=0; i<appCache.size(); i++)
            {

                try {
                    final PackageManager pm = getPackageManager();

                    Method getPackageSizeInfo;

                    getPackageSizeInfo = pm.getClass().getMethod(
                        "getPackageSizeInfo", String.class, IPackageStatsObserver.class);
                    getPackageSizeInfo.invoke(pm, appPackageName.get(i), new IPackageStatsObserver.Stub() {

                            @Override
                            public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
                                throws RemoteException {



                                final String title;
                                ApplicationInfo applicationInfo;



                                    try {
                                        applicationInfo = pm.getApplicationInfo(pStats.packageName, 0);
                                        title = (String)((applicationInfo != null) ? packageManager.getApplicationLabel(applicationInfo) : "???");

                                        MessageDetails Detail;
                                        Detail = new MessageDetails();
                                        Detail.setIcon(getPackageManager().getApplicationIcon( pStats.packageName ));
                                        Detail.setName(title);
                                        Detail.setSub("Cache Size -> "+(((pStats.cacheSize/1024) > 0)?(pStats.cacheSize/1024):"No Cache"));
                                        details.add(Detail);
                                        if((pStats.cacheSize) != 0 )
                                        {
                                            cacheApplicationName.add(title);
                                        }
                                    } catch (final NameNotFoundException e) {}

                               }
                        });
                } 
                catch (SecurityException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }   
            }
            return null;
        }// End of doInBackground method

        @Override
        protected void onPostExecute(Void result) {
            CustomAdapter adapter = new CustomAdapter(details, Messages.this);
            msgList.setAdapter(adapter);
            pd.dismiss();
        }// End of onPostExecute method
    }.execute((Void[]) null);
}
}

Thanks in advance.

Chethan Shetty
  • 1,972
  • 4
  • 25
  • 45

1 Answers1

0

First, do not use detail = new Asyntasck. Create The Asynctask Class below and just use :

AsynTask myTask = new AsynTask();
myTask.execute();

Then your adapter is actually modified from a background thread (asynctask), exactly as the exception suggested. The solution is moving it to UI thread or simply wrapping it with runOnUiThread():

... ...

runOnUiThread(new Runnable() {
  public void run() {
    details.add(result) //use a foreach here
    CustomAdapter adapter = new CustomAdapter(details, Messages.this);
    adapter.notifyDataSetChanged();
    msgList.setAdapter(adapter);
    pd.dismiss();

  }
}); // end of runOnUiThread

... ...
marshallino16
  • 2,645
  • 15
  • 29