我的项目中有一个AsyncTask,有一个警告,它说:
ProgressDialog progressDialog;
AsyncTask<String,Void,Boolean> asyncTask = new AsyncTask<String, Void, Boolean>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setTitle("بارگذاری");
progressDialog.setMessage("در حال دریافت اطلاعات از پایگاه داده..");
progressDialog.setCancelable(false);
progressDialog.show();
}
@Override
protected Boolean doInBackground(String... strings) {
Cursor cursor = DataBase.getinfos(page,limit);
if (cursor.isAfterLast()){
return false;
}else {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
PropertyInfo propertyInfo = new PropertyInfo();
propertyInfo.setId(cursor.getInt(0));
propertyInfo.setAddress(cursor.getString(1));
propertyInfo.setDetails(cursor.getString(2));
propertyInfo.setOptions(cursor.getString(3));
propertyInfo.setMortgage_cost(cursor.getLong(4));
propertyInfo.setRent_cost(cursor.getLong(5));
propertyInfo.setOwner_name(cursor.getString(6));
propertyInfo.setUnits_per_floor(cursor.getInt(7));
propertyInfo.setCurrent_floor(cursor.getInt(8));
propertyInfo.setFloors_count(cursor.getInt(9));
propertyInfo.setRoom_count(cursor.getString(10));
propertyInfo.setOwner_phone(cursor.getString(11));
propertyInfo.setDocument_type(cursor.getString(12));
propertyInfo.setRequest_type(cursor.getString(13));
propertyInfo.setProperty_type(cursor.getString(14));
propertyInfo.setCost(cursor.getLong(15));
propertyInfo.setArea(cursor.getInt(16));
propertyInfo.setHouse_type(cursor.getString(17));
propertyInfo.setLocation(cursor.getString(19));
propertyInfo.setNoeMorajeKonande(cursor.getString(18));
propertyInfo.setShomareSafhe(cursor.getString(20));
propertyInfo.setDate(cursor.getString(21));
arrayList.add(propertyInfo);
lastRecivedDataSize++;
}
return true;
}
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
loading = aBoolean;
if (arrayList.isEmpty()) {
setContentView(R.layout.no_result);
} else {
mAdapter = new RecyclerInfoAdapter(arrayList, ShowAllDataActivity.this);
mAdapter.notifyDataSetChanged();
recyclerView.setAdapter(mAdapter);
recyclerView.scrollToPosition(pastVisiblesItems + visibleItemCount - 1);
page++;
}
progressDialog.dismiss();
}
};
asyncTask.execute();
为了澄清ynsmtki在特定情况下的含义:您的asyncTask是在UI事件处理程序/回调方法中声明的(让我们将其命名为onSomeUIEventHandler{},但它将产生自己的线程,并携带更长的范围引用,如(1)progressDialog,(2)DataBase,(3)propertyInfo,这些引用是泄漏警告的来源。
正如其他人所指出的,这一直是一个安静的问题,直到IntelliJ在两年前部署(实际上是释放)他们的KotlinT分析器。直到最近(在AS V3.0+)中,分析器实际上提供了解决泄漏的有意义的提示,这一直是一个需要解决的难题。下面是它现在的辅助功能,它甚至通过IDE为您生成子类签名:
因此,您需要通过为它们指定getter()方法,即在扩展asyncTask类中使用的getDatabase()、getProgressDialog()和getPropertyInfo(),来执行()异步任务线程,这些方法具有上述三个类的只读副本:
static class HandleDBaseAsyncTask extends AsyncTask<Parameterized.Parameters,Process, Result>{
final PropertyInfo propertyInfo = getPropertyInfo();
final YourDatabaseClass Database = getDatabase();
final ProgressDialog progressDialog = getProgressDialog();
// Then finish off with your original
onPreExecute() {...}
doInBackground(){...}
onPostExecute(){...}
}
然后返回对话框泄漏器的原始回调:
ProgressDialog progressDialog;
ProgressDialog getProgressDialog(){ return progressDialog;}
// and the same for other leakers
onSomeUIEventHandler{
HandleDBaseAsyncTask handleDBTask = new HandleDBaseAsyncTask();
handleDBTask.execute();
// ...
}
在任务的静态上下文中,getter的实例方法不能被调用的地方可能还有其他微妙之处,所以您可以使它们成为静态的,或者将它们的单例容器(如Activity或context)传递到asyncTask块中,以便在那里使用它们的getter()来通过编译器错误。
ParentContainer parent = getDialogContainer();
final ProgressDialog progressDialog = parent.getProgressDialog() // etc
这是我的代码: 我怎么纠正这个?
我正在开发一个带有服务的Android 2.3.3应用程序。我在服务中有以下内容与主要活动进行通信: 在这里,,我得到以下Lint警告:
此AsyncTask类应该是静态的,否则可能发生泄漏(匿名Android.os.AsyncTask) 该警告是由于内部类持有对外部类的隐式引用,因此阻止外部类进行GC。解决方案在于警告本身,即该类应该声明为静态的。 但是,解决方案是java特有的。鉴于kotlin没有修饰符,最接近的是companion object,而companion object确实包含对它的“外部类”的引用。
问题内容: 假设您有以下代码: 重用ps变量是否有潜在的泄漏? 如果是这样,我不希望声明多个此类准备好的语句(ps1,ps2,ps3等)。我应该如何重构呢? 有人在想吗? 编辑 收到几个答案,说明这无关紧要。我想指出的是,我遇到的游标保持打开状态的时间过长,并且想知道该模式是否与此有关。 我的想法是: 第一条语句被取消引用并进行了GC处理,因此在此示例中,如何关闭第一个PreparedStatem
我在两周前开始搜索不断增长的java内存。我使用以下命令来防止堆增长过多,并进行一些调试。 我使用oracle java 8在Ubuntu 16.04上运行,因为openjdk 8没有使jemaloc提供正确数据所需的调试符号 如您所见,我的Xmx设置为256m。然而当前显示我的进程为1.1G 在使用了JProfiler和JVisualVm I以及我在谷歌上可以找到的许多其他东西之后,我得出结论,