是否有一种方法来获得静态方法内的当前上下文实例?
我正在寻找这种方式,因为我讨厌保存'Context'实例每次它改变。
是否有一种方法来获得静态方法内的当前上下文实例?
我正在寻找这种方式,因为我讨厌保存'Context'实例每次它改变。
当前回答
另一种获得上下文而不子类化Application对象和不使用隐藏类的方法是使用ContentProvider。一旦onCreate方法被调用,上下文应该是可用的。您可以在Kotlin中执行类似的操作
class ContextContentProvider : ContentProvider() {
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?) = 0
override fun getType(uri: Uri): String? = null
override fun insert(uri: Uri, values: ContentValues?): Uri? = null
override fun onCreate(): Boolean {
applicationContext = context
return true
}
override fun query(
uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?
): Cursor? = null
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
) = 0
companion object {
private var applicationContext: Context? = null
@JvmStatic
fun applicationContext() = applicationContext
}
}
在任何需要上下文的地方,都可以调用ContextContentProvider.applicationContext()方法
如果你已经有了另一个内容提供程序,并且没有导出该内容提供程序,请确保在AndroidManifest.xml中使用不同的权限。
<application>
<provider
android:name=".ContextContentProvider"
android:authorities="${applicationId}.ContextContentProvider"
android:enabled="true"
android:exported="false" />
</application>
其他回答
我使用单例设计模式的一个变体来帮助我做到这一点。
import android.app.Activity;
import android.content.Context;
public class ApplicationContextSingleton {
private static Activity gContext;
public static void setContext( Activity activity) {
gContext = activity;
}
public static Activity getActivity() {
return gContext;
}
public static Context getContext() {
return gContext;
}
}
然后调用ApplicationContextSingleton。setContext(this);在我的activity.onCreate()和ApplicationContextSingleton。setContext(null);在onDestroy ();
下面是一种从UI线程中的任何地方获取应用程序(它是一个上下文)的未记录的方法。它依赖于隐藏的静态方法ActivityThread.currentApplication()。它至少可以在Android 4.x上运行。
try {
final Class<?> activityThreadClass =
Class.forName("android.app.ActivityThread");
final Method method = activityThreadClass.getMethod("currentApplication");
return (Application) method.invoke(null, (Object[]) null);
} catch (final ClassNotFoundException e) {
// handle exception
} catch (final NoSuchMethodException e) {
// handle exception
} catch (final IllegalArgumentException e) {
// handle exception
} catch (final IllegalAccessException e) {
// handle exception
} catch (final InvocationTargetException e) {
// handle exception
}
注意,这个方法有可能返回null,例如,当你在UI线程之外调用这个方法时,或者应用程序没有绑定到线程上。
如果可以更改应用程序代码,使用@RohitGhatol的解决方案仍然更好。
另一种获得上下文而不子类化Application对象和不使用隐藏类的方法是使用ContentProvider。一旦onCreate方法被调用,上下文应该是可用的。您可以在Kotlin中执行类似的操作
class ContextContentProvider : ContentProvider() {
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?) = 0
override fun getType(uri: Uri): String? = null
override fun insert(uri: Uri, values: ContentValues?): Uri? = null
override fun onCreate(): Boolean {
applicationContext = context
return true
}
override fun query(
uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?
): Cursor? = null
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
) = 0
companion object {
private var applicationContext: Context? = null
@JvmStatic
fun applicationContext() = applicationContext
}
}
在任何需要上下文的地方,都可以调用ContextContentProvider.applicationContext()方法
如果你已经有了另一个内容提供程序,并且没有导出该内容提供程序,请确保在AndroidManifest.xml中使用不同的权限。
<application>
<provider
android:name=".ContextContentProvider"
android:authorities="${applicationId}.ContextContentProvider"
android:enabled="true"
android:exported="false" />
</application>
根据这个源代码,您可以通过扩展ContextWrapper来获得自己的Context
public class SomeClass extends ContextWrapper {
public SomeClass(Context base) {
super(base);
}
public void someMethod() {
// notice how I can use "this" for Context
// this works because this class has it's own Context just like an Activity or Service
startActivity(this, SomeRealActivity.class);
//would require context too
File cacheDir = getCacheDir();
}
}
JavaDoc for ContextWrapper
Context的代理实现,简单地将其所有调用委托给另一个Context。可以通过子类化来修改行为而不改变原始上下文。
罗希特的回答似乎是正确的。然而,据我所知,AndroidStudio的“即时运行”依赖于在你的代码中没有静态上下文属性。