Android 앱에서 다음 접근 방식에 문제가 있습니까?
public class MyApp extends android.app.Application {
private static MyApp instance;
public MyApp() {
instance = this;
}
public static Context getContext() {
return instance;
}
}
컨텍스트가 필요한 곳이라면 어디에서나 전달하십시오 (예 : SQLiteOpenHelper).
답변
이 방법에는 몇 가지 잠재적 인 문제가 있지만, 많은 경우 (예 : 예) 잘 작동합니다.
특히을 GUI
요구하는 모든 것을 다룰 때는 조심 해야합니다 Context
. 예를 들어 응용 프로그램 컨텍스트를 응용 프로그램으로 전달 LayoutInflater
하면 예외가 발생합니다. 일반적으로, 당신의 접근 방식이 우수합니다 : 그것은을 사용하는 것이 좋은 방법입니다 Activity's
Context
그 내에서 Activity
, 그리고 Application Context
의 범위를 벗어나는 상황에 맞는 전달할 때 Activity
하는 메모리 누수를 방지를 .
또한,로 다른 사용자의 패턴에 당신이 전화의 바로 가기를 사용할 수 있습니다 getApplicationContext()
A의 Context
응용 프로그램 컨텍스트를 얻기 위해 (예 : 활동으로) 개체를.
답변
내 경험상이 접근법은 필요하지 않아야합니다. 무엇이든 컨텍스트가 필요한 경우 일반적으로 View.getContext () 호출을 통해 얻을 수 있으며 얻은 컨텍스트를 사용하여 Context.getApplicationContext () 를 Context
호출 하여 컨텍스트 를 가져올 수 있습니다. 컨텍스트 를 가져 오려고하면 언제든지 Activity.getApplication () 을 호출 할 수 있으며 호출에 필요한 대로 전달할 수 있어야 합니다 .Application
Application
Activity
Context
SQLiteOpenHelper()
전반적 으로이 상황에 대한 접근 방식에는 문제가없는 것 같지만 처리 할 때 Context
공식 Google Android 개발자 블로그 에 설명 된 것처럼 메모리 누수가 없는지 확인하십시오 .
답변
어떤 사람들은 싱글 톤이 어떻게 널 포인터를 반환 할 수 있습니까?
나는 그 질문에 대답하고있다. (코드를 게시해야하므로 의견에 답할 수 없습니다.)
두 이벤트 사이에 null을 반환 할 수 있습니다. (1) 클래스가로드되고 (2)이 클래스의 객체가 생성됩니다. 예를 들면 다음과 같습니다.
class X {
static X xinstance;
static Y yinstance = Y.yinstance;
X() {xinstance=this;}
}
class Y {
static X xinstance = X.xinstance;
static Y yinstance;
Y() {yinstance=this;}
}
public class A {
public static void main(String[] p) {
X x = new X();
Y y = new Y();
System.out.println("x:"+X.xinstance+" y:"+Y.yinstance);
System.out.println("x:"+Y.xinstance+" y:"+X.yinstance);
}
}
코드를 실행 해 봅시다 :
$ javac A.java
$ java A
x:X@a63599 y:Y@9036e
x:null y:null
두 번째 줄은 Y.xinstance 와 X.yinstance 가 null 임을 나타냅니다 . 변수 X.xinstance ans Y.yinstance 가 null 일 때 읽혀 지기 때문에 null입니다.
이 문제를 해결할 수 있습니까? 예,
class X {
static Y y = Y.getInstance();
static X theinstance;
static X getInstance() {if(theinstance==null) {theinstance = new X();} return theinstance;}
}
class Y {
static X x = X.getInstance();
static Y theinstance;
static Y getInstance() {if(theinstance==null) {theinstance = new Y();} return theinstance;}
}
public class A {
public static void main(String[] p) {
System.out.println("x:"+X.getInstance()+" y:"+Y.getInstance());
System.out.println("x:"+Y.x+" y:"+X.y);
}
}
이 코드는 이상이 없음을 보여줍니다.
$ javac A.java
$ java A
x:X@1c059f6 y:Y@152506e
x:X@1c059f6 y:Y@152506e
그러나 이것은 Android Application
객체 의 옵션이 아닙니다 . 프로그래머는 생성 시간을 제어하지 않습니다.
다시 한 번 : 첫 번째 예제와 두 번째 예제의 차이점은 두 번째 예제는 정적 포인터가 널인 경우 인스턴스를 작성한다는 것입니다. 그러나 프로그래머는 만들 수 없습니다 시스템이 그것을 할하기로 결정하기 전에 안드로이드 응용 프로그램 개체를.
최신 정보
초기화 된 정적 필드가 발생하는 또 하나의 수수께끼 예 null
입니다.
Main.java :
enum MyEnum {
FIRST,SECOND;
private static String prefix="<", suffix=">";
String myName;
MyEnum() {
myName = makeMyName();
}
String makeMyName() {
return prefix + name() + suffix;
}
String getMyName() {
return myName;
}
}
public class Main {
public static void main(String args[]) {
System.out.println("first: "+MyEnum.FIRST+" second: "+MyEnum.SECOND);
System.out.println("first: "+MyEnum.FIRST.makeMyName()+" second: "+MyEnum.SECOND.makeMyName());
System.out.println("first: "+MyEnum.FIRST.getMyName()+" second: "+MyEnum.SECOND.getMyName());
}
}
그리고 당신은 얻을 :
$ javac Main.java
$ java Main
first: FIRST second: SECOND
first: <FIRST> second: <SECOND>
first: nullFIRSTnull second: nullSECONDnull
정적 변수 선언을 한 줄 위로 이동할 수 없으며 코드는 컴파일되지 않습니다.
답변
응용 프로그램 클래스 :
import android.app.Application;
import android.content.Context;
public class MyApplication extends Application {
private static Context mContext;
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
}
public static Context getAppContext() {
return mContext;
}
}
AndroidManifest에서 애플리케이션을 선언하십시오.
<application android:name=".MyApplication"
...
/>
용법:
MyApplication.getAppContext()
답변
응용 프로그램 컨텍스트를 얻기 위해 랩퍼를 작성하려고하며 ” null
“포인터를 리턴 할 가능성이 있습니다 .
내 이해에 따르면, 2 Context.getApplicationContext()
나 중 하나를 호출하는 것이 더 나은 방법이라고 생각합니다
Activity.getApplication()
.
답변
좋은 접근 방법입니다. 나 자신도 사용합니다. onCreate
생성자를 사용하는 대신 싱글 톤을 설정 하도록 재정의 하는 것이 좋습니다 .
그리고 당신이 언급 한 이후 SQLiteOpenHelper
: onCreate ()
데이터베이스를 열 수도 있습니다.
개인적으로 필자 는 일반적으로 Application을 서브 클래스 화 할 필요가 없다는 말이 잘못되었다고 생각합니다 . 나는 그 반대가 사실이라고 생각한다 : 당신은 항상 Application을 서브 클래 싱해야한다.
답변
응용 프로그램 컨텍스트를 사용하여 생성자에서 시스템 서비스를 가져옵니다. 이것은 테스트를 용이하게하고 컴포지션의 이점을 제공합니다
public class MyActivity extends Activity {
private final NotificationManager notificationManager;
public MyActivity() {
this(MyApp.getContext().getSystemService(NOTIFICATION_SERVICE));
}
public MyActivity(NotificationManager notificationManager) {
this.notificationManager = notificationManager;
}
// onCreate etc
}
그런 다음 테스트 클래스는 오버로드 된 생성자를 사용합니다.
안드로이드는 기본 생성자를 사용합니다.