0

すべてのアプリとそのキャッシュを一覧表示できる Android アプリを開発しようとしています。しかし、生成されたリストをタップするたびに強制的に閉じられるという問題に直面しています。 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.

AsyncTask コードを Thread Hadler に変換しようとしているのですが、どなたかこの問題を解決してください。これが私のコードです

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);
}
}

前もって感謝します。

4

1 に答える 1

0

まず、使用しないでくださいdetail = new Asyntasck。以下の Asynctask クラスを作成し、以下を使用します。

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

次に、例外が示唆するとおり、アダプターは実際にはバックグラウンド スレッド (asynctask) から変更されます。解決策は、UI スレッドに移動するか、単純に 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

... ...
于 2013-07-10T09:49:29.870 に答える