如何将AsyncTask的code到线器 [英] How do I put AsyncTask code to Thread Handler

查看:191
本文介绍了如何将AsyncTask的code到线器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想开发一个Android应用程序,可以列出所有的应用程序和缓存的。
但我面临一个问题,每当我敲击产生的清单我得到强制关闭,因为
java.lang.IllegalStateException:适配器的内容具有
改变,但ListView控件没有收到通知。
确保您的适配器的内容不是从后台线程修改,
但只有从UI线程。

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.

所以我想转换我的AsyncTask code主题哈德勒,任何机构可以请帮我解决这个问题。这里是我的code

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

先谢谢了。

推荐答案

首先,不要使用详细=新Asyntasck 。创建的AsyncTask类的下方,只需使用:

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

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

那么你的适配器实际上是从后台线程(AsyncTask的)修改,正如例外建议。该解决方案是将其移动到UI线程或者干脆runOnUiThread()包装它:

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

... ...

这篇关于如何将AsyncTask的code到线器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