2017-12-11 1 views
-1
public class OuterClass extends Something{ 

    private int unit = 0; 

    private void methodX(int num){ 
     //Do something here 
    } 

    public static class InnerClass extends BroadcastReceiver { 

     @Override 
     public void onReceive(Context context, Intent intent) {  

     // Need to call methodX(100) here  
     } 
    }  
} 

나는 응용 프로그램을 크래킹 중이며 잘 동작합니다. 나는 내부 클래스에서Java의 정적 내부 클래스에서 외부 클래스의 전용 멤버에 액세스하는 방법

instance.methodX(100) 

을 통해 변수를 OuterClass의

static OuterClass instance; 

를 사용하여 액세스하고 때하지만 메모리 누수를 선도하고 있습니다. 내부 클래스에서 정적 키워드를 제거한 경우 브로드 캐스트 수신기가 시작되지 않았습니다.

이것은 내 매니 페스트 파일에 포함되어 있습니다.

<receiver 
    android:name=".OuterClass$InnerClass" 
    android:enabled="true" 
    android:exported="true"> 
    <intent-filter > 
     <action android:name="com.xyz.abc.RESULT"/>   
     <category android:name="android.intent.category.DEFAULT"/> 
    </intent-filter> 
</receiver> 

예상대로 작동하지만 메모리 누수가 있습니다. 메모리 누수없이 정적 내부 클래스에서 외부 클래스 메서드에 액세스 할 필요가. 외부 클래스의 정적 인스턴스를 사용하지 않아야합니다.

누군가 내부 클래스에서 outerClass methodX에 액세스하는 방법을 찾도록 도와 주시면 정말 고맙게 생각합니다.

+0

'Something '이 무엇인지에 따라 달라집니다.'Application' 클래스 인 경우 외부 클래스 인스턴스에 문제가 없어야합니다 ... 'Activity' 또는'Fragment' 인 경우 해당 코드가 생성하지 않습니다. Active/Fragment가 InnerClass를 만들 때 존재하지 않을 수도 있습니다. – Selvin

+0

궁극적으로 Activity가 확장됩니다. –

+0

두 번째 BroadcastReceiver를 onCreate의 비 정적 ... 등록으로 사용하고 onStop에서 등록을 취소합니다 (누수가 없으므로). . 그리고 귀하의 1st BroadcastReceiver의 onReceive에서 브로드 캐스트를 보내십시오. 결국 같은 목적으로 이벤트 버스를 사용할 수 있습니다. – Selvin

답변

0

정적 내부 클래스를 선언하는 것은 새로운 파일을 만드는 것과 비슷합니다. 즉, 외부 클래스에 대한 인스턴스가 필요하다는 점에서 비슷합니다.

비 정적 인 내부 클래스는 비 정적 필드처럼 작동합니다. 즉, 인스턴스에 따라 다릅니다. 새로운 내부 객체를 초기화하기 위해 outter 객체의 인스턴스가 필요하다는 것을 의미합니다.

정적 인 경우 작동하려면 outter 클래스의 개체가 필요하지 않습니다.

outter.new Inner() 

을하고 중첩 년대 클래스에 접근 할 수

을하지만 클래스는 정적이기 때문에, 당신은을 통과해야 :

비 정적 내부 클래스에 대한

, 당신은이 작업을 수행 할 수 있습니다. 예를 들어 정상처럼. 나는.

new Outter.Inner(outterInstance) 

그러나 : 클래스가 브로드 캐스트 리시버를 확장 때문에, 빈 생성자로 초기화합니다. BroadcastReceiver는 시스템에 의해 초기화되고 처리되는 시스템이므로 전달할 값을 가진 생성자는 사용되지 않습니다. 대신 빈 생성자에서 새로운 인스턴스를 만들거나 내부 클래스에게 현재 무엇에 모든 변수를 이동

브로드 캐스트 리시버는이 하지 가능성이다하고, 빈 생성자를 필요로하기 때문에 :

public Inner(Outter instance) 

그것을 초기화되지 않을 것이므로 예외가 발생할 것입니다. 그러나 다음을 수행 할 수 있습니다.

public Inner(){ 
    outter = new Outter(); 
} 

또는 Outter 클래스 필드와 메서드를 모두 BroadcastReceiver로 이동하십시오.

You should read this SO post on the topic

0

당신은 그 방법을 staticmethodX() 표시 만 할 수 있습니다.이 후 내부 클래스 static에있는 해당 메소드에 액세스 할 수 있습니다.

+0

좋은 생각이 아니므로, 인스턴스 특정 vars가있을 수 있습니다. OP가 액세스하려고 시도합니다. – Zoe

+0

흠 현재 사례 메서드가 인스턴스 변수에 액세스하지 않습니다. –

+0

'// 여기에 뭔가를하십시오. '는 본질적으로 코드에서 거대한 와일드 카드입니다. 이 코드에는 인스턴스 변수에 액세스하는 무언가가있을 수 있습니다. – Zoe

관련 문제