문제

전류를 얻는 방법이 있습니까? Context 정적 메소드 내부 인스턴스?

변경할 때마다 '컨텍스트'인스턴스를 저장하는 것을 싫어하기 때문에 그런 식으로 찾고 있습니다.

도움이 되었습니까?

해결책

이 작업을 수행:

Android Manifest 파일에서 다음을 선언하십시오.

<application android:name="com.xyz.MyApplication">

</application>

그런 다음 수업을 작성하십시오.

public class MyApplication extends Application {

    private static Context context;

    public void onCreate() {
        super.onCreate();
        MyApplication.context = getApplicationContext();
    }

    public static Context getAppContext() {
        return MyApplication.context;
    }
}

이제 어디서나 전화하십시오 MyApplication.getAppContext() 응용 프로그램 컨텍스트를 정적으로 얻으려면

다른 팁

애플리케이션 컨텍스트를 얻기 위해 편리한 방법을 원하는 대부분의 앱은 자신의 클래스를 생성하여 확장됩니다. android.app.Application.

가이드

다음과 같이 프로젝트에서 수업을 먼저 만들어이를 달성 할 수 있습니다.

import android.app.Application;
import android.content.Context;

public class App extends Application {

    private static Application sApplication;

    public static Application getApplication() {
        return sApplication;
    }

    public static Context getContext() {
        return getApplication().getApplicationContext();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sApplication = this;
    }
}

그런 다음 AndroidManifest에서 AndroidManifest.xml의 태그에서 클래스 이름을 지정해야합니다.

<application 
    ...
    android:name="com.example.App" >
    ...
</application>

그런 다음 다음을 사용하여 모든 정적 메소드에서 응용 프로그램 컨텍스트를 검색 할 수 있습니다.

public static void someMethod() {
    Context context = App.getContext();
}

경고

위의 프로젝트에 같은 것을 추가하기 전에 문서의 내용을 고려해야합니다.

일반적으로 서브 클래스 애플리케이션이 필요하지 않습니다. 대부분의 상황에서 정적 싱글 톤은보다 모듈 식 방식으로 동일한 기능을 제공 할 수 있습니다. 싱글 톤이 글로벌 컨텍스트 (예 : 방송 수신기를 등록하기 위해)가 필요한 경우,이를 검색 할 수있는 함수는 싱글 톤을 처음 구성 할 때 내부적으로 컨텍스트를 사용하는 컨텍스트를 제공 할 수 있습니다.


반사

반사를 사용하여 응용 프로그램 컨텍스트를 얻는 또 다른 방법도 있습니다. 반사는 종종 안드로이드에서 내려다 보며 개인적으로 이것이 제작에 사용해서는 안된다고 생각합니다.

응용 프로그램 컨텍스트를 검색하려면 숨겨진 클래스에서 메소드를 호출해야합니다 (ActivityThread) API 1 이후로 사용할 수있는) :

public static Application getApplicationUsingReflection() throws Exception {
    return (Application) Class.forName("android.app.ActivityThread")
            .getMethod("currentApplication").invoke(null, (Object[]) null);
}

숨겨진 수업이 하나 더 있습니다 (appglobals)는 응용 프로그램 컨텍스트를 정적으로 얻을 수있는 방법을 제공합니다. 그것은 컨텍스트를 사용합니다 ActivityThread 따라서 다음 방법과 위에 게시 된 방법에는 차이가 없습니다.

public static Application getApplicationUsingReflection() throws Exception {
    return (Application) Class.forName("android.app.AppGlobals")
            .getMethod("getInitialApplication").invoke(null, (Object[]) null);
} 

행복한 코딩!

