在AsyncTask中启动Activity时内存泄漏(从Thread更改)

| 我是Android开发的新手,当发现内存泄漏时即将完成我的第一个应用程序。 当我从线程内启动新活动时,发生泄漏:
private static class CatalogRowOnClickListener implements OnClickListener 
{
    List<CatalogRow> catRows;
    WeakReference<CatalogViewActivity> mActivity;

    CatalogRowOnClickListener(WeakReference<CatalogViewActivity> mActivity) 
    {
        this.mActivity = mActivity;
        catRows = new ArrayList<CatalogRow>();
    }


    public void addCatalogRow(CatalogRow row) 
    {
        catRows.add(row);
    }

    public void onClick(View v) 
    {   
        v.setBackgroundColor(Color.argb(150, 255, 255, 255));


        final ProgressBar linProgressBar = (ProgressBar) v.findViewById(R.id.CatProgressBar);
        linProgressBar.setVisibility(View.VISIBLE);

        final View fv = v;
        final fItem fhitem = findFItem(fv);
        try
        {
            new Thread()
            {


                public void run() 
                {
                    initializeApp();

                }
                public void initializeApp()
                {
                    // Initialize application data here


                    FItemListStore.getItemsFromWebservice(fhitem);
                    boolean isArticleOverview = false;

                    for(FItem item: FItemListStore.fItemViewStorage) 
                    {   
                        if( item instanceof fiArticle ) 
                        {
                            isArticleOverview = true;
                            break;
                        }
                    }


                    Intent intent = new Intent();
                    intent.setClassName(\"nl.project.Android\", \"nl.project.Android.Activities.HomeViewActivity\");
                    Bundle bundle = new Bundle();

                    if(isArticleOverview)
                    {
                        bundle.putInt(\"OverviewNr\", 1);
                    }
                    else
                    {
                        bundle.putInt(\"OverviewNr\", 0);
                    }
                    intent.putExtras(bundle);

                    //if( mActivity.get() != null )
                        mActivity.get().startActivity(intent);

                    mActivity.clear();

                }
            }.start();
        }
        catch (Exception e) {}

        //Debug.stopMethodTracing();
        //android.os.Debug.stopMethodTracing();
    }     
执行此代码后,应用程序的HPROF转储表明该线程将始终保留在堆中并呈指数增长。研究这一点指向引用导致泄漏的线程内的上下文。因此,我几次更改了这段代码,直到它成为该版本,并且在静态类中仅具有弱引用(这是其他帖子中提到的一些内容) 我想在线程中启动Activity的原因是因为我需要从缓慢而大型的Web服务读取数据,这需要一些时间。我在活动中显示了一个加载栏,突出显示选定的项目,直到完成“ 1”,然后再开始新的活动。 可能是没有正确的方法在不引起内存泄漏的情况下启动线程内的活动吗?而且,如果是这样,在xml解析器完成工作之后,还有另一种方法让我启动意图吗? 在弗拉基米尔和海子的建议下,我将线程更改为AnyncTask。我保留的堆的增长已停止,但是我开始的AsyncTask线程仍然保留在堆中。这是我的新代码:
private static class QueryFHTask extends AsyncTask<FredHopperItem, Integer, Boolean> 
 {

     WeakReference<CatalogViewActivity> mActivity;

     QueryFHTask(WeakReference<CatalogViewActivity> mActivity) 
     {
        this.mActivity = mActivity;

     }


     protected void onPreExecute() 
     {

     }
     protected Boolean doInBackground(FItem... items) {
         int count = items.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             FItemListStore.getItemsFromWebservice(items[i]);
             boolean isArticleOverview = false;

             for(FItem item: FItemListStore.fhItemViewStorage) 
             {  
                if( item instanceof FArticle ) 
                {
                    isArticleOverview = true;
                    break;
                }
             }

             Intent intent = new Intent();
             intent.setClassName(\"nl.project.Android\", \"nl.project.Android.Activities.HomeViewActivity\");
             Bundle bundle = new Bundle();

             if(isArticleOverview)
             {
                bundle.putInt(\"OverviewNr\", 1);
             }
             else
             {
                bundle.putInt(\"OverviewNr\", 0);
             }
             intent.putExtras(bundle);
             mActivity.get().startActivity(intent);

         }
         return true;
     }

     protected void onProgressUpdate(Integer... progress) {
         //setProgressPercent(progress[0]);

     }

     protected void onPostExecute(Long result) {
         //showDialog(\"Downloaded \" + result + \" bytes\");
     }
 }

private static class CatalogRowOnClickListener implements OnClickListener 
{
    List<CatalogRow> catRows;
    WeakReference<CatalogViewActivity> mActivity;

    CatalogRowOnClickListener(WeakReference<CatalogViewActivity> mActivity) 
    {
        this.mActivity = mActivity;
        catRows = new ArrayList<CatalogRow>();
    }


    public void addCatalogRow(CatalogRow row) 
    {
        catRows.add(row);
    }

    public void onClick(View v) 
    {   
        v.setBackgroundColor(Color.argb(150, 255, 255, 255));
        final ProgressBar linProgressBar = (ProgressBar) v.findViewById(R.id.CatProgressBar);
        linProgressBar.setVisibility(View.VISIBLE);

        final View fv = v;
        final fItem fhitem = findFItem(fv);     
        new QueryFHTask(mActivity).execute(fhitem);       


    }
为了澄清我的问题,这里是我的HPROF线程概述堆转储的其中之一(很难阅读,因为由于用户级别的原因,我不允许发布包含MAT中的链接和图像的html。 )。 AsyncTask线程保留376或344的堆。随着我浏览该应用程序的时间增加,
AsyncActivity
线程将保留越来越多的堆...
Name Instance Shallow Heap Retained Heap Context Class Loader 
main java.lang.Thread @ 0x40027550 80 1.464 dalvik.system.PathClassLoader @ 0x4051ce30 
JDWP java.lang.Thread @ 0x40515838 80 384  
AsyncTask #6 java.lang.Thread @ 0x406ea788 80 376 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #7 java.lang.Thread @ 0x40690178 80 376 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #4 java.lang.Thread @ 0x4068a630 80 376 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #3 java.lang.Thread @ 0x406851f0 80 376 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #5 java.lang.Thread @ 0x405d9f28 80 376 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #2 java.lang.Thread @ 0x40539db0 80 376 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #1 java.lang.Thread @ 0x40517180 80 376 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #8 java.lang.Thread @ 0x4068cdb0 80 344 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #9 java.lang.Thread @ 0x4068b558 80 344 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #10 java.lang.Thread @ 0x4068a178 80 344 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #11 java.lang.Thread @ 0x406639f0 80 344 dalvik.system.PathClassLoader @ 0x4051ce30 
AsyncTask #12 java.lang.Thread @ 0x40661b00 80 344 dalvik.system.PathClassLoader @ 0x4051ce30 
Binder Thread #2 java.lang.Thread @ 0x40519b20 80 344  
Binder Thread #1 java.lang.Thread @ 0x40516868 80 344  
Thread-2 java.util.logging.LogManager$2$1 @ 0x40195298 80 168 dalvik.system.PathClassLoader @ 0x400277f8 
Signal Catcher java.lang.Thread @ 0x40515778 80 160  
Compiler java.lang.Thread @ 0x405158e8 80 152  
HeapWorker java.lang.Thread @ 0x40515618 80 152  
GC java.lang.Thread @ 0x405156d0 80 136  
Total: 21 entries  1.680 7.656 
    
已邀请:
您应该查看AsyncTask,在ѭ5中进行加载,在
onPreExecute
中设置状态栏,用
publishProgess
发布进度更新,然后在
onPostExecute
中删除进度条。     
哦,天哪,在后台完成一些工作之后,开始一项活动是一件特别的事情。它是带有ProgressDialog的AsyncTask。看一个例子。     

要回复问题请先登录注册