【问题标题】:A static field will leak contexts静态字段会泄漏上下文
【发布时间】:2018-10-17 08:17:39
【问题描述】:

这是我的启动活动代码:

public class Loading extends AsyncTask<Void, Void, Void>{

    @Override
    protected Void doInBackground(Void... voids) {
        try {
            Thread.sleep(4000);
        }catch(InterruptedException ie){
            ie.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        Intent homeIntent = new Intent(getApplicationContext(), ActivityHome.class);
        startActivity(homeIntent);
        overridePendingTransition(R.anim.open_next, R.anim.close_main);
    }
}

一切正常,但显示下一个警告:

This AsyncTask class should be static or leaks might occur (myapp.activities.ActivitySplash.Loading) less... (Ctrl+F1) 
A static field will leak contexts.

如果我将类更改为静态,将使用非静态方法并弹出错误:

Intent homeIntent = new Intent(getApplicationContext(), ActivityHome.class);
startActivity(homeIntent);
overridePendingTransition(R.anim.open_next, R.anim.close_main);

所以如果我将使用私有类将得到警告,如果将尝试使用静态类将得到错误。怎么做才能有清晰的代码?

【问题讨论】:

    标签: android class methods static non-static


    【解决方案1】:

    AsyncTask 作为非静态内部类将收到对其父类Activity 的引用。因此,您的代码中会出现警告。

    为了更正此问题并仍然可以访问您的活动,请将您的活动作为weak reference 传递给AsyncTask 的构造函数。

    然后您可以在onPostExecute 中调用您的意图代码并检查您的活动是否仍然存在于内存中。

    在我看来,您还应该考虑离开AsyncTask。查看RxJava 或现代JobScheduler

    【讨论】:

    • 或者对于这种情况,我认为new Handler().postDelay()就足够了
    【解决方案2】:

    不要在 Asyntasks 中持有对上下文的引用。使用回调将启动新活动委托给上下文活动本身。这是一种常见的不良做法,会导致内存泄漏,因为 AsyncTask 的寿命可能比上下文长。这将避免将其声明为静态,并且您将只有线程安全代码。

    【讨论】:

      猜你喜欢
      • 2018-04-02
      • 2012-08-08
      • 1970-01-01
      • 1970-01-01
      • 2021-06-04
      • 2018-01-11
      • 2016-10-20
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多