2013-09-06 4 views
3

안녕하세요 저는 활동을 만들었습니다. BaseActivity를 가정합니다. 나는 그 활동에 새로운 실을 만들었다.다른 스레드의 한 스레드에서 변수에 액세스 - Android

실제로 나는 onConfigurationChange 또는 다른 일부에서 활동이 삭제되고 스레드가 가비지 수집되지 않았 음을 알고 그 중 하나가 누락되었음을 알게되었습니다.

이 문제를 해결하는 데는 2 가지 규칙이 있습니다.

하나는 Thread 클래스를 Static 클래스로 만들고 다른 하나는 onDestroy에서 스레드를 명시 적으로 중지하는 것입니다. 나는 둘 다 해냈다.

콘텐츠 공급자를 쿼리하기 위해이 스레드를 만들었습니다. 그래서 나는 applicationContext를 Thread로 가져 와서 그것을 사용하기 시작했다. 하지만 불행히도 "Cursor myCursor;"와 같이 OnCreate에서 선언 한 Cursor를 사용할 수 없습니다. . 반환 된 커서를이 myCursor에 할당하려고했습니다. 그것은 내가 지역 변수를 만들 것을 요구한다. 나는 이것이 Activity Context에 문제가 있다고 생각한다.

"응용 프로그램 컨텍스트가 있습니다"라는 컨텍스트를 응용 프로그램으로 생각했습니다. 그러나 불행히도. 나는 심지어 수색을하고, 내가 바깥의 클래스에 대해 약값을 얻어야한다는 것을 알았다. 나는 분명히 WekaReference에 대해 이해했다. 그러나 불행하게도 나의 상황을 위해 나는 나의 외부의 클래스의 약한 참조를 얻는 방법을 모른다. 도와주세요.

심지어 MyThread (BaseActivity.this)와 같은 스레드 생성자에 Context 컨텍스트를 전달하려고했는데 스레드 내부에서이를 사용하는 방법을 모릅니다.

public class MediaActivity extends Activity { 
ExpandableListView expList ; 
ExpandableListAdapter expListAdapter; 
List<String> albumHead; 
HashMap<String, List<String>> albumChild; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_media); 

    ExpandableListView expList = (ExpandableListView)findViewById(R.id.mediaList); 

    Cursor albumCursor; 
    AlbumThread albumThread = new AlbumThread(); 
    albumThread.start(); 
} 

private static class AlbumThread extends Thread{ 
    Context appContext = MediaApp.getAppContext(); 
    Context mediaActivity; 

    public AlbumThread() { 
     super("AlbumThread"); 

    } 


    @Override 
    public void run() { 
     // Query Media Contents from MediaStore.Audio.Media.EXTERNAL_CONTENT_URI 
     super.run(); 
     ContentResolver albumResolver = appContext.getContentResolver(); 
     Uri mediaContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
     String[] mediaColumns = { 
       MediaStore.Audio.Media._ID, 
       MediaStore.Audio.Media.ALBUM, 
       MediaStore.Audio.Media.ALBUM_ID, 
       MediaStore.Audio.Media.DATA, 
       MediaStore.Audio.Media.DISPLAY_NAME, 


      }; 

     String mediaSort = "ORDER BY" + MediaStore.Audio.Media.ALBUM_ID + "ASC" + "," + MediaStore.Audio.Media.DISPLAY_NAME + "ASC"; 

     albumCursor = albumResolver.query(mediaContentUri, mediaColumns, null, null, mediaSort); 

    } 


} 

}

+2

코드를 게시하시기 바랍니다. –

+0

개체/클래스에 대한 공용 변수는 스레드와 관계없이 다른 모든 개체에서 액세스 할 수 있습니다. – Cruncher

+0

@HowardPautz 위 코드는 내 코드입니다. 나는 초급이다. –

답변

0

당신 캔트 액세스를 당신이 당신의 방법에 로컬로 선언하기 때문이다.

당신이 그것을 넣을 수 있음)에서 onCreate (외부 커서 당신의 선언을 넣어 :

 public Cursor myCursor; 

이 방법은 당신이 그것을 액세스 할 수 있습니다.

+0

업데이트 할 필요가있는 모든 뷰에 대해 범위에서 선언해야합니까? 또한 선언하는 경우 그것은 정적 변수로 생성하도록 요청합니다. 괜찮 니? –

+0

MyThread (Myactivity.this)와 같이 스레드를 만드는 동안 활동의 컨텍스트를 전달하는 다른 방법이 있습니까? –

+0

@ RaQForu 귀하의 접근 방식이 문제의 원인인지 궁금합니다. 스레드에서 스레드 실행기로 콜백을 수행하기 위해 스레드에 컨텍스트를 전달해야하는 이유는 무엇입니까? 또한, Runnable을 사용하는 것이 Thread보다 더 쉽습니다. 또한 onCreate는 스레드를 시작하기에 가장 좋은 장소가 아닐 수도 있습니다. 해당 커서가 다른 스레드에서 액세스 될 경우, 잡기 힘든 데이터 경쟁/데이터 준비 버그를 도입 할 수 있습니다 (예 : 쓰레드가 쓰려고 할 때 여전히 커서를 가져 오는 중입니다. –

관련 문제