gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 04:40:45 27 4
gpt4 key购买 nike

我是 Android 开发的新手,正要完成我的第一个应用程序时,我发现我有一个巨大的内存泄漏。

当我从一个线程中开始一个新 Activity 时发生泄漏:

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,是因为我需要从一个又慢又大的webservice中读取数据,这需要一些时间。我在 Activity 中显示了一个加载栏,突出显示所选项目,直到 XMLparser 完成,然后开始一个新的 Activity。

可能是没有正确的方法可以在线程内启动 Activity 而不导致内存泄漏?而且,如果是这样,在 xml 解析器完成其工作后,我还有其他方法可以启动 Intent 吗?


根据 Vladimir 和 Heiko 的建议,我将线程更改为 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 线程概述堆转储的副本(很难阅读,因为由于我的用户级别,我不允许发布带有链接和图像的 html,就像在 MAT 中一样......) . 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

最佳答案

哦,天哪,在后台完成一些工作后启动 Activity 是一件特别的事情。它是带有 ProgressDialog 边界的 AsyncTask。查看 example.

关于android - 在 AsyncTask 中启动 Activity 时内存泄漏(由 Thread 更改),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6030300/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com