문제

저는 Android에서 AsyncTasks를 사용해 왔으며 문제를 다루고 있습니다.

하나의 AsyncTask가 있는 활동이라는 간단한 예를 들어 보겠습니다.백그라운드 작업은 특별한 작업을 수행하지 않고 8초 동안만 잠자기 상태로 유지됩니다.

onPostExecute() 메서드의 AsyncTask 끝에서 버튼 표시 상태를 View.VISIBLE로 설정하고 결과를 확인합니다.

이제 이는 AsyncTask가 작동하는 동안(8초 절전 창 내에서) 사용자가 휴대폰 방향을 변경하기로 결정할 때까지 훌륭하게 작동합니다.

나는 Android 활동 수명 주기를 이해하고 활동이 파괴되고 다시 생성된다는 것을 알고 있습니다.

여기서 문제가 발생합니다.AsyncTask는 버튼을 참조하고 있으며 처음에 AsyncTask를 시작한 컨텍스트에 대한 참조를 보유하고 있는 것으로 보입니다.

나는 이 이전 컨텍스트(사용자가 방향 변경을 유발했기 때문에)가 null이 되고 AsyncTask가 표시하려는 버튼에 대한 참조를 위해 NPE를 던질 것이라고 예상합니다.

대신 NPE가 발생하지 않으며 AsyncTask는 버튼 참조가 null이 아니라고 생각하여 표시되도록 설정합니다.결과?화면에는 아무 일도 일어나지 않습니다!

업데이트: 나는 이것을 유지함으로써 이 문제를 해결했습니다. WeakReference 구성 변경이 발생할 때 활동 및 전환에 적용됩니다.이것은 번거로운 작업입니다.

코드는 다음과 같습니다.

public class Main extends Activity {

    private Button mButton = null;
    private Button mTestButton = null;

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

        mButton = (Button) findViewById(R.id.btnStart);
        mButton.setOnClickListener(new OnClickListener () {
            @Override
            public void onClick(View v) {
                new taskDoSomething().execute(0l);
            }
        });
        mTestButton = (Button) findViewById(R.id.btnTest);   
    }

    private class TaskDoSomething extends AsyncTask<Long, Integer, Integer> 
    {
        @Override
        protected Integer doInBackground(Long... params) {
            Log.i("LOGGER", "Starting...");
            try {
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 0;
        }

        @Override
        protected void onPostExecute(Integer result) {
            Log.i("LOGGER", "...Done");
            mTestButton.setVisibility(View.VISIBLE);
        }
    }
}

실행해 보고 AsyncTask가 작동하는 동안 휴대폰 방향을 변경하세요.

도움이 되었습니까?

해결책

AsyncTask is not designed to be reused once an Activity has been torn down and restarted. The internal Handler object becomes stale, just like you stated. In the Shelves example by Romain Guy, he simple cancels any currently running AsyncTask's and then restarts new ones post-orientation change.

It is possible to hand off your Thread to the new Activity, but it adds a lot of plumbing. There is no generally agreed on way to do this, but you can read about my method here : http://foo.jasonhudgins.com/2010/03/simple-progressbar-tutorial.html

다른 팁

컨텍스트만 필요하고 이를 UI 작업에 사용하지 않으려면 간단히 ApplicationContext를 AsyncTask에 전달하면 됩니다. 예를 들어 시스템 리소스에 대한 컨텍스트가 필요한 경우가 많습니다.

AsyncTask에서 UI를 업데이트하려고 시도하지 말고 구성 변경 사항을 직접 처리하지 마십시오. 지저분해질 수 있습니다.UI를 업데이트하려면 Broadcast Receiver를 등록하고 Broadcast를 보낼 수 있습니다.

또한 위에서 언급한 대로 활동과 별도의 공개 클래스로 AsyncTask를 가져야 하며, 이렇게 하면 테스트가 훨씬 쉬워집니다.불행하게도 Android 프로그래밍은 나쁜 관행을 강화하는 경우가 많으며 공식 예제는 도움이 되지 않습니다.

SharePoint 2010 및 Analysis Services 2008이 별도의 기계에 있었기 때문에 Domain \ TFSREPORTS가 이벤트 뷰어 \ 보안 로그의 Analysis Services 시스템에서 성공하면 Windows 인증을 통해 로그온을 볼 수있었습니다. 그래서 나는 Excel 서비스가 멀리 떨어져 있음을 알고있었습니다 ...

GOOGLING 일반적으로 PF_CHECK_ERROR 및 "등록되지 않은 클래스"정보 OLEDBCONNECTION에서 일종의 COM 오류처럼 보였습니다. 등록되지 않은 클래스 또는 DLL을로드하려고 할 수 있습니까?

OLE DB 연결 유형은 MS OLAP이고 시트의 임베디드 ODC 파일의 연결 문자열은 OLAP.3을 지정합니다. 깜짝 놀라움, 놀라움, OLAP 2 및 4는 분석 서비스 기계, 에 존재하지만 msolap.3은 아닙니다! (regedit - hkey_classes_root \ msolap로 확인).

보고서를 열었으므로 연결 속성에 대한 연결 속성을 Provider= msolap.4로 변경 한 다음 특정 보고서가 올바르게 새로 고쳐졌습니다. 이제 팀 프로젝트에서 OLAP 4를 사용하도록 모든 Excel 보고서를 업데이트했으며 모든 대시 보드가 작동 중입니다.


엑셀 서비스와 보안 저장소 서비스를 사용하려고하는 다른 사람이 도움이되기를 돕습니다. 특히 클라이언트와 서버가 다른 (그러나 신뢰할 수있는) 도메인에있는 경우 Kerberos와 함께 토끼 구멍을 더 많이 내려갔습니다. 그 중 하나가 필요하지 않습니다. 그것은 실제로 여기서는 모든 종속성이 올바르게 설치되는 한

문제의 초기 로그를 얻으려면 Excel Services 응용 프로그램 및 중앙 관리> 모니터링> 진단 로깅 구성에서 Excel Services 응용 프로그램 및 보안 저장소 서비스를 위해 자세한 로깅을 켜야했습니다. 로그는 % Program Files % \ Common Files \ Microsoft Shared \ Web Server Extensions \ 14 \ Logs (명백한, H 응?)에 나타납니다.

(아직 분명하지 않은 것은 Analysis Services 시스템에 Msolap 3을 설치하는지 여부는 연결 문자열을 변경하지 않고 문제를 해결할 수 있는지 여부입니다. OLAP는 SharePoint 서버의 Excel 서비스 또는 Analysis Services로로드됩니다. Analysis Server? X64 설치 프로그램을 보유 할 때 확인할 것입니다.

To avoid this you can use the answer givin here: https://stackoverflow.com/a/2124731/327011

But if you need to destroy the activity (different layouts for portrait and landscape) you can make the AsyncTask a public class (Read here why it shouldn't be private Android: AsyncTask recommendations: private class or public class?) and then create a method setActivity to set the reference to the current activity whenever it is destroyed/created.

You can see an example here: Android AsyncTask in external class

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