- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 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/
我今天在我的 Android 项目中遇到了一个涉及 aSyncTasks 的问题,经过一些研究找到了答案,并且与我交谈过的人都没有意识到,所以我想我会与 SO 社区分享,以防万一有人发现它有任何用处。
我目前正在 AsyncTask 的 onPostExecute 方法中执行类似的操作,其中 NewTask 不是当前正在执行的任务: private class OlderTask extends A
所以,我正在研究一个条形码解码器,一旦我们有了条形码,它就会通过互联网进入多个 API 来解码刚刚扫描的内容。问题是我必须将一些 XML 解析链接在一起,我不知道我做的是否正确。 因此,扫描条形码后,
我的团队开发了一个新的 Android 应用程序,它广泛使用了 Room。 我不确定我们是否正确使用 AsyncTask。 我们不得不在 AsyncTasks 中包装所有对 insert/update
我查看了其他问题,但未能澄清我对从另一个任务调用任务的疑问,我有以下代码: protected List doInBackground(String... params) try {
我正在开发一个访问 Web 服务的应用程序,并使用从中获取的 JSON 创建一个对象并在我的代码中使用它。尽管我的应用程序正在运行,但我不知道它是否写得很好且完美无缺。 我将解释我的内容,然后放置一些
虽然我还没有尝试过,但从理论上讲,我问这个问题只是为了消除我的疑虑。 我有这样一个场景:1. 向服务器发送请求并接收 JSON 响应。为此,我正在使用 AsyncTask,因为接收响应可能会有延迟。2
我有以下 AsyncTask 的实现,允许多个 AsyncTask 同时运行: public abstract class MyAsyncTask extends AsyncTask { pu
花了很多时间试图解决这个问题,我已经阅读了很多问题、论坛、答案......但它仍然不会更新 UI。 我的最终目标是从用户那里获取一个搜索词,并将一个 httprequest 发送到用 JSON 回复的
我有一个异步任务 private class LoadData extends AsyncTask { private String WEBURL; LoadData(String u
我正在用 android 做一些编码工作。我几乎遇到了一个问题,为了解决这个问题,我需要一个匿名 AsyncTask 类来执行。但我还需要在执行之前传递并反对这个类。我尝试了下面的代码,但它不起作用,
我有两个 AsyncTask:第一个寻找素数,如果成功,我必须调用第二个 AsyncTask 显示单词“Yop!” (将这个词添加到数组列表中,并显示在AsyncTask三)。 如果我从 onProg
我想使用 AsyncTask 将图像加载到 ListView。 private class LoadImageTask extends AsyncTask,Void,Bitmap>{ @Sup
在我的 AsyncTask 的某个时刻,在完成一些验证之后,我需要派生另一个线程来做一些其他工作。所以我现在想要两个后台线程,每个都做自己的事情(每个执行大约 2-3 秒)。我们的想法是最大限度地提高
(这与空指针无关):我在 AsyncTask 中有一个进度条,并且添加了一个取消按钮来取消 asynctask。 我可以从异步任务外部取消异步任务,但我需要在异步任务下实现的progressdialo
我有一个 Activity ,在启动时调用“json”来获取歌曲的数据类别,之后我调用方法“AsyncTask”来获取来自另一个“JSON”的歌曲列表问题是,当我启动 Activity 时,它被锁定,
我想做以下事情。我想显示一个包含信息和图像的列表。这些图像需要一段时间才能加载,所以我想我会采取不同的方式。我会使用两个 AsyncTasks。第一个创建所有布局并用除图像之外的数据填充它。第二个只是
如果我做了这样的事情: public class MyFragment extends Fragment { private GetDataTask mGDT; //onCreat
在 Android Activity 中,我在 onCreate 方法中执行 AsyncTask。我应该在 AsyncTask 的 onPostExecute 中还是在 OnCreate 方法中声明
我对 AsyncTask 有疑问我尝试为 10 个 Json 文件向互联网打开 10 个请求,因此我读取它并将其保存到用户设备_由于数据差异,此文件必须分开,包括。 那么,将每个请求放在单个 Asyn
我是一名优秀的程序员,十分优秀!