응용 프로그램 컨텍스트를 얻는 것에 대해 이야기하고 있다고 가정하면 @rohit ghatol 확장 응용 프로그램에서 제안한대로 구현했습니다. 그런 일이 일어 났을 때, 그러한 방식으로 검색된 맥락이 항상 널이 없다는 보장은 없다는 것입니다. 필요할 때, 그것은 일반적으로 시간이 지연 될 수없는 도우미를 초기화하거나 자원을 얻기를 원하기 때문입니다. 널 케이스를 처리하면 도움이되지 않습니다. 그래서 나는 기본적으로 Android 아키텍처와 싸우고 있다는 것을 이해했습니다. 문서

참고 : 일반적으로 서브 클래스 응용 프로그램이 필요하지 않습니다. 대부분의 상황에서 정적 싱글 톤은보다 모듈 식 방식으로 동일한 기능을 제공 할 수 있습니다. 싱글 톤에 글로벌 컨텍스트가 필요한 경우 (예 : 방송 수신기를 등록하기 위해) 컨텍스트를 포함시킬 때 컨텍스트 인수로 context.getApplicationContext ()를 포함하십시오.

그리고 설명했다 Dianne Hackborn

애플리케이션이 도출 할 수있는 유일한 이유는 Pre-1.0 개발 중에 응용 프로그램 개발자 중 한 명이 지속적으로 도출 할 수있는 최상위 응용 프로그램 개체를 가질 필요가있어서 "정상"을 가질 수 있도록 계속해서 나에게 버그를두고 있었기 때문입니다. "그들에게 응용 프로그램 모델과 나는 결국 입었다. 나는 영원히 그것을 후회할 것이다. :)

그녀는 또한이 문제에 대한 해결책을 제안하고 있습니다.

원하는 것이 앱의 다른 부분에서 공유 할 수있는 글로벌 상태라면 싱글 톤을 사용하십시오. [...] 그리고 이것은 이러한 것들을 어떻게 관리 해야하는지 더 자연스럽게 이어집니다.

그래서 내가 한 일은 응용 프로그램을 확장하고 컨텍스트를 싱글 톤 헬퍼의 getinstance ()로 직접 전달하는 동시에 개인 생성자의 응용 프로그램 컨텍스트에 대한 참조를 저장하는 것이 었습니다.

private static MyHelper instance;
private final Context mContext;    

private MyHelper(@NonNull Context context) {
    mContext = context.getApplicationContext();
}

public static MyHelper getInstance(@NonNull Context context) {
    synchronized(MyHelper.class) {
        if (instance == null) {
            instance = new MyHelper(context);
        }
        return instance;
    }
}

그런 다음 발신자는 로컬 컨텍스트를 도우미에게 전달합니다.

Helper.getInstance(myCtx).doSomething();

따라서이 질문에 올바르게 답변하기 위해 : 신청 컨텍스트에 정적으로 액세스 할 수있는 방법이 있지만, 모두 낙담해야하며, 싱글 톤의 getinstance ()에 로컬 컨텍스트를 전달하는 것을 선호해야합니다.


관심있는 사람은 누구나 더 자세한 버전을 읽을 수 있습니다. FWD 블로그

아니요, 나는 생각하지 않습니다. 불행히도, 당신은 전화를 걸었습니다 getApplicationContext() ~에서 Activity 또는 다른 서브 클래스 중 하나 Context. 또한, 이것 질문은 다소 관련이 있습니다.

여기에 있습니다 문서화되지 않은 얻는 방법 신청 (컨텍스트) 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응용 프로그램 코드를 변경할 수있는 경우 솔루션.

컨텍스트를 사용하는 것에 따라 다릅니다. 그 방법에 대한 적어도 하나의 단점을 생각할 수 있습니다.

당신이 만들려고한다면 AlertDialog ~와 함께 AlertDialog.Builder,, Application 컨텍스트는 작동하지 않습니다. 나는 당신이 현재의 상황이 필요하다고 생각합니다 Activity...

당신이 사용하기에 열려 있다면 Roboguice, 원하는 클래스에 컨텍스트를 주입 할 수 있습니다. 다음은 Roboguice 2.0을 사용하여 수행하는 방법에 대한 작은 샘플입니다 (이 글을 쓰는 시점에 베타 4).

