如何将上下文传递给静态方法?
How to pass context to a static method?
在我的片段中,我从另一个 class
调用了一个静态方法
if (getActivity() != null) {
Main.bindMusicService(getActivity().getApplicationContext(), position, songList);
}
主要class:
private static Context context;
private static ArrayList<Song> songList;
private static int songIndex;
public static void bindMusicService(Context c, int songPos, ArrayList<Song> songs){
context = c;
songIndex = songPos;
songList = songs;
/*mediaPlayerServiceIntent binds our connection to the MediaPlayerService. */
if (!mServiceIsBound) {
try {
mediaPlayerServiceIntent = new Intent(c, MediaPlayerService.class);
c.bindService(mediaPlayerServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
Log.e("Main", "Service is not bound!");
}
}else{
Main.mediaPlayerService.startActionPlay(context, songList, songIndex);
}
Log.i("Main","Service is bound!");
}
我收到此上下文警告
Do not place Android context classes in static fields; this is a memory leak
将我的数组列表、适配器位置和上下文发送到另一个 class 中的另一个方法的正确方法是什么?
您的问题是没有发送 Context
。你的问题是:
private static Context context;
如果您绝对确定自己需要类似的东西,请将其替换为:
private static Application context;
调整您的方法以将 Application
作为参数,并让您对该方法的调用使用 getApplication()
而不是 getApplicationContext()
。
IOW,您的代码相当安全——您正在使用 Application
上下文——但是您的代码细节让 Lint 感到紧张。
在Java中,静态变量或常量不会被垃圾回收。所以最好避免将 Context 存储在静态变量中
public static void bindMusicService(Context c, int songPos, ArrayList<Song> songs){
context = c;//remove this line
songIndex = songPos;
songList = songs;
/*mediaPlayerServiceIntent binds our connection to the MediaPlayerService. */
if (!mServiceIsBound) {
try {
mediaPlayerServiceIntent = new Intent(c, MediaPlayerService.class);
c.bindService(mediaPlayerServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
Log.e("Main", "Service is not bound!");
}
}else{
Main.mediaPlayerService.startActionPlay(context, songList, songIndex);
}
Log.i("Main","Service is bound!");
}
将 Context 传递给静态方法是可以的,只是 不要 将其存储在静态变量中。
主要是,我认为你需要一种比将上下文传递给方法更好的方法,你可以使用匕首,最后,如果你别无选择,最好使用单例模式或传统的全局应用程序上下文。
匕首示例:
@Module
public class MainActivityModule {
private final Context context;
public MainActivityModule (Context context) {
this.context = context;
}
@Provides //scope is not necessary for parameters stored within the module
public Context context() {
return context;
}
}
@Component(modules={MainActivityModule.class})
@Singleton
public interface MainActivityComponent {
Context context();
void inject(MainActivity mainActivity);
}
然后
MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(MainActivity.this))
.build();
作为单例模式的例子
private static SingletonDemo instance;
public static SingletonDemo get() {
if(instance == null) instance = getSync();
return instance;
}
private static synchronized SingletonDemo getSync() {
if(instance == null) instance = new SingletonDemo();
return instance;
}
private SingletonDemo(){
App.get();
}
Application-level 上下文:
public class App extends Application {
private static App instance;
public static App get() { return instance; }
@Override
public void onCreate() {
super.onCreate();
instance = this;
}
}
您必须在 AndroidManifest.xml
上定义您的应用程序 class
<application
...
android:name="com.example.YourApplication" >
...
</application>
另一种简单的方法是,在应用程序 class 中提供 public getter 方法,其中 returns class 实例成员上下文和上下文在中初始化oncreatw 应用程序的方法 class 您的应用程序。
在我的片段中,我从另一个 class
调用了一个静态方法if (getActivity() != null) {
Main.bindMusicService(getActivity().getApplicationContext(), position, songList);
}
主要class:
private static Context context;
private static ArrayList<Song> songList;
private static int songIndex;
public static void bindMusicService(Context c, int songPos, ArrayList<Song> songs){
context = c;
songIndex = songPos;
songList = songs;
/*mediaPlayerServiceIntent binds our connection to the MediaPlayerService. */
if (!mServiceIsBound) {
try {
mediaPlayerServiceIntent = new Intent(c, MediaPlayerService.class);
c.bindService(mediaPlayerServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
Log.e("Main", "Service is not bound!");
}
}else{
Main.mediaPlayerService.startActionPlay(context, songList, songIndex);
}
Log.i("Main","Service is bound!");
}
我收到此上下文警告
Do not place Android context classes in static fields; this is a memory leak
将我的数组列表、适配器位置和上下文发送到另一个 class 中的另一个方法的正确方法是什么?
您的问题是没有发送 Context
。你的问题是:
private static Context context;
如果您绝对确定自己需要类似的东西,请将其替换为:
private static Application context;
调整您的方法以将 Application
作为参数,并让您对该方法的调用使用 getApplication()
而不是 getApplicationContext()
。
IOW,您的代码相当安全——您正在使用 Application
上下文——但是您的代码细节让 Lint 感到紧张。
在Java中,静态变量或常量不会被垃圾回收。所以最好避免将 Context 存储在静态变量中
public static void bindMusicService(Context c, int songPos, ArrayList<Song> songs){
context = c;//remove this line
songIndex = songPos;
songList = songs;
/*mediaPlayerServiceIntent binds our connection to the MediaPlayerService. */
if (!mServiceIsBound) {
try {
mediaPlayerServiceIntent = new Intent(c, MediaPlayerService.class);
c.bindService(mediaPlayerServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
Log.e("Main", "Service is not bound!");
}
}else{
Main.mediaPlayerService.startActionPlay(context, songList, songIndex);
}
Log.i("Main","Service is bound!");
}
将 Context 传递给静态方法是可以的,只是 不要 将其存储在静态变量中。
主要是,我认为你需要一种比将上下文传递给方法更好的方法,你可以使用匕首,最后,如果你别无选择,最好使用单例模式或传统的全局应用程序上下文。
匕首示例:
@Module
public class MainActivityModule {
private final Context context;
public MainActivityModule (Context context) {
this.context = context;
}
@Provides //scope is not necessary for parameters stored within the module
public Context context() {
return context;
}
}
@Component(modules={MainActivityModule.class})
@Singleton
public interface MainActivityComponent {
Context context();
void inject(MainActivity mainActivity);
}
然后
MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(MainActivity.this))
.build();
作为单例模式的例子
private static SingletonDemo instance;
public static SingletonDemo get() {
if(instance == null) instance = getSync();
return instance;
}
private static synchronized SingletonDemo getSync() {
if(instance == null) instance = new SingletonDemo();
return instance;
}
private SingletonDemo(){
App.get();
}
Application-level 上下文:
public class App extends Application {
private static App instance;
public static App get() { return instance; }
@Override
public void onCreate() {
super.onCreate();
instance = this;
}
}
您必须在 AndroidManifest.xml
<application
...
android:name="com.example.YourApplication" >
...
</application>
另一种简单的方法是,在应用程序 class 中提供 public getter 方法,其中 returns class 实例成员上下文和上下文在中初始化oncreatw 应用程序的方法 class 您的应用程序。