如何修复不要将安卓上下文类放在静态字段中的警告

440 阅读2分钟

Android框架的Context 类被用来检索特定的应用程序资源。

该类也用于执行应用程序级别的操作,如启动活动和广播。

Android中的Context 类是使用getContext()getApplicationContext() 函数来检索的。

getContext() 方法可以从View 类中获得。它被用来返回视图的上下文。通常情况下,它是当前的Activity 类。

getApplicationContext() 方法可从Activity 类中获得,用于返回应用程序的上下文。

当你把一个上下文字段定义为静态时,Android会以下面的警告来回应:

Do not place Android context classes in static fields;
this is a memory leak

下面是一个导致上述警告的AndroidActivity 类:

public class MainActivity extends AppCompatActivity {
 private static Context ctx;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = getApplicationContext();
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
navigateActivity();
}
});
}
void navigateActivity() {
Intent in = new Intent(ctx, SecondActivity.class);
startActivity(in);
}
}

在上面的代码中,你可以看到创建了一个对Context 实例的静态引用。

后来,ctx 被分配了来自getApplicationContext() 调用里面onCreate() 方法的上下文。

由于Context 是一个全局性的应用程序对象,它在你的应用程序的运行期间将始终可用。

这就是为什么你不需要为Context 类创建一个静态引用。当需要时,你总是可以从一个Activity 类中调用getApplicationContext()

你可以删除静态上下文,并改变上面的代码,如下:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
navigateActivity();
}
});
}
void navigateActivity() {
 Intent in = new Intent(getApplicationContext(), SecondActivity.class);
 startActivity(in);
}
}

当你需要对Activity 类以外的Context 类的引用时,你可以把Context 作为一个参数传递给需要它的方法。

例如,假设你在MainActivity 类中有一个static 方法,如下图所示:

public static void greetings(Context ctx){
Toast.makeText(ctx, "Hello!", Toast.LENGTH_SHORT).show();
}

因为上面的greetings() 方法是静态的,你不能在方法体内调用getApplicationContext()

你可以从Activity ,在你调用greetings() 方法的地方调用它,像这样:

public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
 MainActivity.greetings(getApplicationContext());
 }
});
}
}

在上面的代码中,MainActivity.greetings() 方法是从SecondActivity 类中调用的,其上下文是从getApplicationContext() 调用中获取的。

这样,你就可以得到应用程序的Context 实例,而不需要为它创建一个静态引用。

这就是你如何解决Do not place Android context classes in static fields 的问题。

我希望这个教程对你有用。👍