import android.content.Context;
import android.os.Build;
import roboguice.inject.ContextSingleton;

import javax.inject.Inject;

@ContextSingleton
public class DataManager {
    @Inject
    public DataManager(Context context) {
            Properties properties = new Properties();
            properties.load(context.getResources().getAssets().open("data.properties"));
        } catch (IOException e) {
        }
    }
}

나는 이것을 어느 시점에서 사용했습니다.

ActivityThread at = ActivityThread.systemMain();
Context context = at.getSystemContext();

이것은 시스템 서비스를 얻는 데 사용한 유효한 맥락입니다.

그러나 프레임 워크/기본 수정에서만 사용했으며 Android 응용 프로그램에서는 시도하지 않았습니다.

경고 이 맥락에서 방송 수신기에 등록 할 때는 작동하지 않으며 다음과 같이받을 것입니다.

java.lang.securityException : 발신자 패키지가 Process Record에서 실행되지 않습니다.

Kotlin Way:

명백한:

<application android:name="MyApplication">

</application>

myApplication.kt

class MyApplication: Application() {

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

    companion object {
        lateinit var instance: MyApplication
            private set
    }
}

그런 다음 myApplication.instance를 통해 속성에 액세스 할 수 있습니다

매니페스트 파일을 수정하지 않으려면 초기 활동에서 정적 변수에 컨텍스트를 수동으로 저장할 수 있습니다.

public class App {
    private static Context context;

    public static void setContext(Context cntxt) {
        context = cntxt;
    }

    public static Context getContext() {
        return context;
    }
}

활동 (또는 활동)이 시작될 때 상황을 설정합니다.

// MainActivity

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set Context
    App.setContext(getApplicationContext());

    // Other stuff
}

메모: 다른 모든 대답과 마찬가지로 이것은 잠재적 인 메모리 누출입니다.

코 틀린

open class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        mInstance = this
    }

    companion object {
        lateinit var mInstance: MyApp
        fun getContext(): Context? {
            return mInstance.applicationContext
        }
    }
}

그리고 같은 맥락을 얻으십시오

MyApp.mInstance

또는

MyApp.getContext()

나는 당신이 신체가 필요하다고 생각합니다 getAppContext() 방법:

public static Context getAppContext()
   return MyApplication.context; 

다음을 사용할 수 있습니다.

MainActivity.this.getApplicationContext();

MainActivity.java :

