这是我的代码:
new AsyncTask<Void,Void,Void>(){
@Override
protected Void doInBackground(Void... params) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
return null;
}
}.execute();
我怎么纠正这个?
为了防止泄漏,可以使内部类保持静态。但是,这样做的问题是,您不再能够访问活动的UI视图或成员变量。您可以传入对上下文
的引用,但这样做也会面临内存泄漏的风险。(如果AsyncTask类对活动有很强的引用,Android就不能在活动关闭后对其进行垃圾回收。)解决方案是对活动(或您需要的任何上下文
)进行弱引用。
public class MyActivity extends AppCompatActivity {
int mSomeMemberVariable = 123;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// start the AsyncTask, passing the Activity context
// in to a custom constructor
new MyTask(this).execute();
}
private static class MyTask extends AsyncTask<Void, Void, String> {
private WeakReference<MyActivity> activityReference;
// only retain a weak reference to the activity
MyTask(MyActivity context) {
activityReference = new WeakReference<>(context);
}
@Override
protected String doInBackground(Void... params) {
// do some long running task...
return "task finished";
}
@Override
protected void onPostExecute(String result) {
// get a reference to the activity if it is still there
MyActivity activity = activityReference.get();
if (activity == null || activity.isFinishing()) return;
// modify the activity's UI
TextView textView = activity.findViewById(R.id.textview);
textView.setText(result);
// access Activity member variables
activity.mSomeMemberVariable = 321;
}
}
}
>
AsyncTask
教程仍然没有涉及它(请参阅这里、这里、这里和这里)。AsyncTask
是顶级类,也可以遵循类似的过程。静态内部类与Java中的顶级类基本相同。如果不需要活动本身,但仍然需要上下文(例如,要显示toast
),可以传入对应用程序上下文的引用。在本例中,AsyncTask
构造函数如下所示:
private WeakReference<Application> appReference;
MyTask(Application context) {
appReference = new WeakReference<>(context);
}
在Kotlin中,不要包含内部类的inner
关键字。这使得默认情况下它是静态的。
class MyActivity : AppCompatActivity() {
internal var mSomeMemberVariable = 123
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// start the AsyncTask, passing the Activity context
// in to a custom constructor
MyTask(this).execute()
}
private class MyTask
internal constructor(context: MyActivity) : AsyncTask<Void, Void, String>() {
private val activityReference: WeakReference<MyActivity> = WeakReference(context)
override fun doInBackground(vararg params: Void): String {
// do some long running task...
return "task finished"
}
override fun onPostExecute(result: String) {
// get a reference to the activity if it is still there
val activity = activityReference.get()
if (activity == null || activity.isFinishing) return
// modify the activity's UI
val textView = activity.findViewById(R.id.textview)
textView.setText(result)
// access Activity member variables
activity.mSomeMemberVariable = 321
}
}
}
我的项目中有一个AsyncTask,有一个警告,它说:
我正在开发一个带有服务的Android 2.3.3应用程序。我在服务中有以下内容与主要活动进行通信: 在这里,,我得到以下Lint警告:
此AsyncTask类应该是静态的,否则可能发生泄漏(匿名Android.os.AsyncTask) 该警告是由于内部类持有对外部类的隐式引用,因此阻止外部类进行GC。解决方案在于警告本身,即该类应该声明为静态的。 但是,解决方案是java特有的。鉴于kotlin没有修饰符,最接近的是companion object,而companion object确实包含对它的“外部类”的引用。
我有一个名为的类,它扩展了接口和。但是,当我使用该类并且不调用它的方法时,不会触发存在资源泄漏的警告。我还有一个名为的类,它有一个名为的方法,返回一个对象。当我以以下方式创建一个新的对象时,不会触发任何资源泄漏警告:
问题内容: 假设我有一个要实例化的类。我在类中有几个私有的“帮助器”方法,它们不需要访问任何类成员,而仅对它们的参数进行操作,并返回结果。 有没有指定任何特别的原因,并为静态方法-或任何特别的理由不? 将它们设置为非静态无疑是最容易的,即使它们可以肯定是静态的而不会引起任何问题。 问题答案: 我更喜欢这样的帮助方法; 这将使读者清楚地知道他们不会修改对象的状态。我的IDE还将以斜体显示对静态方