【问题标题】:How to pass context to a static method?如何将上下文传递给静态方法?
【发布时间】:2019-07-07 20:38:01
【问题描述】:

在我的片段中,我从另一个类调用静态方法

if (getActivity() != null) {
        Main.bindMusicService(getActivity().getApplicationContext(), position, songList);
}

主类:

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

将我的数组列表、适配器位置和上下文发送到另一个类中的另一个方法的正确方法是什么?

【问题讨论】:

标签: java android static-methods android-context


【解决方案1】:

您的问题是没有发送Context。你的问题是:

private static Context context;

如果您绝对确定自己需要类似的东西,请将其替换为:

private static Application context;

调整您的方法以将Application 作为参数,并让您对该方法的调用使用getApplication() 而不是getApplicationContext()

IOW,你的代码相当安全——你使用的是Application 上下文——但是你的代码细节让 Lint 很紧张。

【讨论】:

  • 那么Application可以作为Context吗?
  • getApplication和getApplicationContext有区别吗?
  • @Vince:“所以应用程序可以用作上下文?” -- Application 继承自 Context,所以是的。 It is not good for GUI work,但是可以绑定到服务,就像您在此处所做的那样。 “getApplication 和 getApplicationContext 有什么区别吗?” -- 它们应该返回相同的对象,只是转换为不同的类型(分别为ApplicationContext)。但是,出于某种原因,getApplication() 仅在 Activity 上可用。
  • 还有一个问题,如果我使用 getApplication 作为上下文来绑定服务,我是否也应该取消绑定 getApplication 作为上下文?
  • @Vince:是的。使用同一个Context绑定和解绑是最安全的,所以如果你使用Application绑定,我会使用Application解绑。
【解决方案2】:

在 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!");
}

将上下文传递给静态方法很好,只是不要将其存储在静态变量中。

主要是,我认为您需要一种比将上下文传递给方法更好的方法,您可以使用匕首,最后,如果您别无选择,最好使用单例模式或传统的全局应用程序上下文。

匕首的例子:

@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();
    }

应用级上下文:

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>

【讨论】:

  • 但是如果我删除那一行,我在该类的其他方法中没有上下文
【解决方案3】:

另一种简单的方法是,在应用程序类中提供公共 getter 方法,该方法返回类实例成员上下文,并在应用程序的应用程序类的 oncreatw 方法中初始化上下文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 2020-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多