...
public class MainActivity ... {
    static MainActivity ma;
...
    public void onCreate(Bundle b) {
         super...
         ma=this;
         ...

다른 수업 :

public ...
    public ANY_METHOD... {
         Context c = MainActivity.ma.getApplicationContext();

에 따르면 이 소스 ContextWrapper를 확장하여 자신의 컨텍스트를 얻을 수 있습니다

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

ContextWrapper 용 Javadoc

단순히 모든 호출을 다른 컨텍스트로 위임하는 컨텍스트 구현을 위임합니다. 원래 컨텍스트를 변경하지 않고 동작을 수정하기 위해 서브 클래싱 할 수 있습니다.

나는 이것에 도움이되는 싱글 톤 디자인 패턴의 변형을 사용합니다.

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

방금 Android라는 jQuery에서 영감을 얻은 프레임 워크를 발표했습니다 증기 API 그것은 앱 개발을 더 간단하게 만드는 것을 목표로합니다.

중앙 $ 외관 수업 a WeakReference (Ethan Nicholas의 이것에 대한 Awesome Java 블로그 게시물에 대한 링크). Activity 호출을 통해 검색 할 수있는 컨텍스트 :

$.act()

WeakReference 쓰레기 수집이 원래 물체를 되 찾는 것을 방지하지 않고 참조를 유지하므로 메모리 누출에 문제가되지 않아야합니다.

물론 단점은 당신이 위험을 감수한다는 것입니다. $.act() Null을 반환 할 수 있습니다. 나는 아직이 시나리오를 발견하지 못했기 때문에 언급할만한 가치가있는 최소한의 위험 일 것입니다.

사용하지 않는 경우 컨텍스트를 수동으로 설정할 수도 있습니다. VaporActivity 당신으로 Activity 수업:

$.act(Activity);

또한, 많은 것 증기 API 프레임 워크는이 저장된 컨텍스트를 본질적으로 사용하여 프레임 워크를 사용하기로 결정한 경우 직접 저장할 필요가 없음을 의미 할 수 있습니다. 확인하십시오 대지 자세한 정보 및 샘플.

도움이되기를 바랍니다. :)

어떤 이유로 든 신청/활동을 확장하는 것뿐만 아니라 일부 공장 또는 도우미 수업의 경우 어떤 클래스에서 신청 컨텍스트를 원한다면. 다음 싱글 톤을 앱에 추가 할 수 있습니다.

public class GlobalAppContextSingleton {
    private static GlobalAppContextSingleton mInstance;
    private Context context;

    public static GlobalAppContextSingleton getInstance() {
        if (mInstance == null) mInstance = getSync();
        return mInstance;
    }

    private static synchronized GlobalAppContextSingleton getSync() {
        if (mInstance == null) mInstance = 
                new GlobalAppContextSingleton();
        return mInstance;
    }

    public void initialize(Context context) {
        this.context = context;
    }

    public Context getApplicationContext() {
        return context;
    }
}

그런 다음 응용 프로그램 클래스의 OnCreate에서 초기화하십시오.

GlobalAppContextSingleton.getInstance().initialize(this);

전화하여 어디서나 사용하십시오

GlobalAppContextSingleton.getInstance().getApplicationContext()

그러나이 접근법은 응용 프로그램 컨텍스트 외에는 권장하지 않습니다. 메모리 누출을 일으킬 수 있습니다.

Rohit의 대답이 맞습니다. 그러나 Androidstudio의 "Instant Run"은 static Context 내가 아는 한 코드의 속성.

그래서 메모리 누출을 일으키기 때문에 허용 된 답변을 수정했습니다. 이것이 제가 생각해 낸 것입니다 ...

AndroidManifest.xml

    <application android:name="com.xyz.MyApplication">
...

    </application>

myApplication.java

public class MyBakingAppContext extends Application {
    private static Object mContext;

    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
    }

    public static Context getAppContext() {
        return (Context)mContext;
    }
}

내가 실제로 한 일은 컨텍스트를 객체에 할당하고 객체를 컨텍스트로 반환하는 것입니다 (컨텍스트로 캐스팅). 도움이되기를 바랍니다.

Kotlin에서는 동반자 객체에 컨텍스트/앱 컨텍스트를 넣는 것입니다. Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)

또는 다음과 같은 것을 사용하는 경우 :

    companion object {
        lateinit var instance: MyApp
    }

메모리 누출을 발견하지 못하는 것은 보풀을 속이는 것입니다. 응용 프로그램 클래스와 그 후손이 컨텍스트이기 때문에 앱 인스턴스는 여전히 메모리 누출을 생성 할 수 있습니다.

또는 기능 인터페이스 또는 기능적 특성을 사용하여 앱 컨텍스트를 얻을 수 있습니다.

객체 클래스를 만듭니다.

object CoreHelper {
    lateinit var contextGetter: () -> Context
}

또는 Nullable 유형을 사용하여 더 안전하게 사용할 수 있습니다.

object CoreHelper {
    var contextGetter: (() -> Context)? = null
}

앱 클래스 에서이 줄을 추가합니다.


class MyApp: Application() {

    override fun onCreate() {
        super.onCreate()
        CoreHelper.contextGetter = {
            this
        }
    }
}

그리고 당신의 매니페스트에서 앱 이름을 선언합니다 . MyApp


    <application
            android:name=".MyApp"

컨텍스트를 원할 때 간단히 전화하십시오.

CoreHelper.contextGetter()

// or if you use the nullable version
CoreHelper.contextGetter?.invoke()

도움이되기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top